From fe2ff3bbcfe0714a02f62feb445ddfcd77892552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AC=B4=E6=94=BF=20=E6=97=B6?= Date: Wed, 14 May 2025 20:00:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=BE=E5=9B=9E=E8=AF=81=E5=88=B8=E4=B8=9A?= =?UTF-8?q?=E6=8A=A5=E9=80=81=E7=9A=84=E9=80=BB=E8=BE=91,=E4=BB=85?= =?UTF-8?q?=E6=94=AF=E6=8C=81Excel=E6=A8=A1=E6=9D=BF=E6=8A=A5=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YLErp.Core/DBModels/Consts/ConsReport.cs | 1184 +++++++- .../DBModels/Enums/SuperviseReportTypeEnum.cs | 10 + YLErpDAL/Modules/AppModule/AppUpgrader.cs | 2 +- .../SAC/Common/BaseCheckHelper.cs | 121 +- .../SAC/Common/ReportInfoHelper.cs | 2499 +++++++++++++++++ .../SAC/Common/Sac_TranslateHelper.cs | 52 +- .../SAC/Model/ConfirmationAttModel.cs | 101 + .../SAC/Model/MasterAgrmtModel.cs | 44 +- .../SAC/Model/MasterAgrmtProductModel.cs | 54 +- .../SAC/Model/OptionConfirmationModel.cs | 2235 +++++++++++++-- .../SAC/Model/OptionTerminationModel.cs | 198 +- .../SAC/Model/OtherReportModel.cs | 2 +- .../Model/PerformanceGuaranteeAgrmtModel.cs | 6 +- .../SAC/Model/PeriodicReportISDAModel.cs | 121 +- .../SAC/Model/PeriodicReportNAFMIIModel.cs | 57 +- .../SAC/Model/PeriodicReportSACModel.cs | 221 +- .../SAC/Model/ReportReq.cs | 106 +- .../SAC/Model/ReportRootModel.cs | 65 +- .../SAC/Model/SupAgrmtModel.cs | 40 +- .../SAC/Model/SwapConfirmationAttModel.cs | 57 - .../SAC/Model/SwapConfirmationModel.cs | 94 +- .../SAC/Model/SwapDurationManagementModel.cs | 27 +- .../SAC/Model/SwapEquityPaymentModel.cs | 27 +- .../SAC/Model/ValuationInformationModel.cs | 240 ++ .../Service/ContractNumberProcessService.cs | 126 +- .../SAC/Service/ReportBaseService.cs | 808 ++++-- .../SAC/Service/ReportEventReportService.cs | 62 +- .../ReportMasterAgrmtProductService.cs | 240 +- .../SAC/Service/ReportMasterAgrmtService.cs | 351 +-- .../ReportOptionConfirmationAttService.cs | 320 +++ .../ReportOptionConfirmationService.cs | 1033 +++---- .../Service/ReportOptionTerminationService.cs | 588 +--- .../SAC/Service/ReportOtherReportService.cs | 64 +- .../ReportPerformanceGuaranteeAgrmtService.cs | 206 +- .../ReportPeriodicReportISDAService.cs | 163 +- .../ReportPeriodicReportNAFMIIService.cs | 213 +- .../ReportPeriodicReportQuarterService.cs | 63 +- .../Service/ReportPeriodicReportSACService.cs | 1044 +------ .../SAC/Service/ReportService.cs | 1282 +++++---- .../SAC/Service/ReportSupAgrmtService.cs | 233 +- .../ReportSwapConfirmationAttService.cs | 457 +-- .../Service/ReportSwapConfirmationService.cs | 886 +----- .../Service/ReportSwapEquityPaymentService.cs | 584 +--- .../Service/ReportSwapTerminationService.cs | 832 +----- .../ReportValuationInformationService.cs | 484 ++++ YLErpWeb/App_Data/FunctionRight.xml | 3 + YLErpWeb/App_Data/Menus.txt | 5 + YLErpWeb/App_Docs/导入模板/Report.zip | Bin 198176 -> 238244 bytes .../Controllers/supervise_reportController.cs | 110 +- .../supervise_SAC_Report.cshtml | 130 +- .../Scripts/app/superviseReport/sacReport.js | 102 +- YLerpbase.sln | 1 + 52 files changed, 10829 insertions(+), 7124 deletions(-) create mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Common/ReportInfoHelper.cs create mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ConfirmationAttModel.cs delete mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationAttModel.cs create mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ValuationInformationModel.cs create mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationAttService.cs create mode 100644 YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportValuationInformationService.cs diff --git a/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs b/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs index 1e5559e7..9152f16e 100644 --- a/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs +++ b/Framework/YLErp.Core/DBModels/Consts/ConsReport.cs @@ -1,4 +1,10 @@ -using YLErp.Commons; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YLErp.Commons; namespace YLErp.DBModels.Consts { @@ -98,6 +104,16 @@ namespace YLErp.DBModels.Consts /// [Description("收益互换交易确认书附件")] A1017, + /// + /// 场外期权-估值 + /// + [Description("场外期权-估值")] + A1018, + /// + /// 场外期权交易确认书附件 + /// + [Description("场外期权交易确认书附件")] + A1019, } /// /// 操作标识 @@ -131,20 +147,20 @@ namespace YLErp.DBModels.Consts [Flags] public enum SAC_ReportDataSourceEnum : byte { - /// - /// 系统数据 - /// - System = 1, + ///// + ///// 系统数据 + ///// + //System = 1, /// /// Excel模板 /// - Template = 1<<1, + Template = 1 << 1, - /// - /// 金仕达视图 - /// - KingstarView = 1<<2 + ///// + ///// 金仕达视图 + ///// + //KingstarView = 1 << 2 } /// @@ -255,6 +271,14 @@ namespace YLErp.DBModels.Consts {"SAC(2018年12月发布)","5" }, {"SAC信用保护合约专用版","6" }, {"其他","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" }, + {"4","4" }, + {"5","5" }, + {"6","6" }, + {"99","99" } }); } return _masterAgrmtVerMap; @@ -276,6 +300,8 @@ namespace YLErp.DBModels.Consts { {"甲方","0" }, {"乙方","1" }, + {"0","0" }, + {"1","1" } }); } return _fillPartyMap; @@ -296,6 +322,8 @@ namespace YLErp.DBModels.Consts { {"甲方","0" }, {"乙方","1" }, + {"0","0" }, + {"1","1" } }); } return _fillPartyMap; @@ -321,6 +349,10 @@ namespace YLErp.DBModels.Consts {"客户空头","1" }, {"多空组合","2" }, {"其他","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"99","99" } }); } return _swapTypeMap; @@ -342,6 +374,8 @@ namespace YLErp.DBModels.Consts { {"非专业","0" }, {"专业","1" }, + {"0","0" }, + {"1","1" } }); } return _proCounterpartyMap; @@ -411,6 +445,28 @@ namespace YLErp.DBModels.Consts {"政策性银行","19" }, {"外资银行","20" }, {"期货资产管理公司","21" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" }, + {"4","4" }, + {"5","5" }, + {"6","6" }, + {"7","7" }, + {"8","8" }, + {"9","9" }, + {"10","10" }, + {"11","11" }, + {"12","12" }, + {"13","13" }, + {"14","14" }, + {"15","15" }, + {"16","16" }, + {"17","17" }, + {"18","18" }, + {"19","19" }, + {"20","20" }, + {"21","21" } }); } return _counterpartyTypeMap; @@ -480,6 +536,28 @@ namespace YLErp.DBModels.Consts {"外资银行","20" }, {"期货资产管理公司","21" }, {"其他","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"4","4" }, + {"5","5" }, + {"6","6" }, + {"7","7" }, + {"8","8" }, + {"9","9" }, + {"10","10" }, + {"11","11" }, + {"12","12" }, + {"13","13" }, + {"14","14" }, + {"15","15" }, + {"16","16" }, + {"17","17" }, + {"18","18" }, + {"19","19" }, + {"20","20" }, + {"21","21" }, + {"99","99" } }); } return _nafmiiCounterpartyTypeMap; @@ -501,6 +579,8 @@ namespace YLErp.DBModels.Consts { {"产品管理人","1" }, {"自营","2" }, + {"1","1" }, + {"2","2" } }); } return _counterpartyIdentityMap; @@ -522,6 +602,8 @@ namespace YLErp.DBModels.Consts { {"首次","0" }, {"变更","1" }, + {"0","0" }, + {"1","1" } }); } return _reportTypeMap; @@ -545,6 +627,12 @@ namespace YLErp.DBModels.Consts {"首次","01" }, {"补充","02" }, {"变更","03" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"01","01" }, + {"02","02" }, + {"03","03" } }); } return _isdaReportTypeMap; @@ -566,6 +654,10 @@ namespace YLErp.DBModels.Consts { {"首次","01" }, {"变更","02" }, + {"1","01" }, + {"2","02" }, + {"01","01" }, + {"02","02" } }); } return _isdaReportTypeMap2; @@ -590,6 +682,10 @@ namespace YLErp.DBModels.Consts {"填报机构","01" }, {"对手方","02" }, {"交易对手方","02" }, + {"1","01" }, + {"2","02" }, + {"01","01" }, + {"02","02" } }); } return _optionTraderMap; @@ -612,27 +708,49 @@ namespace YLErp.DBModels.Consts {"看涨","0" }, {"看跌","1" }, {"双向","2" }, + {"0","0" }, + {"1","1" }, + {"2","2" } }); } return _optionDirectionMap; } } + private static ExpandoDictionary _multiOrderOptionTypeMap; + /// + /// 多标的期权类型 + /// Best of:0 + /// Worst of:1 + /// 其他类型:2 + /// + public static ExpandoDictionary MultiOrderOptionTypeMap + { + get + { + if (_multiOrderOptionTypeMap == null) + { + _multiOrderOptionTypeMap = new ExpandoDictionary(new Dictionary() { + { "Best of","0"}, + { "Worst of","1"}, + { "其他类型","2"}, + {"0","0" }, + {"1","1" }, + {"2","2" } + }); + } + return _multiOrderOptionTypeMap; + } + } + private static ExpandoDictionary _optionStructureTypeMap; /// /// 期权结构类型 - /// 香草:0 - /// 二元:1 - /// 价差:2 - /// 鲨鱼鳍:4 - /// 障碍:5 - /// 区间累计:6 - /// 自动看涨:7 - /// AutoCallable:7 - /// Auto Callable:7 - /// 自动看涨(AutoCallable):7 - /// 自动看涨(Auto Callable):7 - /// 自动看涨(AutoCallable):7 - /// 自动看涨(Auto Callable):7 + /// 香草及其组合:0 + /// 二元及其组合:1 + /// 障碍及其组合:2 + /// 自动赎回:3 + /// 区间累计:4 + /// 安全气囊:5 /// 其他:99 /// public static ExpandoDictionary OptionStructureTypeMap @@ -642,20 +760,20 @@ namespace YLErp.DBModels.Consts if (_optionStructureTypeMap == null) { _optionStructureTypeMap = new ExpandoDictionary(new Dictionary() { - {"香草","0" }, - {"二元","1" }, - {"价差","2" }, - {"鲨鱼鳍","4" }, - {"障碍","5" }, - {"区间累计","6" }, - {"自动看涨","7" }, - {"AutoCallable","7" }, - {"Auto Callable","7" }, - {"自动看涨(AutoCallable)","7" }, - {"自动看涨(Auto Callable)","7" }, - {"自动看涨(AutoCallable)","7" }, - {"自动看涨(Auto Callable)","7" }, + {"香草及其组合","0" }, + {"二元及其组合","1" }, + {"障碍及其组合","2" }, + {"自动赎回","3" }, + {"区间累计","4" }, + {"安全气囊","5" }, {"其他","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" }, + {"4","4" }, + {"5","5" }, + {"99","99" } }); } return _optionStructureTypeMap; @@ -688,6 +806,22 @@ namespace YLErp.DBModels.Consts {"单鲨","06" }, {"双鲨","07" }, {"其他","08" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"4","04" }, + {"5","05" }, + {"6","06" }, + {"7","07" }, + {"8","08" }, + {"01","01" }, + {"02","02" }, + {"03","03" }, + {"04","04" }, + {"05","05" }, + {"06","06" }, + {"07","07" }, + {"08","08" } }); } return _sacOptionStructureTypeMap; @@ -712,11 +846,37 @@ namespace YLErp.DBModels.Consts {"美式","1" }, {"百慕大","2" }, {"亚式","3" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" } }); } return _exerciseApproachMap; } } + + private static ExpandoDictionary _clearingAgencyMap_optionDisplay; + + public static ExpandoDictionary ClearingAgencyMap_OptionDisplay + { + get + { + if (_clearingAgencyMap_optionDisplay == null) + { + _clearingAgencyMap_optionDisplay = new ExpandoDictionary(new Dictionary() + { + //{"甲方","0" }, + {"乙方","1" }, + {"甲方","0" },//原本是甲方,为了方便交易员理解,创建交易时直观,改成交易员方 + //{"中金","1" },//原本是乙方,为了方便交易员理解,创建交易时直观,改成客户方 + {"报价系统","3" } + }); + } + return _clearingAgencyMap_optionDisplay; + } + } + private static ExpandoDictionary _clearingAgencyMap; /// /// 清算机构 @@ -737,10 +897,18 @@ namespace YLErp.DBModels.Consts { {"甲方","0" }, {"乙方","1" }, + {"交易员方","0" },//原本是甲方,为了方便交易员理解,创建交易时直观,改成交易员方 + {"客户方","1" },//原本是乙方,为了方便交易员理解,创建交易时直观,改成客户方 {"报价系统","3" }, {"中债登","4" }, {"上清所","5" }, {"其他","99" }, + {"1","1" }, + {"0","0" }, + {"3","3" }, + {"4","4" }, + {"5","5" }, + {"99","99" } }); } return _clearingAgencyMap; @@ -769,7 +937,7 @@ namespace YLErp.DBModels.Consts {"报价系统","3" }, {"中债登","4" }, {"上清所","5" }, - {"其他","99" } + {"其他","99" }, }); } return _clearingAgencyMapDisplay; @@ -777,7 +945,7 @@ namespace YLErp.DBModels.Consts } private static ExpandoDictionary _tradingPlaceMap; /// - /// 交易场所 + /// 交易场所(用于报送) ///柜台市场:0 ///报价系统:1 ///银行间市场:2 @@ -795,6 +963,10 @@ namespace YLErp.DBModels.Consts {"报价系统","1" }, {"银行间市场","2" }, {"其他交易场所","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"99","99" } }); } return _tradingPlaceMap; @@ -845,6 +1017,13 @@ namespace YLErp.DBModels.Consts {"报价系统","02" }, {"银行间市场","03" }, {"其他交易场所","99" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"01","01" }, + {"02","02" }, + {"03","03" }, + {"99","99" } }); } return _isdaTradingPlaceMap; @@ -864,6 +1043,7 @@ namespace YLErp.DBModels.Consts _businessModelTypeMap = new ExpandoDictionary(new Dictionary() { {"传统型期权","1" }, + {"1","1" } }); } return _businessModelTypeMap; @@ -895,6 +1075,13 @@ namespace YLErp.DBModels.Consts {"汇率","4" }, {"混合类","5" }, {"其他","99" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" }, + {"4","4" }, + {"5","5" }, + {"99","99" } }); } return _undrlygAssetTypeMap; @@ -925,43 +1112,22 @@ namespace YLErp.DBModels.Consts {"信用类","04" }, {"汇率","05" }, {"其他","99" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"4","04" }, + {"5","05" }, + {"01","01" }, + {"02","02" }, + {"03","03" }, + {"04","04" }, + {"05","05" }, + {"99","99" } }); } return _sacUndrlygAssetTypeMap; } } - - private static ExpandoDictionary _isdaUndrlygAssetDtldTypeMap; - /// - /// ISDA标的类型 - /// 权益类(境内):01 - /// 权益类(境外):02 - /// 大宗商品:03 - /// 利率:04 - /// 信用类:05 - /// 汇率:06 - /// 其他:99 - /// - public static ExpandoDictionary ISDAUndrlygAssetDtldTypeMap - { - get - { - if (_isdaUndrlygAssetDtldTypeMap == null) - { - _isdaUndrlygAssetDtldTypeMap = new ExpandoDictionary(new Dictionary() - { - {"权益类(境内)","01"}, - {"权益类(境外)","02"}, - {"大宗商品","03"}, - {"利率","04"}, - {"信用类","05"}, - {"汇率","06"}, - {"其他","99"}, - }); - } - return _isdaUndrlygAssetDtldTypeMap; - } - } private static ExpandoDictionary _nafmiiUndrlygAssetDtldTypeMap; /// /// NAFMII标的类型 @@ -986,6 +1152,18 @@ namespace YLErp.DBModels.Consts {"黄金期货","04"}, {"利率类","05"}, {"其他","06"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"} }); } return _nafmiiUndrlygAssetDtldTypeMap; @@ -1009,6 +1187,8 @@ namespace YLErp.DBModels.Consts {"单一标的","0" }, {"组合标的","1" }, {"多标的","1" }, + {"0","0" }, + {"1","1" } }); } return _undrlygAssetNoMap; @@ -1021,6 +1201,7 @@ namespace YLErp.DBModels.Consts ///无履约担保:0 ///部分担保:1 ///全额担保:2 + ///双方不涉及履约担保:3 /// public static ExpandoDictionary PerformanceGuaranteeMap { @@ -1034,14 +1215,17 @@ namespace YLErp.DBModels.Consts {"无履约担保","0" }, {"部分担保","1" }, {"全额担保","2" }, + {"双方不涉及履约担保","3" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" }, }); } return _performanceGuaranteeTypeMap; } } - private static ExpandoDictionary _performanceCollProviderMap; private static ExpandoDictionary _performanceGuaranteeMapDisplay; - /// /// 履约担保类型(用于页面展示) ///否:0 @@ -1058,7 +1242,6 @@ namespace YLErp.DBModels.Consts { _performanceGuaranteeMapDisplay = new ExpandoDictionary(new Dictionary() { - {"无","" }, {"无履约担保","0" }, {"部分担保","1" }, {"全额担保","2" }, @@ -1067,6 +1250,7 @@ namespace YLErp.DBModels.Consts return _performanceGuaranteeMapDisplay; } } + private static ExpandoDictionary _performanceCollProviderMap; /// /// 履约担保品提供方 ///甲方:0 @@ -1088,13 +1272,16 @@ namespace YLErp.DBModels.Consts {"第三方","2" }, {"第三方(需在履约担保备注中说明第三方相关情况)","2" }, {"交易双方","3" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" } }); } return _performanceCollProviderMap; } } private static ExpandoDictionary _performanceCollProviderMapDisplay; - /// /// 履约担保品提供方(用于页面展示) ///甲方:0 @@ -1120,7 +1307,6 @@ namespace YLErp.DBModels.Consts return _performanceCollProviderMapDisplay; } } - private static ExpandoDictionary _boolMap; /// /// Bool @@ -1137,11 +1323,14 @@ namespace YLErp.DBModels.Consts { {"是","true" }, {"否","false" }, + {"true","true" }, + {"false","false" } }); } return _boolMap; } } + private static ExpandoDictionary _boolMapDisplay; /// /// Bool (用于页面展示) @@ -1179,6 +1368,10 @@ namespace YLErp.DBModels.Consts { {"是","01" }, {"否","02" }, + {"1","01" }, + {"2","02" }, + {"01","01" }, + {"02","02" } }); } return _boolNumberMap; @@ -1245,6 +1438,28 @@ namespace YLErp.DBModels.Consts {"银行间回购定盘(Fixing Repo Rate)","19"}, {"其他利率","20"}, {"其他标的","99"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"}, + {"7","7"}, + {"8","8"}, + {"9","9"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"19","19"}, + {"20","20"}, + {"99","99"} }); } return _undrlygAssetDtldTypeMap; @@ -1304,6 +1519,26 @@ namespace YLErp.DBModels.Consts {"汇率","17"}, {"利率","18"}, {"其他标的","99"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"}, + {"7","7"}, + {"8","8"}, + {"9","9"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"99","99"} }); } return _swapUndrlygAssetDtldTypeMap; @@ -1366,6 +1601,37 @@ namespace YLErp.DBModels.Consts {"银行间回购定盘(FixingRepoRate)","20"}, {"其他利率","21"}, {"其他标的","99"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"9","09"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"09","09"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"19","19"}, + {"20","20"}, + {"21","21"}, + {"99","99"} }); } return _sacUndrlygAssetDtldTypeMap; @@ -1402,25 +1668,34 @@ namespace YLErp.DBModels.Consts { _swapSACUndrlygAssetDtldTypeMap = new ExpandoDictionary(new Dictionary() { - {"股票","01"}, - {"股指","02"}, - {"新三板挂牌股票","03"}, - {"香港股票","04"}, - {"香港股指","05"}, - {"基金及基金专户","06"}, - {"债券","07"}, - {"黄金期货","08"}, - {"国债期货","09"}, - {"股指期货","10"}, - {"其他期货","11"}, - {"黄金现货","12"}, - {"其他现货","13"}, - {"境外期货","14"}, - {"境外现货","15"}, - {"境外股票","16"}, - {"境外股指","17"}, - {"汇率","18"}, - {"其他标的","99"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"9","09"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"09","09"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"99","99"}, }); } return _swapSACUndrlygAssetDtldTypeMap; @@ -1459,6 +1734,19 @@ namespace YLErp.DBModels.Consts {"香港股指","06"}, {"其他","99"}, {"其他标的","99"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"99","99"} }); } return _hedgeSACUndrlygAssetDtldTypeMap; @@ -1501,6 +1789,27 @@ namespace YLErp.DBModels.Consts {"境外交易所","11"}, {"其他","99"}, {"其他(注明具体场所)","99"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"9","09"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"09","09"}, + {"10","10"}, + {"11","11"}, + {"99","99"} }); } return _undrlygAssetTradgPlcMap; @@ -1537,6 +1846,23 @@ namespace YLErp.DBModels.Consts {"外汇交易中心","08"}, {"其他","99"}, {"其他(注明具体场所)","99"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"99","99"} }); } return _hedgeUndrlygAssetTradgPlcMap; @@ -1574,11 +1900,18 @@ namespace YLErp.DBModels.Consts {"其他(须在履约担保备注栏进行说明)","99" }, {"其他(需在履约担保备注栏进行说明)","99" }, {"其他(须在履约担保备注栏进行说明)","99" }, + {"0","0"}, + {"1","1"}, + {"2","2" }, + {"3","3" }, + {"99","99" } }); } return _performanceCollTypeMap; } } + + private static ExpandoDictionary _performanceCollTypeMapDisplay; /// /// 履约担保品类型(用于页面展示) ///现金:0 @@ -1605,7 +1938,6 @@ namespace YLErp.DBModels.Consts return _performanceCollTypeMapDisplay; } } - private static ExpandoDictionary _performanceCollTypeMapDisplay; private static ExpandoDictionary _performanceCollRangeMap; /// @@ -1627,11 +1959,16 @@ namespace YLErp.DBModels.Consts {"本笔交易对应主协议框架下的所有交易(在附件中上传履约担保协议)","1"}, {"其他情况下多笔交易","2"}, {"其他情况下多笔交易(在附件中上传履约担保协议)","2"}, + {"0","0"}, + {"1","1"}, + {"2","2"} }); } return _performanceCollRangeMap; } } + + private static ExpandoDictionary _performanceCollRangeMapDisplay; /// /// 担保品担保范围(用于页面展示) ///仅本笔交易:0 @@ -1654,7 +1991,6 @@ namespace YLErp.DBModels.Consts return _performanceCollRangeMapDisplay; } } - private static ExpandoDictionary _performanceCollRangeMapDisplay; private static ExpandoDictionary _paymentMethodMap; /// @@ -1686,6 +2022,11 @@ namespace YLErp.DBModels.Consts {"固定利率","3"}, {"固定利率收益","3"}, {"权益收益多空组合","4"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"} }); } return _paymentMethodMap; @@ -1709,6 +2050,9 @@ namespace YLErp.DBModels.Consts {"期初支付","0"}, {"期末支付","1"}, {"期间多次支付","2"}, + {"0","0"}, + {"1","1"}, + {"2","2"} }); } return _paymentFreqMap; @@ -1730,6 +2074,8 @@ namespace YLErp.DBModels.Consts { {"单一标的","0"}, {"多标的","1"}, + {"0","0"}, + {"1","1"} }); } return _ptyBUndrlygAssetNoMap; @@ -1755,6 +2101,10 @@ namespace YLErp.DBModels.Consts {"开空仓","1" }, {"平多仓","2" }, {"平空仓","3" }, + {"0","0" }, + {"1","1" }, + {"2","2" }, + {"3","3" } }); } return _undrlygAssetPositionMap; @@ -1790,6 +2140,15 @@ namespace YLErp.DBModels.Consts {"Libor1M","6"}, {"Hibor1M","7"}, {"其他","99"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"}, + {"7","7"}, + {"99","99"} }); } return _refRateTypeMap; @@ -1797,11 +2156,13 @@ namespace YLErp.DBModels.Consts } private static ExpandoDictionary _operationTypeMap; /// - /// 参考利率类型 + /// 存续期操作类型 /// 展期:01 /// 终止:02 /// 违约终止:03 /// 调仓:04 + /// 敲入:05 + /// 敲出:06 /// public static ExpandoDictionary OperationTypeMap { @@ -1815,11 +2176,58 @@ namespace YLErp.DBModels.Consts {"终止","02"}, {"违约终止","03"}, {"调仓","04"}, + {"敲入","05"}, + {"敲出","06"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"} }); } return _operationTypeMap; } } + private static ExpandoDictionary _swapOperationTypeMap; + /// + /// 互换存续期操作类型 + /// 展期:1 + /// 终止:2 + /// 违约终止:3 + /// 调仓:4 + /// + public static ExpandoDictionary SwapOperationTypeMap + { + get + { + if (_swapOperationTypeMap == null) + { + _swapOperationTypeMap = new ExpandoDictionary(new Dictionary() + { + {"展期","1"}, + {"终止","2"}, + {"违约终止","3"}, + {"调仓","4"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"01","1"}, + {"02","2"}, + {"03","3"}, + {"04","4"}, + }); + } + return _swapOperationTypeMap; + } + } private static ExpandoDictionary _businessTypeMap; /// /// 业务类型 @@ -1850,6 +2258,18 @@ namespace YLErp.DBModels.Consts {"收益互换(客户空头)","12"}, {"多空组合收益互换","13"}, {"其他收益互换","14"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"} }); } return _businessTypeMap; @@ -1875,6 +2295,14 @@ namespace YLErp.DBModels.Consts {"互换看跌","02" }, {"利率上限","03" }, {"利率下限","04" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"4","04" }, + {"01","01" }, + {"02","02" }, + {"03","03" }, + {"04","04" } }); } return _nafmiiOptionDirectionMap; @@ -1902,6 +2330,16 @@ namespace YLErp.DBModels.Consts {"lpr1y_irs","03" }, {"lpr5y_irs","04" }, {"其他","05" }, + {"1","01" }, + {"2","02" }, + {"3","03" }, + {"4","04" }, + {"5","05" }, + {"01","01" }, + {"02","02" }, + {"03","03" }, + {"04","04" }, + {"05","05" } }); } return _nafmiiInvestmentNameMap; @@ -1923,6 +2361,10 @@ namespace YLErp.DBModels.Consts { {"实物交割","01" }, {"现金交割","02" }, + {"1","01" }, + {"2","02" }, + {"01","01" }, + {"02","02" } }); } return _nafmiiDeliveryTypeMap; @@ -1944,6 +2386,10 @@ namespace YLErp.DBModels.Consts { {"本月新增业务","01"}, {"截至上月底尚未完全终止业务","02"}, + {"1","01"}, + {"2","02"}, + {"01","01"}, + {"02","02"} }); } return _dataTypeForBusinessMap; @@ -2040,6 +2486,55 @@ namespace YLErp.DBModels.Consts {"期权","36"}, {"其他衍生品","37"}, {"其他标的","99"}, + {"0","00"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"9","09"}, + {"00","00"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"09","09"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"19","19"}, + {"20","20"}, + {"21","21"}, + {"22","22"}, + {"23","23"}, + {"24","24"}, + {"25","25"}, + {"26","26"}, + {"27","27"}, + {"28","28"}, + {"29","29"}, + {"30","30"}, + {"31","31"}, + {"32","32"}, + {"33","33"}, + {"34","34"}, + {"35","35"}, + {"36","36"}, + {"37","37"}, + {"99","99"} }); } return _investmentTargetTypeMap; @@ -2135,10 +2630,505 @@ namespace YLErp.DBModels.Consts {"期权","36"}, {"其他衍生品","37"}, {"其他标的","99"}, + {"0","00"}, + {"1","01"}, + {"2","02"}, + {"3","03"}, + {"4","04"}, + {"5","05"}, + {"6","06"}, + {"7","07"}, + {"8","08"}, + {"9","09"}, + {"00","00"}, + {"01","01"}, + {"02","02"}, + {"03","03"}, + {"04","04"}, + {"05","05"}, + {"06","06"}, + {"07","07"}, + {"08","08"}, + {"09","09"}, + {"10","10"}, + {"11","11"}, + {"12","12"}, + {"13","13"}, + {"14","14"}, + {"15","15"}, + {"16","16"}, + {"17","17"}, + {"18","18"}, + {"19","19"}, + {"20","20"}, + {"21","21"}, + {"22","22"}, + {"23","23"}, + {"24","24"}, + {"25","25"}, + {"26","26"}, + {"27","27"}, + {"28","28"}, + {"29","29"}, + {"30","30"}, + {"31","31"}, + {"32","32"}, + {"33","33"}, + {"34","34"}, + {"35","35"}, + {"36","36"}, + {"37","37"}, + {"99","99"} }); } return _hedgeUnderlyingTypeMap; } } + + private static ExpandoDictionary _vanillaOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///香草:0 + ///跨式:1 + ///宽跨式:2 + ///参与式看涨:3 + ///两段参与式看涨:4 + ///价差:5 + ///区间保护看涨:6 + ///有限区间保护看涨:7 + ///区间保护看涨价差:8 + ///有限区间保护看涨价差:9 + ///鹰式:10 + ///蝶式:11 + ///其他香草及其组合:12 + /// + public static ExpandoDictionary VanillaOptionStructureSubclassMap + { + get + { + if (_vanillaOptionStructureSubclassMap == null) + { + _vanillaOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"香草","0"}, + {"跨式","1"}, + {"宽跨式","2"}, + {"参与式看涨","3"}, + {"两段参与式看涨","4"}, + {"价差","5"}, + {"区间保护看涨","6"}, + {"有限区间保护看涨","7"}, + {"区间保护看涨价差","8"}, + {"有限区间保护看涨价差","9"}, + {"鹰式","10"}, + {"蝶式","11"}, + {"其他香草及其组合","12"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"}, + {"7","7"}, + {"8","8"}, + {"9","9"}, + {"10","10"}, + {"11","11"}, + {"12","12"} + }); + } + return _vanillaOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _digitalOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///欧式二元:0 + ///美式二元触碰:1 + ///美式二元不触碰:2 + ///美式双触碰:3 + ///美式双不触碰:4 + ///二元凹式:5 + ///二元凸式:6 + ///三层阶梯:7 + ///四层阶梯:8 + ///四层阶梯/:8 + ///其他二元及其组合:9 + /// + public static ExpandoDictionary DigitalOptionStructureSubclassMap + { + get + { + if (_digitalOptionStructureSubclassMap == null) + { + _digitalOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"欧式二元","0"}, + {"美式二元触碰","1"}, + {"美式二元不触碰","2"}, + {"美式双触碰","3"}, + {"美式双不触碰","4"}, + {"二元凹式","5"}, + {"二元凸式","6"}, + {"三层阶梯","7"}, + {"四层阶梯","8"}, + {"四层阶梯/","8"}, + {"其他二元及其组合","9"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"}, + {"7","7"}, + {"8","8"}, + {"9","9"} + }); + } + return _digitalOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _barrierOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///敲入障碍类:0 + ///单向鲨鱼鳍:1 + ///双向鲨鱼鳍:2 + ///其他障碍及其组合:3 + /// + public static ExpandoDictionary BarrierOptionStructureSubclassMap + { + get + { + if (_barrierOptionStructureSubclassMap == null) + { + _barrierOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"敲入障碍类","0"}, + {"单向鲨鱼鳍","1"}, + {"双向鲨鱼鳍","2"}, + {"其他障碍及其组合","3"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"} + }); + } + return _barrierOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _barrierObservationTypeMap; + /// + /// 期权结构小类 + ///到期观察:0 + ///每日观察:1 + ///离散观察:2 + /// + public static ExpandoDictionary BarrierObservationTypeMap + { + get + { + if (_barrierObservationTypeMap == null) + { + _barrierObservationTypeMap = new ExpandoDictionary(new Dictionary() + { + {"到期观察","0"}, + {"每日观察","1"}, + {"离散观察","2"}, + {"0","0"}, + {"1","1"}, + {"2","2"} + }); + } + return _barrierObservationTypeMap; + } + } + + private static ExpandoDictionary _autoCallableOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///保本雪球(二元):0 + ///保本雪球(三元):1 + ///非保本普通型雪球:2 + ///非保本要素(敲入、敲出、收益率)可变型雪球:3 + ///非保本普通型凤凰:4 + ///非保本要素(敲入、敲出、收益率) 可变型凤凰:5 + ///其他自动赎回:6 + /// + public static ExpandoDictionary AutoCallableOptionStructureSubclassMap + { + get + { + if (_autoCallableOptionStructureSubclassMap == null) + { + _autoCallableOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"保本雪球(二元)","0"}, + {"保本雪球(二元)","0"}, + {"保本雪球(三元)","1"}, + {"保本雪球(三元)","1"}, + {"非保本普通型雪球","2"}, + {"非保本要素(敲入、敲出、收益率)可变型雪球","3"}, + {"非保本要素(敲入、敲出、收益率)可变型雪球","3"}, + {"非保本要素(敲入\\敲出\\收益率)可变型雪球","3"}, + {"非保本要素(敲入\\敲出\\收益率)可变型雪球","3"}, + {"非保本普通型凤凰","4"}, + {"非保本要素(敲入、敲出、收益率)可变型凤凰","5"}, + {"非保本要素(敲入、敲出、收益率)可变型凤凰","5"}, + {"非保本要素(敲入\\敲出\\收益率)可变型凤凰","5"}, + {"非保本要素(敲入\\敲出\\收益率)可变型凤凰","5"}, + {"其他自动赎回","6"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"}, + {"6","6"} + }); + } + return _autoCallableOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherDiscountedWarehouseTypeMap; + /// + /// 是否为折价建仓型 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherDiscountedWarehouseTypeMap + { + get + { + if (_autoCallableWhetherDiscountedWarehouseTypeMap == null) + { + _autoCallableWhetherDiscountedWarehouseTypeMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherDiscountedWarehouseTypeMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherRevenueEnhancedTypeMap; + /// + /// 是否为收益增强型 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherRevenueEnhancedTypeMap + { + get + { + if (_autoCallableWhetherRevenueEnhancedTypeMap == null) + { + _autoCallableWhetherRevenueEnhancedTypeMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherRevenueEnhancedTypeMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherKnockInPriceCoefficientIsVariableMap; + /// + /// 敲入价格系数是否可变 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherKnockInPriceCoefficientIsVariableMap + { + get + { + if (_autoCallableWhetherKnockInPriceCoefficientIsVariableMap == null) + { + _autoCallableWhetherKnockInPriceCoefficientIsVariableMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherKnockInPriceCoefficientIsVariableMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherKnockOutPriceCoefficientIsVariableMap; + /// + /// 敲出价格系数是否可变 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherKnockOutPriceCoefficientIsVariableMap + { + get + { + if (_autoCallableWhetherKnockOutPriceCoefficientIsVariableMap == null) + { + _autoCallableWhetherKnockOutPriceCoefficientIsVariableMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherKnockOutPriceCoefficientIsVariableMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherKnockOutYieldIsVariableMap; + /// + /// 敲出收益率是否可变 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherKnockOutYieldIsVariableMap + { + get + { + if (_autoCallableWhetherKnockOutYieldIsVariableMap == null) + { + _autoCallableWhetherKnockOutYieldIsVariableMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherKnockOutYieldIsVariableMap; + } + } + + private static ExpandoDictionary _autoCallableWhetherDividendYieldIsVariableMap; + /// + /// 敲出收益率是否可变 + ///是:0 + ///否:1 + /// + public static ExpandoDictionary AutoCallableWhetherDividendYieldIsVariableMap + { + get + { + if (_autoCallableWhetherDividendYieldIsVariableMap == null) + { + _autoCallableWhetherDividendYieldIsVariableMap = new ExpandoDictionary(new Dictionary() + { + {"是","0"}, + {"否","1"}, + {"0","0"}, + {"1","1"} + }); + } + return _autoCallableWhetherDividendYieldIsVariableMap; + } + } + + private static ExpandoDictionary _rangeAccrualOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///区间累计:0 + ///双层区间累计:1 + ///其他区间累计:2 + /// + public static ExpandoDictionary RangeAccrualOptionStructureSubclassMap + { + get + { + if (_rangeAccrualOptionStructureSubclassMap == null) + { + _rangeAccrualOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"区间累计","0"}, + {"双层区间累计","1"}, + {"其他区间累计","2"}, + {"0","0"}, + {"1","1"}, + {"2","2"} + }); + } + return _rangeAccrualOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _airbagOptionStructureSubclassMap; + /// + /// 期权结构小类 + ///安全气囊看涨:0 + ///安全气囊看涨价差:1 + ///安全气囊看涨保护:2 + ///安全气囊看涨价差保护:3 + ///上段封顶安全气囊:4 + ///上端封顶安全气囊:4 + ///其他气囊结构:5 + /// + public static ExpandoDictionary AirbagOptionStructureSubclassMap + { + get + { + if (_airbagOptionStructureSubclassMap == null) + { + _airbagOptionStructureSubclassMap = new ExpandoDictionary(new Dictionary() + { + {"安全气囊看涨","0"}, + {"安全气囊看涨价差","1"}, + {"安全气囊看涨保护","2"}, + {"安全气囊看涨价差保护","3"}, + {"上段封顶安全气囊","4"}, + {"上端封顶安全气囊","4"}, + {"其他气囊结构","5"}, + {"0","0"}, + {"1","1"}, + {"2","2"}, + {"3","3"}, + {"4","4"}, + {"5","5"} + }); + } + return _airbagOptionStructureSubclassMap; + } + } + + private static ExpandoDictionary _barrierEventStatusMap; + /// + /// 期权结构小类 + ///已敲入:01 + ///已敲出:02 + /// + public static ExpandoDictionary BarrierEventStatusMap + { + get + { + if (_barrierEventStatusMap == null) + { + _barrierEventStatusMap = new ExpandoDictionary(new Dictionary() + { + {"已敲入","01"}, + {"已敲出","02"}, + {"1","01"}, + {"2","02"}, + {"01","01"}, + {"02","02"} + }); + } + return _barrierEventStatusMap; + } + } } } diff --git a/Framework/YLErp.Core/DBModels/Enums/SuperviseReportTypeEnum.cs b/Framework/YLErp.Core/DBModels/Enums/SuperviseReportTypeEnum.cs index 8689596d..df8d9e83 100644 --- a/Framework/YLErp.Core/DBModels/Enums/SuperviseReportTypeEnum.cs +++ b/Framework/YLErp.Core/DBModels/Enums/SuperviseReportTypeEnum.cs @@ -95,5 +95,15 @@ /// [Description("互换交易确认书附件")] SAC_ConfirmationAtt = 17, + /// + /// 场外期权估值 + /// + [Description("场外期权估值")] + SAC_ValuationInformation = 18, + /// + /// 场外期权交易确认书附件 + /// + [Description("场外期权交易确认书附件")] + SAC_OptionConfirmationAtt = 19, } } diff --git a/YLErpDAL/Modules/AppModule/AppUpgrader.cs b/YLErpDAL/Modules/AppModule/AppUpgrader.cs index f9488b0b..4617f13f 100644 --- a/YLErpDAL/Modules/AppModule/AppUpgrader.cs +++ b/YLErpDAL/Modules/AppModule/AppUpgrader.cs @@ -210,7 +210,7 @@ namespace YLErp.Modules.AppModule configService.AddDataIfNotExists("ProjectConfig", "SAC_FDEPOutboxPath", data?.PValue ?? "", "string", "FDEP发件箱目录,支持本地目录,内网共享目录和Ftp目录,共享路径例:\\\\192.168.1.200\\share-test\\ ;Ftp目录应填不包含根目录的相对目录例\\share-test\\ 注意:共享路径和ftp模式下,不要忘记最后的\\"); data = configService.RemoveData("ProjectConfig", "SACReportDataSource"); - configService.AddDataIfNotExists("ProjectConfig", "SAC_ReportDataSource", data?.PValue ?? "3", "int", "证券业报送数据源;1=Db;2=Excel模板;3=Db+Excel模板(该方式中涉及百分比汇总计算时仍使用模板中数据)"); + configService.AddDataIfNotExists("ProjectConfig", "SAC_ReportDataSource", data?.PValue ?? "3", "int", "证券业报送数据源;2=Excel模板;"); configService.AddDataIfNotExists("ProjectConfig", "SAC_FtpUsePassive", data?.PValue ?? "false", "bool", "FDEP收发目录如果采用Ftp时,这里要选择是否为被动模式,不确定就选false"); diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/BaseCheckHelper.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/BaseCheckHelper.cs index 6e6a5a8b..29eabe0e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/BaseCheckHelper.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/BaseCheckHelper.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Globalization; using System.Reflection; namespace YLErp.Modules.SuperviseReportModule.SAC.Common @@ -56,11 +56,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - bool state = false; - string text = (value?.ToString()) ?? ""; + var state = false; + var text = (value?.ToString()) ?? ""; if (text.Length == 0) { - state = (!Required || IgnoreNullOrEmpty); + state = !Required || IgnoreNullOrEmpty; } else { @@ -258,7 +258,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - bool match = false; + var match = false; if (Multiple) { var split = EndsWithString.Split(SplitStr.ToCharArray()); @@ -316,13 +316,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - bool result = true; + var result = true; try { - result = DateTime.TryParseExact((value ?? ""), FormatString, CultureInfo.CurrentCulture, DateTimeStyles.None, out _); + result = DateTime.TryParseExact(value ?? "", FormatString, CultureInfo.CurrentCulture, DateTimeStyles.None, out _); if (!result) { - result = DateTime.TryParse(value ?? "", out DateTime temp); + result = DateTime.TryParse(value ?? "", out var temp); if (result) { UseChangeValue = true; @@ -410,7 +410,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common minValue = MinValue_Number; maxValue = MaxValue_Number; } - List msgArr = new List(); + var msgArr = new List(); if (!double.IsNaN(minValue)) { msgArr.Add(">={MinValue}"); @@ -439,7 +439,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common int beforePointMaxLength, afterPointMaxLength; double maxValue, minValue; - isPercent = value.EndsWith("%"); + isPercent = isPercent = value != null && value.EndsWith("%"); if (isPercent) { value = value.Remove(value.Length - 1); @@ -455,11 +455,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common maxValue = MaxValue_Number; minValue = MinValue_Number; } - if (!double.TryParse(value, out double temp)) + if (!double.TryParse(value, out var temp)) { return false; } - string[] part = (value ?? "").Split('.'); + var part = (value ?? "").Split('.'); if (part.Length > 2) { return false; @@ -468,6 +468,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { return false; } + if (!double.IsNaN(maxValue) && temp > maxValue) + { + return false; + } + if (!double.IsNaN(minValue) && temp < minValue) + { + return false; + } if (part.Length > 1 && part[1].Length > afterPointMaxLength) { UseChangeValue = true; @@ -476,14 +484,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common ChangedValue = temp.ToString(sufix) + (isPercent ? "%" : ""); return true; } - if (!double.IsNaN(maxValue) && temp > maxValue) - { - return false; - } - if (!double.IsNaN(minValue) && temp < minValue) - { - return false; - } return true; } @@ -492,7 +492,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common int beforePointMaxLength, afterPointMaxLength; double maxValue, minValue; - isPercent = isPercent = value != null && value.EndsWith("%"); + isPercent = isPercent = value != null && value.EndsWith("%"); if (isPercent) { value = value.Remove(value.Length - 2); @@ -512,8 +512,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common .Replace("{fieldValue}", value) .Replace("{BeforePointMaxLength}", beforePointMaxLength.ToString()) .Replace("{AfterPointMaxLength}", afterPointMaxLength.ToString()) - .Replace("{MinValue}", maxValue.ToString()) - .Replace("{MaxValue}", minValue.ToString()); + .Replace("{MinValue}", minValue.ToString()) + .Replace("{MaxValue}", maxValue.ToString()); } } @@ -554,7 +554,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { //_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; _errMsg = "值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]"; - List msgArr = new List(); + var msgArr = new List(); if (!double.IsNaN(MinValue)) { msgArr.Add(">={MinValue}"); @@ -578,11 +578,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - if (!double.TryParse(value, out double temp)) + if (!double.TryParse(value, out var temp)) { return false; } - string[] part = (value ?? "").Split('.'); + var part = (value ?? "").Split('.'); if (part.Length > 2) { return false; @@ -591,23 +591,24 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { return false; } + var state = true; if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointMaxLength)) { UseChangeValue = true; - string sufix = "0.".PadRight(AfterPointMaxLength + 2, '0'); + var sufix = "0.".PadRight(AfterPointMaxLength + 2, '0'); UseChangeValue = true; ChangedValue = temp.ToString(sufix); - return true; + state = true; } if (!double.IsNaN(MinValue) && temp < MinValue) { - return false; + state = false; } if (!double.IsNaN(MaxValue) && temp > MaxValue) { - return false; + state = false; } - return true; + return state; } protected override string GenerateErrMsg(string value) @@ -659,7 +660,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { //_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]"; _errMsg = "值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]"; - List msgArr = new List(); + var msgArr = new List(); if (!double.IsNaN(MinValue)) { msgArr.Add(">={MinValue}"); @@ -683,7 +684,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - if (!double.TryParse(value, out double temp)) + if (!double.TryParse(value, out var temp)) { return false; } @@ -695,14 +696,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { return false; } - string[] part = (value ?? "").Split('.'); + var part = (value ?? "").Split('.'); if (part[0].Length > BeforePointMaxLength) { return false; } if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointLength)) { - string sufix = "0.".PadRight(AfterPointLength + 2, '0'); + var sufix = "0.".PadRight(AfterPointLength + 2, '0'); UseChangeValue = true; ChangedValue = temp.ToString(sufix); return true; @@ -728,8 +729,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { public override bool Execute(object value) { - bool state = false; - IEnumerable objs = value as IEnumerable; + var state = false; + var objs = value as IEnumerable; //if (objs != null) //{ state = Execute(objs); @@ -869,7 +870,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - return Map.Contains((value ?? "")); + return Map.Contains(value ?? ""); } protected override string GenerateErrMsg(string value) @@ -912,7 +913,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common protected override bool Execute(string value) { - int length = value.Length; + var length = value.Length; return Map.Contains(length); } @@ -974,7 +975,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - return (value?.ToString() == ConditionValue); + return value?.ToString() == ConditionValue; } } /// @@ -989,7 +990,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - return (value?.ToString() != ConditionValue); + return value?.ToString() != ConditionValue; } } @@ -1012,7 +1013,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - if (double.TryParse((value ?? "").ToString(), out double temp)) + if (double.TryParse((value ?? "").ToString(), out var temp)) { return temp >= MinValue && temp <= MaxValue; } @@ -1038,7 +1039,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - if (int.TryParse((value ?? "").ToString(), out int temp)) + if (double.TryParse((value ?? "").ToString(), out double temp)) { return temp < MinValue || temp > MaxValue; } @@ -1055,7 +1056,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - return ConditionMap.Contains((value?.ToString() ?? "")); + return ConditionMap.Contains(value?.ToString() ?? ""); } } @@ -1068,7 +1069,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common public override bool Execute(object value) { - return !ConditionMap.Contains((value?.ToString() ?? "")); + return !ConditionMap.Contains(value?.ToString() ?? ""); } } @@ -1078,14 +1079,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common /// 检查帮助类 /// /// - public class CheckHelper + public class CheckHelper where T:notnull { - private PropertyInfo[] _properties = null; + private readonly PropertyInfo[]? _properties = null; /// /// 属性缓存 /// 应通过方法访问 /// - private Dictionary> _propertyInfoDict = null; + private Dictionary>? _propertyInfoDict = null; /// /// 检查不通过时回调的委托 /// @@ -1101,10 +1102,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common private Dictionary getPropertyInfos(T obj) { - if (_propertyInfoDict == null) - { - _propertyInfoDict = new Dictionary>(); - } + _propertyInfoDict ??= new Dictionary>(); if (!_propertyInfoDict.ContainsKey(obj)) { _propertyInfoDict[obj] = _properties.ToDictionary(K => K.Name, V => V.GetValue(obj)); @@ -1114,7 +1112,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common private bool checkCondition(List conditionAttributes, Dictionary dict) { - bool state = true; + var state = true; foreach (var item in conditionAttributes) { if (!dict.ContainsKey(item.ConditionName)) @@ -1132,14 +1130,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common private bool checkCondition(PropertyInfo pInfo, T obj, Func callback) { - bool state = true; - IEnumerable conditionAttrs = pInfo.GetCustomAttributes(typeof(BaseCheckConditionAttribute), true).Cast(); + var state = true; + var conditionAttrs = pInfo.GetCustomAttributes(typeof(BaseCheckConditionAttribute), true).Cast(); var conditGroup = conditionAttrs.GroupBy(O => O.CheckHandleNameArr == null ? "" : string.Join(",", O.CheckHandleNameArr)).ToDictionary(K => K.Key, V => V.ToList()); if (conditGroup.Count > 0) { foreach (var condit in conditGroup) { - Dictionary dict = getPropertyInfos(obj); + var dict = getPropertyInfos(obj); state = checkCondition(condit.Value, dict); if (state) { @@ -1161,7 +1159,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common private bool checkValue(string checkName, BaseCheckAttribute[] checkAttributes, PropertyInfo pInfo, T obj, out string errMsg) { errMsg = ""; - bool state = true; + var state = true; var attrs = checkAttributes.Where(O => (O.CheckHandleName ?? "") == checkName); foreach (var item in attrs) { @@ -1187,23 +1185,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common /// public bool ExecuteCheck(T obj, CheckErrorCallback callback) { - bool checkState = false; - string errMsg; + var checkState = false; if (obj == null) { return checkState; } foreach (var p in _properties) { - BaseCheckAttribute[] attr = p.GetCustomAttributes(typeof(BaseCheckAttribute), true).Cast().ToArray(); + var attr = p.GetCustomAttributes(typeof(BaseCheckAttribute), true).Cast().ToArray(); if (attr.Length == 0) { continue; } checkCondition(p, obj, (checkNames) => { - bool status = true; + var status = true; foreach (var item in checkNames) { - if (!checkValue((item ?? ""), attr, p, obj, out errMsg)) + if (!checkValue(item ?? "", attr, p, obj, out var errMsg)) { callback(p.Name, p.GetValue(obj), errMsg); status = false; diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/ReportInfoHelper.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/ReportInfoHelper.cs new file mode 100644 index 00000000..1f27fee7 --- /dev/null +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/ReportInfoHelper.cs @@ -0,0 +1,2499 @@ +using DocumentFormat.OpenXml; +using NPOI.OpenXmlFormats.Dml; +using NPOI.SS.Formula.Functions; +using OfficeOpenXml; +using Qdp.Foundation.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YLErp.BLL; +using YLErp.DBModels.Consts; +using YLErp.Helpers; +using YLErp.Modules.SuperviseReportModule.SAC.Model; +using YLErp.Office; +using static YLErp.DBModels.Consts.ConsReport; +using XmlHelper = YLErp.Helpers.XmlHelper; + +namespace YLErp.Modules.SuperviseReportModule.SAC.Common +{ + public class ReportInfoHelper + { + static readonly IYcLogger logger; + + /// + /// 映射虚拟路径到物理路径 + /// + public Func MapPath { get; private set; } = null!; + + private List _reportInfoList = new List(); + + /// + /// 错误信息 + /// + public string ErrorMsg { get; private set; } = ""; + + static ReportInfoHelper() + { + logger = LogFactory.GetLogger(); + } + + public ReportInfoHelper() : this(OtcAppContext.MapPath) { } + + public ReportInfoHelper(Func mapPath) + { + this.MapPath = mapPath; + } + + public bool Init(int id) + { + var masterFileTag = DbContextFactory.GetYLDbContext().supervise_report.Where(O => O.id == id).Select(O => O.FileTag).FirstOrDefault(); + if (masterFileTag is null) + { + ErrorMsg = "未找到对应的报告"; + return false; + } + return Init(id, masterFileTag); + } + + public bool Init(int id, string fileTag) + { + return init(id, fileTag); + } + + public bool Init(params ReportRootModel[] reportInfo) + { + try + { + if (reportInfo is null || reportInfo.Length == 0) + { + ErrorMsg = "报告信息不应为空"; + return false; + } + foreach (var item in reportInfo) + { + switch (item.Header.BusiDataType) + { + case DataFlagsEnum.A1001: + setMasterAgrmtInfo(item); + break; + case DataFlagsEnum.A1002: + setMasterAgrmtProductInfo(item); + break; + case DataFlagsEnum.A1003: + setMasterSupAgrmtInfo(item); + break; + case DataFlagsEnum.A1004: + setOptionConfirmationInfo(item); + break; + case DataFlagsEnum.A1005: + setSwapConfirmationInfo(item); + break; + case DataFlagsEnum.A1006: + setSwapTerminationInfo(item); + break; + case DataFlagsEnum.A1007: + setOptionTerminationInfo(item); + break; + case DataFlagsEnum.A1008: + setPerformanceGuaranteeAgrmtInfo(item); + break; + case DataFlagsEnum.A1011: + setPeriodicReportSACInfo(item); + break; + case DataFlagsEnum.A1012: + setPeriodicReportNAFMIIInfo(item); + break; + case DataFlagsEnum.A1013: + setPeriodicReportISDAInfo(item); + break; + case DataFlagsEnum.A1016: + setSwapEquityPaymentInfo(item); + break; + case DataFlagsEnum.A1017: + setSwapConfirmationAttInfo(item); + break; + case DataFlagsEnum.A1018: + setValuationInformationInfo(item); + break; + case DataFlagsEnum.A1019: + setOptionConfirmationAttInfo(item); + break; + case DataFlagsEnum.A1009: + case DataFlagsEnum.A1010: + case DataFlagsEnum.A1014: + case DataFlagsEnum.A1015: + case DataFlagsEnum.NONE: + default: + break; + } + if (item.Annex != null && item.Annex.Count > 0) + { + item.Annex = item.Annex.Where(O => !string.IsNullOrWhiteSpace(O)).Select(O => MapPath(O)).ToList(); + } + _reportInfoList.Add(item); + } + return true; + } + catch (Exception ex) + { + ErrorMsg = "未知错误:" + ex.ToJson(); + return false; + } + } + + public bool Init(ReportResponse res) + { + if (res is null) + { + ErrorMsg = "报告信息不应为空"; + return false; + } + Init(res.Infos.ToArray()); + return true; + } + + /// + /// 转换为Zip文件 + /// 可用于重新上传的格式 + /// + /// 包含文件名的输出路径 + /// + public bool SaveToZipFile(string outZipPath) + { + try + { + if (_reportInfoList.Count == 0) + { + ErrorMsg = "未找到报告信息"; + return false; + } + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + var outPath = MapPath(outZipPath); + var originPath = Path.GetDirectoryName(outPath); + var tempPath = Path.Combine(originPath, DateTime.Now.ToString("yyyyMMddHHmmssfff")); + createDirectory(tempPath); + var masterAgrmtStatus = saveMasterAgrmtInfoToExcel(tempPath); + var optionConfirmationStatus = saveOptionConfirmationInfoToExcel(tempPath); + var optionValuationStatus = saveValuationInformationInfoToExcel(tempPath); + var optionConfirmationAttStatus = saveOptionConfirmationAttInfoToExcel(tempPath); + var optionTerminationStatus = saveOptionTerminationInfoToExcel(tempPath); + var swapConfirmationStatus = saveSwapConfirmationInfoToExcel(tempPath); + var swapEquityPaymentStatus = saveSwapEquityPaymentInfoToExcel(tempPath); + var swapConfirmationAttStatus = saveSwapConfirmationAttInfoToExcel(tempPath); + var swapTerminationStatus = saveSwapTerminationInfoToExcel(tempPath); + var sacStatus = saveSACReportInfoToExcel(tempPath); + var nafmiiStatus = saveNAFMIIReportInfoToExcel(tempPath); + var isdaStatus = saveISDAReportInfoToExcel(tempPath); + var attStatus = saveAttachment(tempPath); + + ZipHelper.ZipDirectory(tempPath, outPath); + Directory.Delete(tempPath, true); + + _reportInfoList.Clear(); + + return true; + } + catch (Exception ex) + { + ErrorMsg = "未知错误:" + ex.ToJson(); + return false; + } + } + + #region 保存到Excel + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveMasterAgrmtInfoToExcel(string rootPath) + { + var reportInfo_masterAgrmt = _reportInfoList.Where(O => O.Body.MasterAgrmt != null).SelectMany(O => O.Body.MasterAgrmt ?? new List()).ToList(); + var reportInfo_supAgrmt = _reportInfoList.Where(O => O.Body.SupAgrmt != null).SelectMany(O => O.Body.SupAgrmt ?? new List()).ToList(); + var reportInfo_masterProductAgrmt = _reportInfoList.Where(O => O.Body.MasterAgrmtProduct != null).SelectMany(O => O.Body.MasterAgrmtProduct ?? new List()).ToList(); + var reportInfo_performanceGuaranteeAgrmt = _reportInfoList.Where(O => O.Body.PerformanceGuaranteeAgrmt != null).SelectMany(O => O.Body.PerformanceGuaranteeAgrmt ?? new List()).ToList(); + + if (reportInfo_masterAgrmt.Count > 0 || + reportInfo_supAgrmt.Count > 0 || + reportInfo_masterProductAgrmt.Count > 0 || + reportInfo_performanceGuaranteeAgrmt.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "协议相关")); + var outPath = Path.Combine(path, "import_MasterAgrmt_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/协议相关/import_MasterAgrmt_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["主协议"] = reportInfo_masterAgrmt, + ["填报方业务代表明细"] = reportInfo_masterAgrmt.SelectMany(O => O.CounterpartyInformationTuple ?? new List()), + ["主协议关联产品列表"] = reportInfo_masterProductAgrmt, + ["补充协议"] = reportInfo_supAgrmt, + ["履约保证书明细"] = reportInfo_performanceGuaranteeAgrmt + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveOptionConfirmationInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.OptionConfirmation != null).SelectMany(O => O.Body.OptionConfirmation ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_OptionConfirmation_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_OptionConfirmation_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["期权交易确认书明细"] = reportInfo, + ["标的详情明细"] = reportInfo.SelectMany(O => O.UndrlygAssetTuple ?? new List()).ToList(), + ["履约担保品详情明细"] = reportInfo.SelectMany(O => O.PerformanceCollTuple ?? new List()).ToList(), + ["期权结构类型详情(香草及其组合)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["香草及其组合"]).ToList(), + ["期权结构类型详情(二元及其组合)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["二元及其组合"]).ToList(), + ["期权结构类型详情(障碍及其组合)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["障碍及其组合"]).ToList(), + ["期权结构类型详情(自动赎回)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["自动赎回"]).ToList(), + ["期权结构类型详情(区间累计)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["区间累计"]).ToList(), + ["期权结构类型详情(安全气囊)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["安全气囊"]).ToList(), + ["期权结构类型详情(其他)"] = reportInfo.Where(O => O.OptionStructureType == ConsReport.OptionStructureTypeMap["其他"]).ToList() + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveValuationInformationInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.ValuationInformation != null).SelectMany(O => O.Body.ValuationInformation ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_ValuationInformation_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_ValuationInformation_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["每日估值信息"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveOptionConfirmationAttInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.ConfirmationAtt != null && O.Body.ConfirmationAtt.Any(B => !string.IsNullOrWhiteSpace(B.ConfirmationAtt))).SelectMany(O => O.Body.ConfirmationAtt ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_OptionConfirmationAtt_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_OptionConfirmationAtt_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["场外期权确认书附件明细"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveOptionTerminationInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.OptionTermination != null).SelectMany(O => O.Body.OptionTermination ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_OptionTermination_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_OptionTermination_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["期权交易存续期明细"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveSwapConfirmationInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.SwapConfirmation != null).SelectMany(O => O.Body.SwapConfirmation ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_SwapConfirmation_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_SwapConfirmation_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["互换交易确认书明细"] = reportInfo, + ["收益互换交易费用支付端"] = reportInfo.SelectMany(O => O.CostPaymentTuple ?? new List()).ToList(), + ["履约担保品明细"] = reportInfo.SelectMany(O => O.PerformanceCollTuple ?? new List()).ToList() + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveSwapEquityPaymentInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.SwapEquityPayment != null).SelectMany(O => O.Body.SwapEquityPayment ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_SwapEquityPayment_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_SwapEquityPayment_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["收益互换交易权益端支付"] = reportInfo, + ["权益端支付明细"] = reportInfo.SelectMany(O => O.SwapEquityPaymentTuple ?? new List()).ToList() + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveSwapConfirmationAttInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.ConfirmationAtt != null && O.Body.ConfirmationAtt.Any(B => !string.IsNullOrWhiteSpace(B.ConfirmationFiles))).SelectMany(O => O.Body.ConfirmationAtt ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_SwapConfirmationAtt_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_SwapConfirmationAtt_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["收益互换确认书附件明细"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveSwapTerminationInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.SwapDurationManagement != null).SelectMany(O => O.Body.SwapDurationManagement ?? new List()).ToList(); + if (reportInfo?.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "交易相关")); + var outPath = Path.Combine(path, "import_SwapTermination_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/交易相关/import_SwapTermination_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["互换交易存续期明细"] = reportInfo, + ["合约持仓明细"] = reportInfo.SelectMany(O => O.CurrentPositionDetails ?? new List()).ToList(), + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveSACReportInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.PeriodicReportSAC != null).Select(O => O.Body.PeriodicReportSAC).FirstOrDefault(); + if (reportInfo != null) + { + var path = createDirectory(Path.Combine(rootPath, "定期报告")); + var outPath = Path.Combine(path, "import_SAC_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/定期报告/import_SAC_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["业务统计"] = reportInfo, + ["本月新增业务明细"] = reportInfo.IncreaseBusinessDetailsThisMonthTuple ?? new List(), + ["本月末存量业务明细"] = reportInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple ?? new List(), + ["标的情况与对冲"] = reportInfo.TargetCaseAndHedgeTuple ?? new List(), + ["履约担保情况"] = reportInfo, + ["盈亏情况"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveNAFMIIReportInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.PeriodicReportNAFMII != null).Select(O => O.Body.PeriodicReportNAFMII).FirstOrDefault(); + if (reportInfo != null) + { + var path = createDirectory(Path.Combine(rootPath, "定期报告")); + var outPath = Path.Combine(path, "import_NAFMII_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/定期报告/import_NAFMII_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["业务统计"] = reportInfo, + ["利率互换明细"] = reportInfo.InterestRateSwapDetails ?? new List(), + ["利率期权明细"] = reportInfo.InterestRateOptionDetails ?? new List(), + ["其他交易明细"] = reportInfo.ScheduleOfOtherTransactions ?? new List() + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存对象到Excel + /// + /// + /// + private bool saveISDAReportInfoToExcel(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Body.PeriodicReportISDA != null).Select(O => O.Body.PeriodicReportISDA).FirstOrDefault(); + if (reportInfo != null) + { + var path = createDirectory(Path.Combine(rootPath, "定期报告")); + var outPath = Path.Combine(path, "import_ISDA_template.xlsx"); + new ExcelTemplateGenerator() + .SetTemplateFile(MapPath("~/App_Docs/导出模板/报送模板/定期报告/import_ISDA_template.xlsx")) + .SetTemplateData(new Dictionary + { + ["业务统计"] = reportInfo, + ["本月新增业务明细"] = reportInfo.IncreaseBusinessDetailsThisMonthTuple ?? new List(), + ["本月末存量业务明细"] = reportInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple ?? new List(), + ["标的情况与对冲"] = reportInfo.TargetCaseAndHedgeTuple ?? new List(), + ["履约担保情况"] = reportInfo, + ["盈亏情况"] = reportInfo + }) + .OutputToFile(outPath); + } + return true; + } + + /// + /// 保存附件 + /// + /// + /// + private bool saveAttachment(string rootPath) + { + var reportInfo = _reportInfoList.Where(O => O.Annex != null).SelectMany(O => O.Annex ?? new List()).ToList(); + if (reportInfo != null && reportInfo.Count > 0) + { + var path = createDirectory(Path.Combine(rootPath, "附件")); + foreach (var att in reportInfo) + { + var fileName = Path.GetFileName(att); + var attPath = Path.Combine(path, fileName); + File.Copy(att, attPath, true); + } + } + return true; + } + + /// + /// 目录不存在,则创建目录 + /// + /// + /// + private string createDirectory(string p) + { + if (!Directory.Exists(p)) + { + Directory.CreateDirectory(p); + } + + return p; + } + #endregion + + #region 从Xml中获取数据 + private bool init(int id, string masterFileTag) + { + try + { + var fileTag = masterFileTag.Replace("YSP_", ""); + var fileInfos = DbContextFactory.GetYLDbContext().supervise_report.Where(O => O.id == id || O.FileTag.Contains(fileTag)).ToList(); + if (fileInfos.Count == 0) + { + ErrorMsg = "未找到对应的报告"; + return false; + } + logger.Info($"找到符合Id={id}或FileTag包含{fileTag}的记录数: {fileInfos.Count}"); + var filePath = fileInfos.Where(O => O.id == id).Select(O => O.FilePath).FirstOrDefault(); + if (string.IsNullOrEmpty(filePath)) + { + ErrorMsg = "报告文件不存在"; + return false; + } + logger.Info($"查找对应解压文件: {filePath}"); + if (!getXmlFilePath(filePath, out var xmlPath)) + { + ErrorMsg = "报告文件解压失败"; + return false; + } + + convertToMasterAgrmtInfo(fileInfos, xmlPath); + convertToMasterSupAgrmtInfo(fileInfos, xmlPath); + convertToMasterAgrmtProductInfo(fileInfos, xmlPath); + convertToPerformanceGuaranteeAgrmtInfo(fileInfos, xmlPath); + convertToOptionConfirmationInfo(fileInfos, xmlPath); + convertToValuationInformationInfo(fileInfos, xmlPath); + convertToOptionConfirmationAttInfo(fileInfos, xmlPath); + convertToOptionTerminationInfo(fileInfos, xmlPath); + convertToSwapConfirmationInfo(fileInfos, xmlPath); + convertToSwapEquityPaymentInfo(fileInfos, xmlPath); + convertToSwapTerminationInfo(fileInfos, xmlPath); + convertToSwapConfirmationAttInfo(fileInfos, xmlPath); + convertToPeriodicReportSACInfo(fileInfos, xmlPath); + convertToPeriodicReportNAFMIIInfo(fileInfos, xmlPath); + convertToPeriodicReportISDAInfo(fileInfos, xmlPath); + getAttachment(xmlPath); + return true; + } + catch (Exception ex) + { + ErrorMsg = "解析报告失败,未知错误:" + ex.ToJson(); + return false; + } + } + + /// + /// 设置主协议信息 + /// + /// + /// + private void convertToMasterAgrmtInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_MasterAgrmt).ToList(); + xmlToObj(xmlPath, reportList, setMasterAgrmtInfo); + } + + /// + /// 设置补充协议信息 + /// + /// + /// + private void convertToMasterSupAgrmtInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_SupAgrmt).ToList(); + xmlToObj(xmlPath, reportList, setMasterSupAgrmtInfo); + } + + /// + /// 设置履约保障信息 + /// + /// + /// + private void convertToPerformanceGuaranteeAgrmtInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt).ToList(); + xmlToObj(xmlPath, reportList, setPerformanceGuaranteeAgrmtInfo); + } + + /// + /// 设置代签产品信息 + /// + /// + /// + private void convertToMasterAgrmtProductInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_MasterAgrmtProduct).ToList(); + xmlToObj(xmlPath, reportList, setMasterAgrmtProductInfo); + } + + /// + /// 设置期权交易信息 + /// + /// + /// + private void convertToOptionConfirmationInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_OptionConfirmation).ToList(); + xmlToObj(xmlPath, reportList, setOptionConfirmationInfo); + } + + /// + /// 设置每日估值信息 + /// + /// + /// + private void convertToValuationInformationInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_ValuationInformation).ToList(); + xmlToObj(xmlPath, reportList, setValuationInformationInfo); + } + + /// + /// 设置期权确认附件信息 + /// + /// + /// + private void convertToOptionConfirmationAttInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_OptionConfirmationAtt).ToList(); + xmlToObj(xmlPath, reportList, setOptionConfirmationAttInfo); + } + + /// + /// 设置期权存续期信息 + /// + /// + /// + private void convertToOptionTerminationInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_OptionTermination).ToList(); + xmlToObj(xmlPath, reportList, setOptionTerminationInfo); + } + + /// + /// 设置互换确认书信息 + /// + /// + /// + private void convertToSwapConfirmationInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_SwapConfirmation).ToList(); + xmlToObj(xmlPath, reportList, setSwapConfirmationInfo); + } + + /// + /// 设置互换权益端支付信息 + /// + /// + /// + private void convertToSwapEquityPaymentInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_SwapEquityPayment).ToList(); + xmlToObj(xmlPath, reportList, setSwapEquityPaymentInfo); + } + + /// + /// 设置互换存续期信息 + /// + /// + /// + private void convertToSwapTerminationInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_SwapDurationManagement).ToList(); + xmlToObj(xmlPath, reportList, setSwapTerminationInfo); + } + + /// + /// 设置互换确认书附件信息 + /// + /// + /// + private void convertToSwapConfirmationAttInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_ConfirmationAtt).ToList(); + xmlToObj(xmlPath, reportList, setSwapConfirmationAttInfo); + } + + /// + /// 设置SAC月报信息 + /// + /// + /// + private void convertToPeriodicReportSACInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_PeriodicReportSAC).ToList(); + xmlToObj(xmlPath, reportList, setPeriodicReportSACInfo); + } + + /// + /// 设置NAFMII月报信息 + /// + /// + /// + private void convertToPeriodicReportNAFMIIInfo(List fileInfos, string xmlPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII).ToList(); + xmlToObj(xmlPath, reportList, setPeriodicReportNAFMIIInfo); + } + + /// + /// 设置ISDA月报信息 + /// + /// + /// + private void convertToPeriodicReportISDAInfo(List fileInfos, string tempPath) + { + var reportList = fileInfos.Where(O => O.ReportType == DBModels.Enums.SuperviseReportTypeEnum.SAC_PeriodicReportISDA).ToList(); + xmlToObj(tempPath, reportList, setPeriodicReportISDAInfo); + } + + private void getAttachment(string tempPath) + { + if (_reportInfoList.Count == 0) + { + return; + } + var filePath = Path.Combine(tempPath, "ATTACHMENT"); + if (!Directory.Exists(filePath)) + { + return; + } + var files = Directory.GetFiles(filePath).ToList(); + _reportInfoList[0].Annex = _reportInfoList[0].Annex == null ? new List() : _reportInfoList[0].Annex; + _reportInfoList[0].Annex.AddRange(files); + logger.Info($"处理附件: {filePath}"); + + } + + /// + /// 转换Xml为对象 + /// + /// + /// + /// + private void xmlToObj(string tempPath, List reportList, Action action) + { + foreach (var item in reportList) + { + var xmlPath = Path.Combine(tempPath, $"{item.FileTag}.xml"); + logger.Info($"准备读取报告文件: {xmlPath}"); + var xml = File.ReadAllText(xmlPath); + logger.Info($"准备解析报告文件: {xmlPath}"); + var rootObj = XmlHelper.Deserialize(xml); + action?.Invoke(rootObj); + logger.Info($"解析成功"); + _reportInfoList.Add(rootObj); + } + } + + /// + /// 获取Xml文件路径 + /// + /// + /// + /// + /// + private bool getXmlFilePath(string filePath, out string xmlPath) + { + var zipPath = MapPath(filePath) ?? ""; + if (!File.Exists(zipPath)) + { + ErrorMsg = "文件不存在"; + xmlPath = ""; + return false; + } + + var rootPath = Path.Combine(Path.GetDirectoryName(zipPath), "Temp"); + xmlPath = Path.Combine(rootPath, Path.GetFileNameWithoutExtension(zipPath)); + if (!Directory.Exists(xmlPath)) + { + logger.Info($"文件不存在,准备解压: {xmlPath}"); + Directory.CreateDirectory(xmlPath); + ZipHelper.unZipFile(zipPath, rootPath, out var msg); + if (msg.StartsWith("解压失败")) + { + Directory.Delete(xmlPath, true); + ErrorMsg = $"解压失败:{msg}"; + return false; + } + } + return true; + } + #endregion + + #region 设置附加信息 + /// + /// 设置主协议信息 + /// + /// + private void setMasterAgrmtInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.MasterAgrmt; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var operationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var reportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = operationType; + item.ReportDate = reportDate; + if (item.CounterpartyInformationTuple != null) + { + foreach (var counterpartyInfo in item.CounterpartyInformationTuple) + { + counterpartyInfo.MasterAgrmtNo = item.MasterAgrmtNo; + counterpartyInfo.ReportDate = item.ReportDate; + counterpartyInfo.ExceID = item.ExceID; + } + } + } + } + + /// + /// 设置补充协议信息 + /// + /// + private void setMasterSupAgrmtInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.SupAgrmt; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var operationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var reportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = operationType; + item.ReportDate = reportDate; + if (item.SupAgrmtAttTuple?.Count > 0) + { + var attList = item.SupAgrmtAttTuple!.Select(O => O.SupAgrmtAtt).ToList(); + item.SupAgrmtAtt = string.Join(",", attList); + } + } + } + + /// + /// 设置履约保障信息 + /// + /// + private void setPerformanceGuaranteeAgrmtInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.PerformanceGuaranteeAgrmt; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var operationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var reportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = operationType; + item.ReportDate = reportDate; + } + } + + /// + /// 设置代签产品信息 + /// + /// + private void setMasterAgrmtProductInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.MasterAgrmtProduct; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + } + } + + /// + /// 设置期权交易信息 + /// + /// + private void setOptionConfirmationInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.OptionConfirmation; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + if (item.UndrlygAssetTuple != null) + { + foreach (var undrlyAsset in item.UndrlygAssetTuple) + { + undrlyAsset.UndrlygAssetNo = item.UndrlygAssetNo; + undrlyAsset.ConfirmationNo = item.ConfirmationNo; + undrlyAsset.ReportDate = item.ReportDate; + undrlyAsset.ExceID = item.ExceID; + } + } + if (item.PerformanceCollTuple != null) + { + foreach (var performanceGuarantee in item.PerformanceCollTuple) + { + performanceGuarantee.PerformanceGuaranteeType = item.PerformanceGuaranteeType; + performanceGuarantee.ConfirmationNo = item.ConfirmationNo; + performanceGuarantee.ReportDate = item.ReportDate; + performanceGuarantee.ExceID = item.ExceID; + } + } + } + } + + /// + /// 设置每日估值信息 + /// + /// + private void setValuationInformationInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.ValuationInformation; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + } + } + + /// + /// 设置期权确认附件信息 + /// + /// + private void setOptionConfirmationAttInfo(ReportRootModel model) + { + if (model.Body.ConfirmationAtt == null) + { + return; + } + var reportObj = model.Body.ConfirmationAtt.Where(O => O.ConfirmationFilesTuple.Any(B => !string.IsNullOrEmpty(B.ConfirmationAtt))).ToList(); + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + var attList = item.ConfirmationFilesTuple.Select(O => O.ConfirmationAtt); + item.OperationType = OperationType; + item.ReportDate = ReportDate; + item.ConfirmationAtt = string.Join(",", attList); + } + } + + /// + /// 设置期权存续期信息 + /// + /// + private void setOptionTerminationInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.OptionTermination; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + } + } + + /// + /// 设置互换确认书信息 + /// + /// + private void setSwapConfirmationInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.SwapConfirmation; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + + if (item.CostPaymentTuple != null) + { + foreach (var detail in item.CostPaymentTuple) + { + detail.ConfirmationNo = item.ConfirmationNo; + detail.ReportDate = item.ReportDate; + detail.ExceID = item.ExceID; + } + } + if (item.PerformanceCollTuple != null) + { + foreach (var performance in item.PerformanceCollTuple) + { + performance.ConfirmationNo = item.ConfirmationNo; + performance.ReportDate = item.ReportDate; + performance.ExceID = item.ExceID; + } + } + } + } + + /// + /// 设置互换权益端支付信息 + /// + /// + private void setSwapEquityPaymentInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.SwapEquityPayment; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + if (item.SwapEquityPaymentTuple != null) + { + foreach (var equityPayment in item.SwapEquityPaymentTuple) + { + equityPayment.ConfirmationNo = item.ConfirmationNo; + equityPayment.ReportDate = item.ReportDate; + equityPayment.ExceID = item.ExceID; + + } + } + } + } + + /// + /// 设置互换存续期信息 + /// + /// + private void setSwapTerminationInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.SwapDurationManagement; + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + item.OperationType = OperationType; + item.ReportDate = ReportDate; + item.SwapType = item.DurationOperationType == SwapOperationTypeMap["调仓"] ? SwapTypeMap["多空组合"] : SwapTypeMap["其他"]; + + if (item.CurrentPositionDetails != null) + { + foreach (var detail in item.CurrentPositionDetails) + { + detail.ConfirmationNo = item.ConfirmationNo; + detail.ReportDate = item.ReportDate; + detail.ExceID = item.ExceID; + } + } + } + } + + /// + /// 设置互换确认书附件信息 + /// + /// + private void setSwapConfirmationAttInfo(ReportRootModel model) + { + if (model.Body.ConfirmationAtt == null) + { + return; + } + var reportObj = model.Body.ConfirmationAtt.Where(O => O.ConfirmationFilesTuple.Any(B => !string.IsNullOrEmpty(B.ConfirmationFiles))).ToList(); + if (reportObj == null || reportObj.Count == 0) + { + return; + } + var OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + var ReportDate = DateTime.Parse(model.Header.SendDate); + foreach (var item in reportObj) + { + var attList = item.ConfirmationFilesTuple.Select(O => O.ConfirmationFiles); + item.OperationType = OperationType; + item.ReportDate = ReportDate; + item.ConfirmationFiles = string.Join(",", attList); + } + } + + /// + /// 设置SAC月报信息 + /// + /// + private void setPeriodicReportSACInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.PeriodicReportSAC; + if (reportObj == null) + { + return; + } + reportObj.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + reportObj.ReportDate = DateTime.Parse(model.Header.SendDate); + if (reportObj.IncreaseBusinessDetailsThisMonthTuple != null) + { + index = 0; + foreach (var item in reportObj.IncreaseBusinessDetailsThisMonthTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + if (reportObj.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) + { + index = 0; + foreach (var item in reportObj.InventoryBusinessDetailsAtTheEndOfThisMonthTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + if (reportObj.TargetCaseAndHedgeTuple != null) + { + index = 0; + foreach (var item in reportObj.TargetCaseAndHedgeTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + } + + /// + /// 设置NAFMII月报信息 + /// + /// + private void setPeriodicReportNAFMIIInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.PeriodicReportNAFMII; + if (reportObj == null) + { + return; + } + reportObj.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + reportObj.ReportDate = DateTime.Parse(model.Header.SendDate); + if (reportObj.InterestRateSwapDetails != null) + { + index = 0; + foreach (var item in reportObj.InterestRateSwapDetails) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + if (reportObj.InterestRateOptionDetails != null) + { + index = 0; + foreach (var item in reportObj.InterestRateOptionDetails) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + if (reportObj.ScheduleOfOtherTransactions != null) + { + index = 0; + foreach (var item in reportObj.ScheduleOfOtherTransactions) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + } + + /// + /// 设置ISDA月报信息 + /// + /// + private void setPeriodicReportISDAInfo(ReportRootModel model) + { + var index = 0; + var reportObj = model.Body.PeriodicReportISDA; + if (reportObj == null) + { + return; + } + reportObj.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType); + reportObj.ReportDate = DateTime.Parse(model.Header.SendDate); + if (reportObj.IncreaseBusinessDetailsThisMonthTuple != null) + { + index = 0; + foreach (var item in reportObj.IncreaseBusinessDetailsThisMonthTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + + if (reportObj.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) + { + index = 0; + foreach (var item in reportObj.InventoryBusinessDetailsAtTheEndOfThisMonthTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + + if (reportObj.TargetCaseAndHedgeTuple != null) + { + index = 0; + foreach (var item in reportObj.TargetCaseAndHedgeTuple) + { + item.ReportDate = reportObj.ReportDate; + item.ExceID = reportObj.ExceID; + item.Index = $"{++index}"; + } + } + } + #endregion + } +} + +/*暂存所有报送相关表的sql +CREATE TABLE `A1001_MasterAgrmt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`MasterAgrmtID` varchar(32) NULL COMMENT '主协议编号', +`MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`SigningDate` varchar(10) NOT NULL COMMENT '签订时间', +`MasterAgrmtVer` varchar(10) NOT NULL COMMENT '主协议版本', +`FillParty` varchar(2) NOT NULL COMMENT '填报方角色', +`NameOfCounterparty` varchar(200) NOT NULL COMMENT '交易对手方名称(全称)', +`CODS` varchar(18) NULL COMMENT '统一社会信用代码', +`CounterpartyCode` varchar(20) NULL COMMENT '交易对手编码', +`LEI` varchar(20) NULL COMMENT 'LEI码', +`ProCounterparty` varchar(200) NOT NULL COMMENT '交易对手类别', +`CounterpartyType` varchar(20) NOT NULL COMMENT '交易对手方类型', +`NFICode` varchar(20) NULL COMMENT '非金融机构行业代码', +`CounterpartyRegdCptl` varchar(37) NULL COMMENT '交易对手方注册资本(万元)', +`MasterAgrmtRemark` text NULL COMMENT '主协议备注', +`MasterAgrmtAtt` varchar(255) NOT NULL COMMENT '主协议附件', +`CounterpartyIdentity` varchar(2) NOT NULL COMMENT '交易对手方身份', + PRIMARY KEY (`id`) +) COMMENT = '主协议'; +CREATE TABLE `A1001_CounterpartyInfomation` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', +`MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', + `Name` varchar(200) NOT NULL COMMENT '填报方业务代表姓名', +`Title` varchar(200) NULL COMMENT '职务', +`Telephone` varchar(200) NULL COMMENT '电话', +`Mobile` varchar(11) NULL COMMENT '手机', +`Email` varchar(200) NULL COMMENT '邮箱', + + PRIMARY KEY (`id`) +) COMMENT = '填报方业务代表明细'; +CREATE TABLE `A1003_SupAgrmt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`SupAgrmtID` varchar(32) NULL COMMENT '补充议编号', +`SupAgrmtNo` varchar(100) NOT NULL COMMENT '补充协议编号(双方约定)', +`SupAgrmtType` varchar(2) NOT NULL COMMENT '补充协议类型', +`SigningDate` varchar(10) NOT NULL COMMENT '签署时间', +`SupAgrmtRemark` text NULL COMMENT '补充协议备注', +`SupAgrmtAtt` text NULL COMMENT '补充协议附件', + + PRIMARY KEY (`id`) +) COMMENT = '补充协议'; +CREATE TABLE `A1002_MasterAgrmtProduct` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`ProductNo` varchar(32) NULL COMMENT '代签产品编号', +`ClientType` varchar(255) NULL COMMENT '客户类型', +`ProductName` varchar(100) NULL COMMENT '产品名称', +`CounterpartyCodeProducts` varchar(20) NULL COMMENT '交易对手码(产品)', +`ManagerName` varchar(100) NULL COMMENT '产品投资经理姓名', +`InvestmentManagerContactNumber` varchar(20) NULL COMMENT '投资经理联系电话', +`TrusteeAgency` varchar(200) NULL COMMENT '托管机构(如有)', +`TheDateTable` varchar(10) NULL COMMENT '入表日期', +`SuchProducts` varchar(255) NULL COMMENT '代签产品附件', + + PRIMARY KEY (`id`) +) COMMENT = '主协议关联产品'; +CREATE TABLE `A1008_PerformanceGuaranteeAgrmt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`SupAgrmtNo` varchar(100) NOT NULL COMMENT '补充协议编号(双方约定)', +`PerformanceGuaranteeAgrmtID` varchar(32) NULL COMMENT '履约担保协议编号', +`PerformanceGuaranteeAgrmt` varchar(100) NOT NULL COMMENT '履约担保协议(附件)', +`SigningDate` varchar(10) NOT NULL COMMENT '签署时间', + + PRIMARY KEY (`id`) +) COMMENT = '履约保证书'; +CREATE TABLE `A1004_OptionConfirmation` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`SupAgrmtNo` varchar(100) NOT NULL COMMENT '补充协议编号(双方约定)', +`OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`ConfirmationID` varchar(32) NULL COMMENT '交易确认书编号', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`ConfirmationType` varchar(2) NOT NULL COMMENT '交易确认书类型', +`FillParty` varchar(2) NOT NULL COMMENT '填报方角色', +`OptionSeller` varchar(2) NOT NULL COMMENT '期权卖方', +`OptionDirection` varchar(2) NOT NULL COMMENT '期权方向', +`OptionStructureType` varchar(2) NOT NULL COMMENT '期权结构类型', +`OptionStructure` varchar(2000) NULL COMMENT '期权结构类型', +`ExerciseApproach` varchar(2) NOT NULL COMMENT '行权方式', +`StartDate` varchar(10) NOT NULL COMMENT '起始日', +`DueDate` varchar(10) NOT NULL COMMENT '到期日', +`SettlementDate` varchar(10) NULL COMMENT '结算日', +`OptionPremium` varchar(6) NOT NULL COMMENT '期权费(非年化)(%)', +`AnnualizedDays` varchar(3) NOT NULL COMMENT '年化天数', +`PricingVolatility` varchar(6) NOT NULL COMMENT '定价波动率(%)', +`RiskFreeInterestRates` varchar(6) NOT NULL COMMENT '无风险利率(%)', +`Currency` varchar(2) NOT NULL COMMENT '结算货币', +`NotinalPrincipleAmt` varchar(37) NOT NULL COMMENT '名义本金(元)', +`ClearingAgency` varchar(2) NOT NULL COMMENT '清算机构', +`TradingPlace` varchar(2) NOT NULL COMMENT '交易场所', +`TradingPlaceOther` varchar(200) NULL COMMENT '交易场所(其他)', +`ConfirmationRemark` text NULL COMMENT '基本信息备注', +`UndrlygAssetType` varchar(2) NOT NULL COMMENT '标的类型', +`UndrlygAssetNo` varchar(2) NOT NULL COMMENT '标的个数', +`ProfitCalculationInfo` text NOT NULL COMMENT '期权收益计算说明', +`ProfitRemark` text NULL COMMENT '备注/收益备注', +`PerformanceGuaranteeType` varchar(2) NOT NULL COMMENT '履约担保类型', +`PerformanceCollProvider` varchar(2) NULL COMMENT '履约担保品提供方', +`PartyUseColl` varchar(6) NULL COMMENT '担保品收取方是否可使用担保品', +`CollInstruction` text NULL COMMENT '担保品使用说明', +`CalculateCollInterest` varchar(6) NULL COMMENT '是否计算担保品价值产生利息', +`PerformanceCollInitialRatio` varchar(6) NULL COMMENT '履约担保品初始比率(%)', +`PerformanceCollInitialRatioCash` varchar(6) NULL COMMENT '履约担保品初始比率(现金部分)(%)', +`PerformanceCollAddtlRatio` varchar(6) NULL COMMENT '履约担保品追保比率(%)', +`PerformanceCollOffsetRatio` varchar(6) NULL COMMENT '履约担保品平仓比率(%)', +`MaintainGuaranteeRatio` varchar(6) NULL COMMENT '维持担保比率(%)', +`PerformanceGuaranteeRemark` text NULL COMMENT '备注/履约担保备注', +`PerformanceGuaranteeAtt` text NULL COMMENT '履约担保附件', +`Remark` text NULL COMMENT '备注/其他信息备注', +`ValidNotinalPrincipleAmt` varchar(37) NOT NULL COMMENT '有效名义本金(元)', +`ComplianceOpinion` text NULL COMMENT '合规意见书', +`PtyAPdctName` varchar(100) NULL COMMENT '甲方代签产品名称', +`PytAPdctCode` varchar(20) NULL COMMENT '甲方交易对手码(产品)', +`PtyBPdctName` varchar(100) NULL COMMENT '乙方代签产品名称', +`PytBPdctCode` varchar(20) NULL COMMENT '乙方交易对手码(产品)', +`CrossBorderTransactions` varchar(6) NOT NULL COMMENT '是否为跨境交易', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', +`VanillaOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`VanillaStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`VanillaStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`VanillaStrikePriceCoefficientThree` varchar(6) NULL COMMENT '行权价格系数3(%)', +`VanillaStrikePriceCoefficientFour` varchar(6) NULL COMMENT '行权价格系数4(%)', +`VanillaEngagementRateOne` varchar(6) NULL COMMENT '参与率1(%)', +`VanillaEngagementRateTwo` varchar(6) NULL COMMENT '参与率2(%)', +`VanillaEngagementRateThree` varchar(6) NULL COMMENT '参与率3(%)', +`VanillaEngagementRateFour` varchar(6) NULL COMMENT '参与率4(%)', +`VanillaBackCoverYield` varchar(6) NULL COMMENT '封底收益率(非年化)(%)', +`VanillaCappingYield` varchar(6) NULL COMMENT '封顶收益率(非年化)(%)', +`VanillaBlank1` text NULL COMMENT '空白1', +`VanillaBlank2` text NULL COMMENT '空白2', +`DigitalOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`DigitalStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`DigitalStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`DigitalStrikePriceCoefficientThree` varchar(6) NULL COMMENT '行权价格系数3(%)', +`DigitalEngagementRateOne` varchar(6) NULL COMMENT '参与率1(%)', +`DigitalEngagementRateTwo` varchar(6) NULL COMMENT '参与率2(%)', +`DigitalEngagementRateThree` varchar(6) NULL COMMENT '参与率3(%)', +`DigitalYieldOneNonAnnualized` varchar(6) NULL COMMENT '收益率1(非年化)(%)', +`DigitalYieldTwoNonAnnualized` varchar(6) NULL COMMENT '收益率2(非年化)(%)', +`DigitalYieldThreeNonAnnualized` varchar(6) NULL COMMENT '收益率3(非年化)(%)', +`DigitalYieldFourNonAnnualized` varchar(6) NULL COMMENT '收益率4(非年化)(%)', +`DigitalBlank1` text NULL COMMENT '空白1', +`DigitalBlank2` text NULL COMMENT '空白2', +`BarrierOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`BarrierStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`BarrierStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`BarrierEngagementRateOne` varchar(6) NULL COMMENT '参与率1(%)', +`BarrierEngagementRateTwo` varchar(6) NULL COMMENT '参与率2(%)', +`BarrierKnockInPriceCoefficient` varchar(6) NULL COMMENT '敲入价格系数(%)', +`BarrierKnockOutPriceCoefficientOne` varchar(6) NULL COMMENT '敲出价格系数1(%)', +`BarrierKnockOutYieldOneNonAnnualized` varchar(6) NULL COMMENT '敲出收益率1(非年化)(%)', +`BarrierKnockOutPriceCoefficientTwo` varchar(6) NULL COMMENT '敲出价格系数2(%)', +`BarrierKnockOutYieldTwoNonAnnualized` varchar(6) NULL COMMENT '敲出收益率2(非年化)(%)', +`BarrierObservationType` varchar(2) NULL COMMENT '观察类型', +`BarrierBackCoverYield` varchar(6) NULL COMMENT '封底收益率(非年化)(%)', +`BarrierUnknockedYield` varchar(6) NULL COMMENT '未敲入收益率(非年化)(%)', +`BarrierBlank1` text NULL COMMENT '空白1', +`BarrierBlank2` text NULL COMMENT '空白2', +`AutoCallableOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`AutoCallableEngagementRate` varchar(6) NULL COMMENT '参与率(%)', +`AutoCallableStrikePriceCoefficient` varchar(6) NULL COMMENT '行权价格系数(%)', +`AutoCallableKnockOutPriceCoefficient` text NULL COMMENT '敲出价格系数(%)', +`AutoCallableKnockOutYieldAnnualized` text NULL COMMENT '敲出收益率(年化)(%)', +`AutoCallableKnockOutObservationDay` varchar(2048) NULL COMMENT '敲出观察日', +`AutoCallableKnockOutSettlementDay` varchar(2048) NULL COMMENT '敲出结算日', +`AutoCallableKnockInPriceCoefficient` text NULL COMMENT '敲入价格系数(%)', +`AutoCallableKnockInObservationDay` text NULL COMMENT '敲入观察日', +`AutoCallableDividendYieldAnnualized` varchar(6) NULL COMMENT '红利收益率(年化)(%)', +`AutoCallableMinimumYieldAnnualized` varchar(6) NULL COMMENT '最低收益率(年化)(%)', +`AutoCallableMinimumPrincipalProtectionRatio` varchar(6) NULL COMMENT '最低本金保障比例(%)', +`AutoCallableWhetherDiscountedWarehouseType` varchar(2) NULL COMMENT '是否为折价建仓型', +`AutoCallableWhetherRevenueEnhancedType` varchar(2) NULL COMMENT '是否为收益增强型', +`AutoCallableWhetherFixedCouponNote` varchar(2) NULL COMMENT '是否为FCN型', +`AutoCallableWhetherKnockInPriceCoefficientIsVariable` varchar(2) NULL COMMENT '敲入价格系数是否可变', +`AutoCallableWhetherKnockOutPriceCoefficientIsVariable` varchar(2) NULL COMMENT '敲出价格系数是否可变', +`AutoCallableWhetherKnockOutYieldIsVariable` varchar(2) NULL COMMENT '敲出收益率是否可变', +`AutoCallableWhetherDividendYieldIsVariable` varchar(2) NULL COMMENT '红利收益率是否可变', +`AutoCallableBlank1` text NULL COMMENT '空白1', +`AutoCallableBlank2` text NULL COMMENT '空白2', +`RangeAccrualOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`RangeAccrualStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`RangeAccrualStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`RangeAccrualStrikePriceCoefficientThree` varchar(6) NULL COMMENT '行权价格系数3(%)', +`RangeAccrualStrikePriceCoefficientFour` varchar(6) NULL COMMENT '行权价格系数4(%)', +`RangeAccrualEngagementRate` varchar(6) NULL COMMENT '参与率(%)', +`RangeAccrualOneNonAnnualized` varchar(6) NULL COMMENT '收益率1(非年化)(%)', +`RangeAccrualTwoNonAnnualized` varchar(6) NULL COMMENT '收益率2(非年化)(%)', +`RangeAccrualThreeNonAnnualized` varchar(6) NULL COMMENT '收益率3(非年化)(%)', +`RangeAccrualFourNonAnnualized` varchar(6) NULL COMMENT '收益率4(非年化)(%)', +`RangeAccrualBlank1` text NULL COMMENT '空白1', +`RangeAccrualBlank2` text NULL COMMENT '空白2', +`AirbagOptionStructureSubclass` varchar(2) NULL COMMENT '期权结构小类', +`AirbagStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`AirbagStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`AirbagStrikePriceCoefficientThree` varchar(6) NULL COMMENT '行权价格系数3(%)', +`AirbagStrikePriceCoefficientFour` varchar(6) NULL COMMENT '行权价格系数4(%)', +`AirbagEngagementRateOne` varchar(6) NULL COMMENT '参与率1(%)', +`AirbagEngagementRateTwo` varchar(6) NULL COMMENT '参与率2(%)', +`AirbagEngagementRateThree` varchar(6) NULL COMMENT '参与率3(%)', +`AirbagKnockInPriceCoefficient` varchar(6) NULL COMMENT '敲入价格系数(%)', +`AirbagBackCoverYield` varchar(6) NULL COMMENT '封底收益率(非年化)(%)', +`AirbagCappingYield` varchar(6) NULL COMMENT '封顶收益率(非年化)(%)', +`AirbagBlank1` text NULL COMMENT '空白1', +`AirbagBlank2` text NULL COMMENT '空白2', +`OthersOptionStructureSubclass` text NULL COMMENT '期权结构类型', +`OthersStrikePriceCoefficientOne` varchar(6) NULL COMMENT '行权价格系数1(%)', +`OthersStrikePriceCoefficientTwo` varchar(6) NULL COMMENT '行权价格系数2(%)', +`OthersStrikePriceCoefficientThree` varchar(6) NULL COMMENT '行权价格系数3(%)', +`OthersStrikePriceCoefficientFour` varchar(6) NULL COMMENT '行权价格系数4(%)', +`OthersEngagementRateOne` varchar(6) NULL COMMENT '参与率1(%)', +`OthersEngagementRateTwo` varchar(6) NULL COMMENT '参与率2(%)', +`OthersEngagementRateThree` varchar(6) NULL COMMENT '参与率3(%)', +`OthersEngagementRateFour` varchar(6) NULL COMMENT '参与率4(%)', +`OthersBarrierPricesCoefficientOne` varchar(6) NULL COMMENT '障碍价格系数1(%)', +`OthersBarrierPricesCoefficientTwo` varchar(6) NULL COMMENT '障碍价格系数2(%)', +`OthersBackCoverYield` varchar(6) NULL COMMENT '封底收益率(非年化)(%)', +`OthersCappingYield` varchar(6) NULL COMMENT '封顶收益率(非年化)(%)', +`OthersBlank1` text NULL COMMENT '空白1', +`OthersBlank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '期权交易确认书'; +CREATE TABLE `A1004_UndrlygAsset` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `UndrlygAssetDtldType` varchar(2) NOT NULL COMMENT '标的小类', +`UndrlygAssetName` varchar(200) NOT NULL COMMENT '标的名称', +`UndrlygAssetTradgPlc` varchar(200) NOT NULL COMMENT '标的交易场所', +`UndrlygAssetCode` varchar(200) NOT NULL COMMENT '标的编码', +`UndrlygAssetAmt` varchar(37) NOT NULL COMMENT '标的数量', +`ContractMultiplier` varchar(37) NOT NULL COMMENT '合约乘数', +`UndrlygAssetNo` varchar(2) NOT NULL COMMENT '标的个数', +`MultiOrderOptionType` varchar(2) NULL COMMENT '多标的期权类型', +`UndrlygAssetNotinalPrincipleAmtRMB` varchar(37) NOT NULL COMMENT '标的名义本金(元)', +`OpeningPrice` varchar(37) NOT NULL COMMENT '标的价格', +`UndrlygAssetType` varchar(2) NULL COMMENT '标的类型', +`OpeningPriceCurrency` varchar(2) NULL COMMENT '标的价格货币', +`ConfirmationNo` varchar(32) NULL COMMENT '关联交易确认书编号', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '标的详情'; +CREATE TABLE `A1004_PerformanceGuaranteeAtt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `PerformanceCollType` varchar(2) NULL COMMENT '履约担保品类型', +`PerformanceGuaranteeType` varchar(2) NOT NULL COMMENT '履约担保类型', +`PerformanceCollRange` varchar(2) NULL COMMENT '担保品担保范围', +`MultiConfirmationID` text NULL COMMENT '多笔担保交易确认书编号', +`ConfirmationNo` varchar(32) NULL COMMENT '关联交易确认书编号', +`Remarks` text NULL COMMENT '备注', + + PRIMARY KEY (`id`) +) COMMENT = '履约担保品详情'; +CREATE TABLE `A1018_ValuationInformation` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`ValuationDate` varchar(10) NOT NULL COMMENT '估值日期', +`Balance` varchar(37) NOT NULL COMMENT '存量名义本金(元)', +`MarginRatio` varchar(8) NULL COMMENT '保证金比例(%)', +`OptionValuation` varchar(37) NOT NULL COMMENT '期权估值', +`Delta` varchar(37) NOT NULL COMMENT 'Delta', +`Gamma` varchar(37) NOT NULL COMMENT 'Gamma', +`Vega` varchar(37) NOT NULL COMMENT 'Vega', +`Theta` varchar(37) NOT NULL COMMENT 'Theta', +`Rho` varchar(37) NOT NULL COMMENT 'Rho', +`RhoQ` varchar(37) NULL COMMENT 'RhoQ', +`DeltaCash` varchar(37) NOT NULL COMMENT 'DeltaCash', +`GammaCash` varchar(37) NOT NULL COMMENT 'GammaCash', +`VegaCash` varchar(37) NOT NULL COMMENT 'VegaCash', +`ThetaCash` varchar(37) NULL COMMENT 'ThetaCash', +`RhoCash` varchar(37) NULL COMMENT 'RhoCash', +`RhoQCash` varchar(37) NULL COMMENT 'RhoQCash', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '场外期权合约估值信息'; +CREATE TABLE `A1019_ConfirmationAtt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`ConfirmationAtt` varchar(1024) NULL COMMENT '期权交易确认书附件', +`ConfirmationFiles` varchar(1024) NULL COMMENT '互换交易确认书附件', + + PRIMARY KEY (`id`) +) COMMENT = '交易确认书附件'; +CREATE TABLE `A1007_OptionTermination` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`BizID` varchar(50) NULL COMMENT '业务编号', +`DurationEventNO` varchar(6) NOT NULL COMMENT '操作事件编号', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`DurationOperationType` varchar(2) NOT NULL COMMENT '存续期操作类型', +`ExpirationDate` varchar(10) NOT NULL COMMENT '操作发生日期', +`RenewalDate` varchar(10) NULL COMMENT '展期后到期日', +`DefaultingParty` varchar(2) NULL COMMENT '违约方', +`DefaultEvent` text NULL COMMENT '违约事件说明', +`TerminationAmount` varchar(37) NULL COMMENT '名义本金变动(元)', +`Balance` varchar(37) NOT NULL COMMENT '存量名义本金(元)', +`AmountPaidThisTime` varchar(37) NULL COMMENT '本次支付金额(元)', +`ClosedTransactionsRealRateReturn` varchar(8) NULL COMMENT '已了结交易实际收益率(%)', +`OptionDurationManagementAtt` text NULL COMMENT '存续期信息附件', +`BarrierEventStatus` varchar(2) NULL COMMENT '障碍事件状态', +`TradeId` varchar(37) NULL COMMENT '本次支付金额', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '期权存续期报告'; +CREATE TABLE `A1005_SwapConfirmation` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `PaymentMethod` varchar(2) NULL COMMENT '支付方式', +`OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`MasterAgrmtNo` varchar(100) NOT NULL COMMENT '主协议编号(双方约定)', +`SupAgrmtNo` varchar(100) NOT NULL COMMENT '补充协议编号(双方约定)', +`ConfirmationID` varchar(32) NULL COMMENT '交易确认书编号', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`ConfirmationType` varchar(2) NOT NULL COMMENT '交易确认书类型', +`FillParty` varchar(2) NOT NULL COMMENT '填报方角色', +`SwapType` varchar(2) NOT NULL COMMENT '收益互换交易类型', +`StartDate` varchar(10) NOT NULL COMMENT '起始日', +`DueDate` varchar(10) NOT NULL COMMENT '到期日', +`SettlementDate` varchar(10) NULL COMMENT '结算日', +`Currency` varchar(2) NOT NULL COMMENT '结算货币', +`NotinalPrincipleAmt` varchar(37) NOT NULL COMMENT '名义本金(元)', +`ClearingAgency` varchar(2) NOT NULL COMMENT '清算机构', +`TradingPlace` varchar(2) NOT NULL COMMENT '交易场所', +`TradingPlaceOther` varchar(200) NULL COMMENT '交易场所(其他)', +`UndrlygAssetType` varchar(2) NOT NULL COMMENT '标的类型', +`ConfirmationRemark` text NULL COMMENT '基本信息备注', +`PerformanceGuaranteeType` varchar(2) NOT NULL COMMENT '履约担保类型', +`PerformanceCollProvider` varchar(2) NULL COMMENT '履约担保品提供方', +`PartyUseColl` varchar(6) NULL COMMENT '担保品收取方是否可使用担保品', +`CollInstruction` text NULL COMMENT '担保品使用说明', +`CalculateCollInterest` varchar(6) NULL COMMENT '是否计算担保品价值产生利息', +`PerformanceCollInitialRatio` varchar(6) NOT NULL COMMENT '履约担保品初始比率(%)', +`PerformanceCollAddtlRatio` varchar(6) NULL COMMENT '履约担保品追保比率(%)', +`PerformanceCollOffsetRatio` varchar(6) NULL COMMENT '履约担保品平仓比率(%)', +`MaintainGuaranteeRatio` varchar(6) NOT NULL COMMENT '维持担保比率(%)', +`PerformanceGuaranteeAtt` text NULL COMMENT '履约担保附件', +`PerformanceGuaranteeRemark` text NULL COMMENT '履约担保备注', +`Remark` text NULL COMMENT '备注', +`ComplianceOpinion` text NULL COMMENT '合规意见书', +`PtyAUndrlygAssetNo` varchar(2) NOT NULL COMMENT '标的个数', +`PtyAPrOfitCalculationInfo` text NOT NULL COMMENT '收益计算说明', +`PtyAProfitRemark` text NULL COMMENT '收益备注', +`PtyAPdctName` varchar(200) NULL COMMENT '甲方代签产品名称', +`PytAPdctCode` varchar(20) NULL COMMENT '甲方交易对手码(产品)', +`PtyBPdctName` varchar(200) NULL COMMENT '乙方代签产品名称', +`PytBPdctCode` varchar(20) NULL COMMENT '乙方交易对手码(产品)', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '互换交易确认书'; +CREATE TABLE `A1005_SwapPerformanceGuaranteeAtt` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `PerformanceCollType` varchar(2) NULL COMMENT '履约担保品类型', +`PerformanceCollRange` varchar(2) NULL COMMENT '担保品担保范围', +`MultiConfirmationID` text NULL COMMENT '多笔担保交易确认书编号', +`Remarks` text NULL COMMENT '备注', +`ConfirmationNo` varchar(100) NULL COMMENT '交易确认书编号', + + PRIMARY KEY (`id`) +) COMMENT = '履约担保品详情'; +CREATE TABLE `A1005_PaymentMethod` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `PaymentMethod` varchar(2) NOT NULL COMMENT '支付方式', +`Payer` varchar(2) NOT NULL COMMENT '支付方', +`PaymentFreq` varchar(2) NOT NULL COMMENT '支付频率', +`FixedInterestRate` varchar(8) NULL COMMENT '固定利率(%)', +`FloatInterestRate` varchar(2) NULL COMMENT '浮动利率类型', +`ReferenceofFloatingInterestRate` varchar(200) NULL COMMENT '浮动利率参考标的', +`BasePoint` varchar(20) NULL COMMENT '浮动基点', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', +`ConfirmationNo` varchar(100) NULL COMMENT '交易确认书编号', + + PRIMARY KEY (`id`) +) COMMENT = '收益互换交易费用端支付'; +CREATE TABLE `A1016_SwapEquityPayment` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书(双方约定)', +`DurationEventNO` varchar(6) NULL COMMENT '操作事件编号', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '收益互换交易权益端支付'; +CREATE TABLE `A1016_SwapEquityPaymentTuple` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `PaymentMethod` varchar(2) NOT NULL COMMENT '支付方式', +`Payer` varchar(2) NOT NULL COMMENT '支付方', +`PaymentFreq` varchar(2) NOT NULL COMMENT '支付频率', +`OpenandClosingDate` varchar(10) NOT NULL COMMENT '标的开/平仓日期', +`UndrlygAssetDtldType` varchar(2) NOT NULL COMMENT '标的小类', +`UndrlygAssetCode` varchar(200) NOT NULL COMMENT '挂钩标的编码', +`UndrlygAssetName` varchar(200) NOT NULL COMMENT '标的名称', +`UndrlygAssetTradgPlc` varchar(200) NOT NULL COMMENT '标的交易场所', +`UndrlygAssetPrice` varchar(37) NOT NULL COMMENT '标的价格', +`UndrlygAssetPosition` varchar(2) NOT NULL COMMENT '开平仓', +`UndrlygAssetAmt` varchar(37) NOT NULL COMMENT '标的数量', +`ContractMultiplier` varchar(37) NOT NULL COMMENT '合约乘数', +`LNotinalPrincipleAmt` varchar(37) NULL COMMENT '多头名义本金(元)', +`SNotinalPrincipleAmt` varchar(37) NULL COMMENT '空头名义本金(元)', +`InterestRate` varchar(8) NULL COMMENT '利率(%)', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', +`ConfirmationNo` varchar(100) NULL COMMENT '交易确认书编号', + + PRIMARY KEY (`id`) +) COMMENT = '权益端支付'; +CREATE TABLE `A1006_SwapDurationManagement` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期',`PaymentMethod` varchar(2) NOT NULL COMMENT '支付方式', +`OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`SwapType` varchar(2) NOT NULL COMMENT '收益互换交易类型', +`DurationEventNO` varchar(6) NOT NULL COMMENT '操作事件编号', +`ConfirmationNo` varchar(100) NOT NULL COMMENT '交易确认书编号(双方约定)', +`DurationOperationType` varchar(2) NOT NULL COMMENT '存续期操作类型', +`DurationOperationDate` varchar(10) NOT NULL COMMENT '操作发生日期', +`RenewalDate` varchar(10) NULL COMMENT '展期后到期日', +`DefaultingParty` varchar(2) NULL COMMENT '违约方', +`DefaultEvent` text NULL COMMENT '违约事件说明', +`ChangeAmount` varchar(37) NULL COMMENT '名义本金变动(元)', +`Balance` varchar(37) NOT NULL COMMENT '存量名义本金(元)', +`AmountPaidThisTime` varchar(37) NULL COMMENT '本次支付金额(元)', +`MarginRatio` varchar(8) NOT NULL COMMENT '保证金比例(%)', +`SwapDurationManagementAtt` text NULL COMMENT '存续期信息附件', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', + + PRIMARY KEY (`id`) +) COMMENT = '收益互换交易存续期管理'; +CREATE TABLE `A1006_CurrentPositionDetail` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `UndrlygAssetCode` varchar(200) NOT NULL COMMENT '挂钩标的编码', +`UndrlygAssetDtldType` varchar(2) NOT NULL COMMENT '标的小类', +`UndrlygAssetName` varchar(200) NOT NULL COMMENT '标的名称', +`UndrlygAssetTradgPlc` varchar(200) NOT NULL COMMENT '标的交易场所', +`UndrlygAssetPrice` varchar(37) NOT NULL COMMENT '标的价格', +`InvestorPosition` varchar(2) NOT NULL COMMENT '客户持仓方向', +`UndrlygAssetAmt` varchar(37) NOT NULL COMMENT '标的数量', +`ContractMultiplier` varchar(37) NOT NULL COMMENT '合约乘数', +`NotinalPrincipleAmt` varchar(37) NOT NULL COMMENT '名义本金(元)', +`Blank1` text NULL COMMENT '空白1', +`Blank2` text NULL COMMENT '空白2', +`ConfirmationNo` varchar(100) NULL COMMENT '交易确认书编号', + + PRIMARY KEY (`id`) +) COMMENT = '合约持仓明细'; +CREATE TABLE `A1011_PeriodicReportSAC` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`BizID` varchar(50) NULL COMMENT '业务编号', +`Year` varchar(4) NOT NULL COMMENT '年份', +`Month` varchar(2) NOT NULL COMMENT '月份', +`MainAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增主协议(笔)', +`MainAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计主协议(笔)', +`MainAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '截至月末存续主协议数量(笔)', +`SupplementalAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增补充协议(笔)', +`SupplementalAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计补充协议(笔)', +`SupplementalAgreementValidedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '截至月末存续补充协议数量(笔)', +`PerformanceGuaranteeAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增履约担保协议(笔)', +`PerformanceGuaranteeAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计履约担保协议(笔)', +`PerformanceGuaranteeAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '截至月末存续履约担保协议数量(笔)', +`TransactionConfirmationAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增交易确认书(笔)', +`TransactionConfirmationBookAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计交易确认书(笔)', +`TransactionConfirmationValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '截至月末存续交易确认书数量', +`ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionBusinessCorrespondence` varchar(37) NOT NULL COMMENT '开展场外个股期权业务对应的自营权益类证券及衍生品规模(元)', +`NetCapitalAtEndOfTheMonth` varchar(37) NOT NULL COMMENT '本月末净资本(元)', +`ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionsBusinessAccountedForTheProportionOfTheCorrespondingNetCapital` varchar(37) NOT NULL COMMENT '开展场外个股期权业务对应的自营权益类证券及衍生品规模占净资本比例(%)', +`OTCOptionHasSignedByLegalPerson` varchar(20) NOT NULL COMMENT '场外期权已签约法人(家)', +`OTCOptionsHaveContractedProducts` varchar(20) NOT NULL COMMENT '场外期权已签约产品(家)', +`OTCOptionsForTheMonthOfTheNewAddLegalPerson` varchar(20) NOT NULL COMMENT '场外期权当月新增法人(家)', +`OTCOptionsForTheMonthOfTheNewAddProduct` varchar(20) NOT NULL COMMENT '场外期权当月新增产品(家)', +`OTCOptionsLegalPersonInDurationForThisMouth` varchar(20) NOT NULL COMMENT '场外期权当月末存续法人(家)', +`OTCOptionsProductsInDurationForThisMouth` varchar(20) NOT NULL COMMENT '场外期权当月末存续产品(家)', +`IncomeSwapHasSignedLegalPersonNumber` varchar(20) NOT NULL COMMENT '收益互换已签约法人(家)', +`IncomeSwapHasSignedProductNumber` varchar(20) NOT NULL COMMENT '收益互换已签约产品(家)', +`IncomeSwapForTheMonthOfTheNewAddLegalPerson` varchar(20) NOT NULL COMMENT '收益互换当月新增法人(家)', +`IncomeSwapForTheMonthOfTheNewAddProduct` varchar(20) NOT NULL COMMENT '收益互换当月新增产品(家)', +`IncomeSwapLegalPersonInDurationForThisMouth` varchar(20) NOT NULL COMMENT '收益互换当月末存续法人(家)', +`IncomeSwapProductsInDurationForThisMouth` varchar(20) NOT NULL COMMENT '收益互换当月末存续产品(家)', +`OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale` varchar(37) NOT NULL COMMENT '场外期权境内股指上月末存续规模(亿元)', +`OTCOptionsWithinIndividualStocksLateLastMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权境内个股上月末存续期规模(亿元)', +`OTCOptionsCommoditiesLastMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权大宗商品上月末存续期规模(亿元)', +`OTCOptionsOtherSubjectLastMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权其他标的上月末存续期规模(亿元)', +`RevenueExchangeDomesticStockIndexLastMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换境内股指上月末存续规模(亿元)', +`RevenueExchangeDomesticIndividualStocksLastMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换境内个股上月末存续规模(亿元)', +`RevenueExchangeCommoditiesLastMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换大宗商品上月末存续规模(亿元)', +`RevenueExchangeOtherSubjectLastMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换其他标的上月末存续规模(亿元)', +`TotalOfLastMonthDurationScale` varchar(37) NOT NULL COMMENT '上月末存续规模合计(亿元)', +`OTCOptionsWithinTheIndexThisMonthOfTheNewScale` varchar(37) NOT NULL COMMENT '场外期权境内股指本月新增规模(亿元)', +`OTCOptionsToAddScaleDomesticStocksInThisMonth` varchar(37) NOT NULL COMMENT '场外期权境内个股本月新增规模(亿元)', +`OTCOptionsCommoditiesTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '场外期权大宗商品本月新增规模(亿元)', +`OTCOptionsOtherSubjectTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '场外期权其他标的本月新增规模(亿元)', +`RevenueExchangeDomesticStockIndexTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '收益互换境内股指本月新增规模(亿元)', +`RevenueExchangeDomesticIndividualStocksTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '收益互换境内个股本月新增规模(亿元)', +`RevenueExchangeCommoditiesTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '收益互换大宗商品本月新增规模(亿元)', +`RevenueExchangeOtherSubjectTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '收益互换其他标的本月新增规模(亿元)', +`TotalOfTheNewSizeOfTheIncreaseInThisMonth` varchar(37) NOT NULL COMMENT '本月新增规模合计(亿元)', +`OTCOptionsTerminateScaleDomesticStockIndexThisMonth` varchar(37) NOT NULL COMMENT '场外期权境内股指本月终止规模(亿元)', +`OTCOptionsTerminateScaleDomesticStocksInThisMonth` varchar(37) NOT NULL COMMENT '场外期权境内个股本月终止规模(亿元)', +`OTCOptionsCommoditiesTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '场外期权大宗商品本月终止规模(亿元)', +`OTCOptionsOtherSubjectTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '场外期权其他标的本月终止规模(亿元)', +`RevenueExchangeDomesticStockIndexTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '收益互换境内股指本月终止规模(亿元)', +`RevenueExchangeDomesticIndividualStocksTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '收益互换境内个股本月终止规模(亿元)', +`RevenueExchangeCommoditiesTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '收益互换大宗商品本月终止规模(亿元)', +`RevenueExchangeOtherSubjectTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '收益互换其他标的本月终止规模(亿元)', +`TotalOfTerminationOfTheScaleOfThisMonth` varchar(37) NOT NULL COMMENT '本月终止规模合计(亿元)', +`OTCStockIndexOptionsWithinThisMonthOfTheExistenceOfScale` varchar(37) NOT NULL COMMENT '场外期权境内股指本月末存续规模(亿元)', +`OTCOptionsWithinIndividualStocksInThisMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权境内个股本月末存续规模(亿元)', +`OTCOptionsCommoditiesInThisMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权大宗商品本月末存续规模(亿元)', +`OTCOptionsOtherSubjectThisMonthDurationScale` varchar(37) NOT NULL COMMENT '场外期权其他标的本月末存续期规模(亿元)', +`RevenueExchangeDomesticStockIndexThisMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换境内股指本月末存续规模(亿元)', +`RevenueExchangeDomesticIndividualStocksThisMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换境内个股本月末存续规模(亿元)', +`RevenueExchangeCommoditiesThisMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换大宗商品本月末存续规模(亿元)', +`RevenueExchangeOtherSubjectThisMonthDurationScale` varchar(37) NOT NULL COMMENT '收益互换其他标的本月末存续规模(亿元)', +`TotalOfThisMonthDurationScale` varchar(37) NOT NULL COMMENT '本月末存续规模合计(亿元)', +`OTCOptionsStockIndexThisYearCumulativeScaleOfNewTerritory` varchar(37) NOT NULL COMMENT '场外期权境内股指本年累计新增规模(亿元)', +`OTCOptionsStockThisYearCumulativeScaleOfNewTerritory` varchar(37) NOT NULL COMMENT '场外期权境内个股本年累计新增规模(亿元)', +`OTCOptionsCommoditiesThisYearCumulativeScaleOfNewTerritory` varchar(37) NOT NULL COMMENT '场外期权大宗商品本年累计新增规模(亿元)', +`OTCOptionsOtherSubjectThisYearCumulativeScaleOfNewTerritory` varchar(37) NOT NULL COMMENT '场外期权其他标的本年累计新增规模(亿元)', +`IncomeSwapDomesticStockIndexHasAddedNewScaleInThisYear` varchar(37) NOT NULL COMMENT '收益互换境内股指本年累计新增规模(亿元)', +`IncomeSwapDomesticStockHasAddedNewScaleInThisYear` varchar(37) NOT NULL COMMENT '收益互换境内个股本年累计新增规模(亿元)', +`IncomeSwapCommoditiesIndexHasAddedNewScaleInThisYear` varchar(37) NOT NULL COMMENT '收益互换大宗商品本年累计新增规模(亿元)', +`IncomeSwapOtherSubjectIndexHasAddedNewScaleInThisYear` varchar(37) NOT NULL COMMENT '收益互换其他标的本年累计新增规模(亿元)', +`TotalNewScaleInThisYear` varchar(37) NOT NULL COMMENT '本年累计新增规模规模合计(亿元)', +`OTCOptionsStockIndexAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '场外期权境内股指上月末存续合约笔数(笔)', +`OTCOptionsStockAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '场外期权境内个股上月末存续合约笔数(笔)', +`OTCOptionsCommoditiesAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '场外期权大宗商品上月末存续合约笔数(笔)', +`OTCOptionsOtherSubjectAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '场外期权其他标的上月末存续合约笔数(笔)', +`IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '收益互换境内股指上月末存续合约笔数(笔)', +`IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '收益互换境内个股上月末存续合约笔数(笔)', +`IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '收益互换大宗商品上月末存续合约笔数(笔)', +`IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '收益互换其他标的上月末存续合约笔数(笔)', +`TotalNumberOfContractsAtTheEndOfLastMonth` varchar(20) NOT NULL COMMENT '上月末存续合约笔数规模合计(笔)', +`OTCOptionsStockIndexThisMonthNewDomesticContractNumber` varchar(20) NOT NULL COMMENT '场外期权境内股指本月新增合约笔数(笔)', +`OTCOptionsStockThisMonthNewDomesticContractNumber` varchar(20) NOT NULL COMMENT '场外期权境内个股本月新增合约笔数(笔)', +`OTCOptionsCommoditiesThisMonthNewDomesticContractNumber` varchar(20) NOT NULL COMMENT '场外期权大宗商品本月新增合约笔数(笔)', +`OTCOptionsOtherSubjectThisMonthNewDomesticContractNumber` varchar(20) NOT NULL COMMENT '场外期权其他标的本月新增合约笔数(笔)', +`IncomeSwapDomesticStockIndexNewContractInThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内股指本月新增合约笔数(笔)', +`IncomeSwapDomesticStockNewContractInThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内个股本月新增合约笔数(笔)', +`IncomeSwapCommoditiesNewContractInThisMonth` varchar(20) NOT NULL COMMENT '收益互换大宗商品本月新增合约笔数(笔)', +`IncomeSwapOtherSubjectNewContractInThisMonth` varchar(20) NOT NULL COMMENT '收益互换其他标的本月新增合约笔数(笔)', +`TotalNumberOfNewContractsInThisMonth` varchar(20) NOT NULL COMMENT '本月新增合约笔数规模合计(笔)', +`OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockIndexNumber` varchar(20) NOT NULL COMMENT '场外期权境内股指本月终止合约笔数(笔)', +`OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockNumber` varchar(20) NOT NULL COMMENT '场外期权境内个股本月终止合约笔数(笔)', +`OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheCommoditiesNumber` varchar(20) NOT NULL COMMENT '场外期权大宗商品本月终止合约笔数(笔)', +`OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheOtherSubjectNumber` varchar(20) NOT NULL COMMENT '场外期权其他标的本月终止合约笔数(笔)', +`IncomeSwapDomesticStockIndexTerminatesTheNumberOfContractsThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内股指本月终止合约笔数(笔)', +`IncomeSwapDomesticStockTerminatesTheNumberOfContractsThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内个股本月终止合约笔数(笔)', +`IncomeSwapCommoditiesTerminatesTheNumberOfContractsThisMonth` varchar(20) NOT NULL COMMENT '收益互换大宗商品本月终止合约笔数(笔)', +`IncomeSwapOtherSubjectTerminatesTheNumberOfContractsThisMonth` varchar(20) NOT NULL COMMENT '收益互换其他标的本月终止合约笔数(笔)', +`TotalNumberOfContractsTerminatedThisMonth` varchar(20) NOT NULL COMMENT '本月终止合约笔数规模合计(笔)', +`OTCDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '场外期权境内股指本月末存续合约笔数(笔)', +`OTCDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '场外期权境内个股本月末存续合约笔数(笔)', +`OTCCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '场外期权大宗商品本月末存续合约笔数(笔)', +`OTCOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '场外期权其他标的本月末存续合约笔数(笔)', +`IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内股指本月末存续合约笔数(笔)', +`IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '收益互换境内个股本月末存续合约笔数(笔)', +`IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '收益互换大宗商品本月末存续合约笔数(笔)', +`IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '收益互换其他标的本月末存续合约笔数(笔)', +`TotalNumberOfContractsAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末存续合约笔数规模合计(笔)', +`OTCOptionsStockIndexCumulativeDomesticNewContractNumberInThisYear` varchar(20) NOT NULL COMMENT '场外期权境内股指本年累计新增合约笔数(笔)', +`OTCOptionsStockCumulativeDomesticNewContractNumberInThisYear` varchar(20) NOT NULL COMMENT '场外期权境内个股本年累计新增合约笔数(笔)', +`OTCOptionsCommoditiesCumulativeDomesticNewContractNumberInThisYear` varchar(20) NOT NULL COMMENT '场外期权大宗商品本年累计新增合约笔数(笔)', +`OTCOptionsOtherSubjectCumulativeDomesticNewContractNumberInThisYear` varchar(20) NOT NULL COMMENT '场外期权其他标的本年累计新增合约笔数(笔)', +`IncomeSwapDomesticStockIndexCumulativeNumberOfNewContractsInThisYear` varchar(20) NOT NULL COMMENT '收益互换境内股指本年累计新增合约笔数(笔)', +`IncomeSwapDomesticStockCumulativeNumberOfNewContractsInThisYear` varchar(20) NOT NULL COMMENT '收益互换境内个股本年累计新增合约笔数(笔)', +`IncomeSwapCommoditiesCumulativeNumberOfNewContractsInThisYear` varchar(20) NOT NULL COMMENT '收益互换大宗商品本年累计新增合约笔数(笔)', +`IncomeSwapOtherSubjectCumulativeNumberOfNewContractsInThisYear` varchar(20) NOT NULL COMMENT '收益互换其他标的本年累计新增合约笔数(笔)', +`TotalNumberOfNewContractsInThisYear` varchar(20) NOT NULL COMMENT '本年累计新增合约笔数规模合计(笔)', +`TotalNominalPrincipalAmountOfSwapThisMonth` varchar(37) NOT NULL COMMENT '本月末互换存量名义本金总额(亿元)', +`TotalNominalPrincipalAmountOfSwapLastMonth` varchar(37) NOT NULL COMMENT '上月末互换存量名义本金总额(亿元)', +`TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth` varchar(37) NOT NULL COMMENT '本月末互换存量交易对应履约担保品价值(元)', +`TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth` varchar(37) NOT NULL COMMENT '上月末互换存量交易对应履约担保品价值(元)', +`SwapCashCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末互换现金担保物价值(元)', +`SwapCashCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末互换现金担保物价值(元)', +`SwapSecuritiesCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末互换证券担保物价值(元)', +`SwapSecuritiesCollateralValueLastMonthThisMonth` varchar(37) NOT NULL COMMENT '上月末互换证券担保物价值(元)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull` varchar(37) NOT NULL COMMENT '本月末互换业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull` varchar(37) NOT NULL COMMENT '上月末互换业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet` varchar(37) NOT NULL COMMENT '本月末互换业务整体履约担保比例(净额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet` varchar(37) NOT NULL COMMENT '上月末互换业务整体履约担保比例(净额)(%)', +`SwapNumberOfDefaultCustomersAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末互换本月违约客户数(家)', +`SwapNumberOfDefaultCustomersAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末互换本月违约客户数(家)', +`SwapDefaultTransactionNumberAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末互换本月违约交易数(笔)', +`SwapDefaultTransactionNumberAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末互换本月违约交易数(笔)', +`TotalSwapDefaultCustomerNumberInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末互换本年累计违约客户数(家)', +`TotalSwapDefaultCustomerNumberInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末互换本年累计违约客户数(家)', +`SwapNumberOfDefaultCustomersInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末互换本年累计违约交易数(笔)', +`SwapNumberOfDefaultCustomersInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末互换本年累计违约交易数(笔)', +`StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末存量交易对应履约担保品价值(元)', +`StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末存量交易对应履约担保品价值(元)', +`CashBalanceAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有现金余额(元)', +`CashBalanceAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有现金余额(元)', +`HoldStockMarketValueAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有股票市值(元)', +`HoldStockMarketValueAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有股票市值(元)', +`HoldMarketValueOfBondsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有债券市值(元)', +`HoldMarketValueOfBondsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有债券市值(元)', +`OwnedAssetManagementProductsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有证券公司资产管理产品(元)', +`OwnedAssetManagementProductsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有证券公司资产管理产品(元)', +`OwnedBankFinanceAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有银行理财(元)', +`OwnedBankFinanceAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有银行理财(元)', +`HoldTrustProductAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有信托产品(元)', +`HoldTrustProductAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有信托产品(元)', +`InsuranceProductsAreHeldAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有保险产品(元)', +`InsuranceProductsAreHeldAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有保险产品(元)', +`HoldOtherProductsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有其他产品(元)', +`HoldOtherProductsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有其他产品(元)', +`SettledSwapItemsAtThisMonth` varchar(20) NOT NULL COMMENT '互换本月了结笔数(笔)', +`SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth` varchar(37) NOT NULL COMMENT '互换本月了结交易涉及名义本金(亿元)', +`SwapIncomeCashFlow` varchar(37) NOT NULL COMMENT '互换收入现金流(万元)', +`SwapExpensesCashFlow` varchar(37) NOT NULL COMMENT '互换支出现金流(万元)', +`CashFlowCorrespondingToNetIncomeOnSwapMargin` varchar(37) NOT NULL COMMENT '互换使用保证金形成的净收益对应现金流(万元)', +`SwapHedgeCost` varchar(37) NOT NULL COMMENT '互换对冲成本(万元)', +`SettledOptionItemsAtThisMonth` varchar(20) NOT NULL COMMENT '期权本月了结笔数(笔)', +`SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth` varchar(37) NOT NULL COMMENT '期权本月了结交易涉及名义本金(亿元)', +`OptionPremiumIncome` varchar(37) NOT NULL COMMENT '期权权利金收入(万元)', +`OptionHedgeCost` varchar(37) NOT NULL COMMENT '期权对冲成本(万元)', +`BalanceOfSwapRealizedGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '互换合约端损益本月发生额(万元)', +`BalanceOfOptionRealizedGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '期权合约端损益本月发生额(万元)', +`BalanceOfSwapRealizedGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '互换合约端损益本年累计额(万元)', +`BalanceOfOptionRealizedGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '期权合约端损益本年累计额(万元)', +`BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth` varchar(37) NOT NULL COMMENT '互换对冲端损益本月发生额(万元)', +`BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth` varchar(37) NOT NULL COMMENT '期权对冲端损益本月发生额(万元)', +`BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear` varchar(37) NOT NULL COMMENT '互换对冲端损益本年累计额(万元)', +`BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear` varchar(37) NOT NULL COMMENT '期权对冲端损益本年累计额(万元)', +`BalanceOfSwapTotalGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '互换损益合计本月发生额(万元)', +`BalanceOfOptionTotalGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '期权损益合计本月发生额(万元)', +`BalanceOfSwapTotalGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '互换损益合计本年累计额(万元)', +`BalanceOfOptionTotalGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '期权损益合计本年累计额(万元)', +`MarginOfSubsistSwap` varchar(37) NOT NULL COMMENT '收益互换整体业务存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfSwap` varchar(37) NOT NULL COMMENT '收益互换整体业务对冲持仓市值(元)', +`LeverageRatiOfSwap` varchar(6) NOT NULL COMMENT '收益互换整体业务杠杆率(%)', +`MarginOfSubsistStockIndexSwap` varchar(37) NOT NULL COMMENT '收益互换股指标的存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfStockIndexSwap` varchar(37) NOT NULL COMMENT '收益互换股指标的对冲持仓市值(元)', +`LeverageRatioOfStockIndexSwap` varchar(6) NOT NULL COMMENT '收益互换股指标的杠杆率(%)', +`MarginOfSubsistStockSwap` varchar(37) NOT NULL COMMENT '收益互换个股标的存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfStockSwap` varchar(37) NOT NULL COMMENT '收益互换个股标的对冲持仓市值(元)', +`LeverageRatioOfStockSwap` varchar(6) NOT NULL COMMENT '收益互换个股标的杠杆率(%)', +`MarginandPremiumOfSubsistOption` varchar(37) NOT NULL COMMENT '场外期权整体业务存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfOption` varchar(37) NOT NULL COMMENT '场外期权整体业务对冲持仓市值(元)', +`LeverageRatioOfOption` varchar(6) NOT NULL COMMENT '场外期权整体业务杠杆率(%)', +`MarginandPremiumOfSubsistStockIndexOption` varchar(37) NOT NULL COMMENT '场外期权股指标的存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfStockIndexOption` varchar(37) NOT NULL COMMENT '场外期权股指标的对冲持仓市值(元)', +`LeverageRatioOfStockIndexOption` varchar(6) NOT NULL COMMENT '场外期权股指标的杠杆率(%)', +`MarginandPremiumOfSubsistStockOption` varchar(37) NOT NULL COMMENT '场外期权个股标的存量对应保证金(元)+期权费(元)', +`HedgedMarketValueOfStockOption` varchar(37) NOT NULL COMMENT '场外期权个股标的对冲持仓市值(元)', +`LeverageRatioOfStockOption` varchar(6) NOT NULL COMMENT '场外期权个股标的杠杆率(%)', +`TotalNominalPrincipalAmountOfOptionThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权存量名义本金总额(亿元)', +`TotalNominalPrincipalAmountOfOptionLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权存量名义本金总额(亿元)', +`TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权存量交易对应履约担保品价值(元)', +`TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权存量交易对应履约担保品价值(元)', +`OptionCashCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权现金担保物价值(元)', +`OptionCashCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权现金担保物价值(元)', +`OptionSecuritiesCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权证券担保物价值(元)', +`OptionSecuritiesCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权证券担保物价值(元)', +`ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthFull` varchar(37) NOT NULL COMMENT '本月末场外期权业务整体履约担保比例全额(%)', +`ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthFull` varchar(37) NOT NULL COMMENT '上月末场外期权业务整体履约担保比例全额(%)', +`ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthNet` varchar(37) NOT NULL COMMENT '本月末场外期权业务整体履约担保比例净额(%)', +`ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthNet` varchar(37) NOT NULL COMMENT '上月末场外期权业务整体履约担保比例净额(%)', +`OptionNumberOfDefaultCustomersAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本月违约客户数(家)', +`OptionNumberOfDefaultCustomersAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本月违约客户数(家)', +`OptionTransactionNumberAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本月违约交易数(笔)', +`OptionTransactionNumberAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本月违约交易数(笔)', +`TotalOptionDefaultCustomerNumberInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本年累计违约客户数(家)', +`TotalOptionDefaultCustomerNumberInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本年累计违约客户数(家)', +`OptionNumberOfDefaultCustomersInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本年累计违约交易数(笔)', +`OptionNumberOfDefaultCustomersInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本年累计违约交易数(笔)', + + PRIMARY KEY (`id`) +) COMMENT = 'SAC月报'; +CREATE TABLE `A1011_TargetCaseAndHedge` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`SumInvestmentTargetType` varchar(2) NULL COMMENT '标的分类', +`SumInvestmentTargetName` varchar(200) NULL COMMENT '标的名称/品种名称', +`UndrlygAssetCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`BuyingImpulseVolume` varchar(37) NULL COMMENT '买入对冲交易量(元)', +`SellingImpulseVolume` varchar(37) NULL COMMENT '卖出对冲交易量(元)', +`ImpulseVolume` varchar(37) NULL COMMENT '对冲交易量(元)(买入+卖出)', +`PositionAtTheEndOfThisMonth` varchar(37) NULL COMMENT '本月末持仓规模/合约价值(元)', +`TheNumberOfPositionsHeldAtTheEndOfThisMonth` varchar(37) NULL COMMENT '本月末持仓数量(股/手)', +`AveragePriceAtTheEndOfTheMonth` varchar(37) NULL COMMENT '本月末持仓平均价格(元)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '标的情况与对冲'; +CREATE TABLE `A1011_InventoryBusinessDetailsAtTheEndOfThisMonth` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手名称(全称)', +`NameOfCounterpartyProduct` varchar(100) NULL COMMENT '交易对手产品名称(如有)', +`TradeConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(双方约定)', +`TransactionConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(报告库编号)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`NotionalPrincipalAmountLNotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(或多头名义本金)(元)', +`SNotionalPrincipalAmount` varchar(37) NULL COMMENT '空头名义本金(元)(多空组合填写)', +`StartDay` varchar(10) NULL COMMENT '起始日(T日)', +`DueDate` varchar(10) NULL COMMENT '到期日', +`SumInvestmentTargetType` varchar(2) NULL COMMENT '标的类型', +`UndrlygAssetName` varchar(200) NULL COMMENT '标的名称', +`UndrlygAssetCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`OptionSumInvestmentTargetType` varchar(2) NULL COMMENT '期权标的小类(场外期权填写)', +`ExchangeSumInvestmentTargetType` varchar(2) NULL COMMENT '收益互换标的小类(收益互换填写)', +`OptionFee` varchar(6) NULL COMMENT '期权费(非年化)(%)', +`OptionType` varchar(2) NULL COMMENT '期权结构类型(期权填写)', +`MaitainMarginRation` varchar(37) NULL COMMENT '本月末维持保证金比例(%)', +`CorrelationCoefficient` varchar(20) NULL COMMENT '标的相关系数', +`LongPositionContractValue` varchar(37) NULL COMMENT '多头合约价值(元)', +`ShortPositionContractValue` varchar(37) NULL COMMENT '空头合约价值(元)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '本月末存量业务明细'; +CREATE TABLE `A1011_IncreaseBusinessDetailsThisMonth` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手名称(全称)', +`CounterpartyProductName` varchar(100) NULL COMMENT '交易对手产品名称(如有)', +`TradeConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(双方约定)', +`TransactionConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(报告库编号)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`NotionalPrincipalAmountLNotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(或多头名义本金)(元)', +`SNotionalPrincipalAmount` varchar(37) NULL COMMENT '空头名义本金(元)(多空组合填写)', +`StartDate` varchar(10) NULL COMMENT '起始日(T日)', +`DueDate` varchar(10) NULL COMMENT '到期日', +`InvestmentTargetType` varchar(2) NULL COMMENT '标的类型', +`UndrlygAssetName` varchar(200) NULL COMMENT '标的名称', +`UndrlygAssetCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`OptionObjectSecondClass` varchar(2) NULL COMMENT '期权标的小类(场外期权填写)', +`ReturnSwapObjectSecondClass` varchar(2) NULL COMMENT '收益互换标的小类(收益互换填写)', +`NonAnnualOptionFee` varchar(6) NULL COMMENT '期权费(非年化)(%)', +`OptionType` varchar(2) NULL COMMENT '期权结构类型(期权填写)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '本月新增业务明细'; +CREATE TABLE `A1012_PeriodicReportNAFMII` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`BizID` varchar(50) NULL COMMENT '业务编号', +`Year` varchar(4) NOT NULL COMMENT '年份', +`Month` varchar(2) NOT NULL COMMENT '月份', +`MainAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计主协议(笔)', +`MainAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增主协议(笔)', +`MainAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计主协议(笔)', +`MainAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效主协议(笔)', +`SupplementalAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计补充协议(笔)', +`SupplementalAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增补充协议(笔)', +`SupplementalAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计补充协议(笔)', +`SupplementalAgreementValidedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效补充协议(笔)', +`PerformanceGuaranteeAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计履约担保协议(笔)', +`PerformanceGuaranteeAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增履约担保协议(笔)', +`PerformanceGuaranteeAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计履约担保协议(笔)', +`PerformanceGuaranteeAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效履约担保协议(笔)', +`TransactionConfirmationLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计交易确认书(笔)', +`TransactionConfirmationAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增交易确认书(笔)', +`TransactionConfirmationBookAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计交易确认书(笔)', +`TransactionConfirmationValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效交易确认书(笔)', +`NominalPrincipalInterestRateTradedAtTheBeginningOfThisMonth` varchar(37) NOT NULL COMMENT '本月初利率类存续交易名义本金(亿元)', +`NominalPrincipalRateIncreasesThisMonth` varchar(37) NOT NULL COMMENT '本月新增利率类交易名义本金(亿元)', +`NominalPrincipalRateIsSettledThisMonth` varchar(37) NOT NULL COMMENT '本月了结利率类交易名义本金(亿元)', +`NominalPrincipalRateRemainsTradedAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末利率类存续交易名义本金(亿元)', +`NominalPrincipalRateAsOfTheEndOfThisMonthToAddTransactions` varchar(37) NOT NULL COMMENT '截至本月末利率类年度新增交易名义本金(亿元)', +`ContractsInterestRateTradedAtTheBeginningOfThisMonth` varchar(20) NOT NULL COMMENT '本月初利率类存续交易合约笔数(笔)', +`NumberOfContractedInterestRatesThisMonthToAddTransactions` varchar(20) NOT NULL COMMENT '本月利率类新增交易合约笔数(笔)', +`AmountOfInterestInTheContractIsSettledThisMonth` varchar(20) NOT NULL COMMENT '合约笔数利率本月了结交易(笔)', +`ContractInterestRatesRemainTradedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末利率类存续交易合约笔数(笔)', +`ContractsInterestRateAsOfTheEndOfThisMonthAddNewTransactions` varchar(20) NOT NULL COMMENT '截至本月末利率类年度新增交易合约笔数(笔)', +`NominalPrincipalGoldTradedAtTheBeginningOfThisMonth` varchar(37) NOT NULL COMMENT '本月初黄金类存续交易名义本金(亿元)', +`NominalGoldThisMonthToAddTransactions` varchar(37) NOT NULL COMMENT '本月黄金类新增交易名义本金(亿元)', +`TheNominalGoldIsTradingThisMonth` varchar(37) NOT NULL COMMENT '本月了结黄金类交易名义本金(亿元)', +`NominalPrincipalGoldIsTradedAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末黄金类存续交易名义本金(亿元)', +`NominalPrincipalGoldAsOfTheEndOfThisYearTheNewTransaction` varchar(37) NOT NULL COMMENT '截至本月末黄金类年度新增交易名义本金(亿元)', +`TheNumberOfContractsForGoldIsTradedAtTheBeginningOfThisMonth` varchar(20) NOT NULL COMMENT '本月初黄金类存续交易合约笔数(笔)', +`TheNumberOfContractsGoldThisMonthToAddTransactions` varchar(20) NOT NULL COMMENT '本月黄金类新增交易合约笔数(笔)', +`TheNumberOfContractsIsGoldThisMonth` varchar(20) NOT NULL COMMENT '本月了结黄金类交易(笔)', +`TheNumberOfContractsIsGoldAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末黄金类存续交易合约笔数(笔)', +`TheNumberOfContractsForTheGoldAsOfTheEndOfThisYearTheNewTransaction` varchar(20) NOT NULL COMMENT '截至本月末年度黄金类新增交易合约笔数(笔)', +`NominalPrincipalForeignExchangeTradedAtTheBeginningOfThisMonth` varchar(37) NOT NULL COMMENT '本月初外汇类存续交易名义本金(亿元)', +`NominalPrincipalForeignExchangeThisMonthToAddTransactions` varchar(37) NOT NULL COMMENT '本月新增外汇类交易名义本金(亿元)', +`TheNominalPrincipalForeignExchangeSettledThisMonth` varchar(37) NOT NULL COMMENT '本月了结外汇类交易名义本金(亿元)', +`NominalPrincipalForeignExchangeTradedAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末存续外汇类交易名义本金(亿元)', +`NominalPrincipalForeignExchangeAsOfTheEndOfThisYearTheNewTransaction` varchar(37) NOT NULL COMMENT '截至本月末年度外汇类新增交易名义本金(亿元)', +`ContractsForeignExchangeIsTradedAtTheBeginningOfThisMonth` varchar(20) NOT NULL COMMENT '本月初外汇类存续交易合约笔数(笔)', +`ContractNumberForeignExchangeThisMonthNewTransaction` varchar(20) NOT NULL COMMENT '本月外汇类新增交易合约笔数(笔)', +`TheNumberOfContractsForForeignExchangeTransactionsThisMonth` varchar(20) NOT NULL COMMENT '本月外汇类了结交易合约笔数(笔)', +`ContractsForeignExchangeIsTradedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末外汇类存续交易合约笔数(笔)', +`NumberOfContractsForeignExchangeAsOfTheEndOfThisMonthTheNewTransaction` varchar(20) NOT NULL COMMENT '截至本月末外汇类年度新增交易合约笔数(笔)', +`TheNameOfThePrincipalOtherTransactionsHeldEarlierThisMonth` varchar(37) NOT NULL COMMENT '本月初其他类存续交易名义本金(亿元)', +`NominalPrincipalOtherNewTransactionsThisMonth` varchar(37) NOT NULL COMMENT '本月其他类新增交易名义本金(亿元)', +`TheNameOfThePrincipalOtherTransactionsThisMonth` varchar(37) NOT NULL COMMENT '本月其他类了结交易名义本金(亿元)', +`NominalPrincipalOtherTransactionsRemainAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末其他类存续交易名义本金(亿元)', +`NominalPrincipalOtherTransactionsUpToTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '截至本月末其他类年度新增交易名义本金(亿元)', +`TheNumberOfContractsIsTheBeginningOfThisMonth` varchar(20) NOT NULL COMMENT '本月初其他类存续交易合约笔数(笔)', +`ContractNumberOtherNewTransactionsThisMonth` varchar(20) NOT NULL COMMENT '本月其他类新增交易合约笔数(笔)', +`TheNumberOfContractsOtherTransactionsThisMonth` varchar(20) NOT NULL COMMENT '本月其他类了结交易合约笔数(笔)', +`ContractsOthersRemainTradedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末其他类存续交易合约笔数(笔)', +`NumberOfContractsOtherTransactionsAsOfTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '截至本月末其他类年度新增交易合约笔数(笔)', +`TheNominalPrincipalIsTradedAtTheBeginningOfThisMonth` varchar(37) NOT NULL COMMENT '本月初存续交易名义本金合计(亿元)', +`NominalPrincipalTotalNewTransactionsThisMonth` varchar(37) NOT NULL COMMENT '本月新增交易名义本金合计(亿元)', +`NominalPrincipalTotalSettledThisMonth` varchar(37) NOT NULL COMMENT '本月了结交易名义本金合计(亿元)', +`TheNominalPrincipalIsTradedAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末存续交易名义本金合计(亿元)', +`NominalPrincipalTotalNewTransactionAsOfTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '截至本月末年度新增交易名义本金合计(亿元)', +`TheTotalNumberOfContractsIsTradedAtTheBeginningOfThisMonth` varchar(20) NOT NULL COMMENT '本月初存续交易合约笔数合计(笔)', +`TheTotalNumberOfContractsIsAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增交易合约笔数合计(笔)', +`TheTotalNumberOfContractsIsSettledThisMonth` varchar(20) NOT NULL COMMENT '本月了结交易合约笔数合计(笔)', +`TheTotalNumberOfContractsIsTradedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末存续交易合约笔数合计(笔)', +`TheTotalNumberOfContractsAsOfTheEndOfThisYearAddTheNewTransaction` varchar(20) NOT NULL COMMENT '截至本月末年度新增交易合约笔数合计(笔)', + + PRIMARY KEY (`id`) +) COMMENT = 'NAFMII月报'; +CREATE TABLE `A1012_ScheduleOfOtherTransaction` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `TradingDate` varchar(10) NULL COMMENT '起始日', +`NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`FillInTheNameOfTheAgency` varchar(100) NULL COMMENT '填报机构代签产品名称', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手方名称', +`CounterpartyAllographProduct` varchar(100) NULL COMMENT '交易对手方代签产品名称', +`BusinessType` varchar(2) NULL COMMENT '交易类型', +`CounterpartyType` varchar(2) NULL COMMENT '交易对手方类型', +`CounterpartyIsProfessionalInstitutionsOrNot` varchar(2) NULL COMMENT '交易对手是否专业机构', +`NotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(元)', +`InvestmentTargetType` varchar(2) NULL COMMENT '标的类型', +`InvestmentTarget` varchar(100) NULL COMMENT '标的名称', +`StartDate` varchar(10) NULL COMMENT '合约起始日', +`ContractExpirationDate` varchar(10) NULL COMMENT '合约到期日', +`Index` text NULL COMMENT '序号', + + + PRIMARY KEY (`id`) +) COMMENT = '其他交易明细表'; +CREATE TABLE `A1012_InterestRateOptionDetail` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `TradingDate` varchar(10) NULL COMMENT '起始日', +`NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`FillInTheNameOfTheAgency` varchar(100) NULL COMMENT '填报机构代签产品名称', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手方名称(全称)', +`CounterpartyAllographProduct` varchar(100) NULL COMMENT '交易对手方代签产品名称', +`BusinessType` varchar(2) NULL COMMENT '期权卖方', +`OptionType` varchar(2) NULL COMMENT '期权类型', +`OptionPosition` varchar(2) NULL COMMENT '期权方向', +`CounterpartyType` varchar(2) NULL COMMENT '交易对手方类型', +`CounterpartyIsProfessionalInstitutionsOrNot` varchar(2) NULL COMMENT '交易对手是否专业机构', +`NotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(元)', +`ExcerciseInterestRate` varchar(8) NULL COMMENT '行权利率(%)', +`InvestmentTarget` varchar(2) NULL COMMENT '标的名称', +`DeliveryType` varchar(2) NULL COMMENT '交割方式', +`StartDate` varchar(10) NULL COMMENT '合约起始日', +`ContractExpirationDate` varchar(10) NULL COMMENT '合约到期日', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '利率期权明细'; +CREATE TABLE `A1012_InterestRateSwapDetail` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `TransactionDate` varchar(10) NULL COMMENT '交易日期', +`NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`FillInTheNameOfTheAgency` varchar(100) NULL COMMENT '填报机构代签产品名称', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手方名称(全称)', +`CounterpartyAllographProduct` varchar(100) NULL COMMENT '交易对手方代签产品名称', +`CounterpartyType` varchar(2) NULL COMMENT '交易对手方类型', +`CounterpartyIsProfessionalInstitutionsOrNot` varchar(2) NULL COMMENT '交易对手是否专业机构', +`FixedInterestPaymentParty` varchar(100) NULL COMMENT '固定利息支付方', +`FloatingInterestPaymentParty` varchar(100) NULL COMMENT '浮动利息支付方', +`NotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金金额', +`ContractPeriod` varchar(40) NULL COMMENT '合约期限', +`DalueDate` varchar(10) NULL COMMENT '起息日', +`DueDate` varchar(10) NULL COMMENT '到期日', +`FixedRate` varchar(8) NULL COMMENT '固定利率', +`FixedRatePaymentCycle` varchar(1000) NULL COMMENT '固定利率支付周期', +`FixedInterestRateBasis` varchar(1000) NULL COMMENT '固定利率计息基准', +`NameOfReferenceRate` varchar(1000) NULL COMMENT '参考利率名称', +`Spreads` varchar(1000) NULL COMMENT '利差', +`FloatingRatePaymentCycle` varchar(1000) NULL COMMENT '浮动利率支付周期', +`ResetTheFrequency` varchar(1000) NULL COMMENT '重置频率', +`FloatingInterestRateBasis` varchar(1000) NULL COMMENT '浮动利率计息基准', +`FirstInterestPaymentDay` varchar(10) NULL COMMENT '首次利息支付(互换)日', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '利率互换明细'; +CREATE TABLE `A1013_PeriodicReportISDA` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `OperationType` varchar(1) NOT NULL COMMENT '操作标识', +`BizID` varchar(50) NULL COMMENT '业务编号', +`Year` varchar(4) NOT NULL COMMENT '年份', +`Month` varchar(2) NOT NULL COMMENT '月份', +`MainAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计主协议(笔)', +`MainAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增主协议(笔)', +`MainAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计主协议(笔)', +`MainAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效主协议(笔)', +`SupplementalAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计补充协议(笔)', +`SupplementalAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增补充协议(笔)', +`SupplementalAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计补充协议(笔)', +`SupplementalAgreementValidedAtTheEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效补充协议(笔)', +`PerformanceGuaranteeAgreementLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计履约担保协议(笔)', +`PerformanceGuaranteeAgreementAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增履约担保协议(笔)', +`PerformanceGuaranteeAgreementAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计履约担保协议(笔)', +`PerformanceGuaranteeAgreementValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效履约担保协议(笔)', +`TransactionConfirmationLastMonthAccumulatedThisYear` varchar(20) NOT NULL COMMENT '上月末本年累计交易确认书(笔)', +`TransactionConfirmationAddedThisMonth` varchar(20) NOT NULL COMMENT '本月新增交易确认书(笔)', +`TransactionConfirmationBookAccumulatedThisYear` varchar(20) NOT NULL COMMENT '本年累计交易确认书(笔)', +`TransactionConfirmationValidedAtEndOfThisMonth` varchar(20) NOT NULL COMMENT '本月末有效交易确认书(笔)', +`SWAPNominalCapitalStockAtBeginning` varchar(36,4) NOT NULL COMMENT '收益互换期初存量名义本金(亿元)', +`SWAPIncreasedOriginalTransactionNominalCapitalAtThisMonth` varchar(36,4) NOT NULL COMMENT '收益互换本月新增初始交易名义本金(亿元)', +`SWAPNotionalPrincipalAmountAllowedToBeTerminatedAtThisMonth` varchar(36,4) NOT NULL COMMENT '收益互换本月终止交易名义本金(亿元)', +`SWAPNominalCapitalStockAtEnding` varchar(36,4) NOT NULL COMMENT '收益互换期末存量名义本金(亿元)', +`SwapCategoryNominalPrincipalThisYearCumulativeInitialTransaction` varchar(36,4) NOT NULL COMMENT '收益互换本年累计新增初始交易名义本金(亿元)', +`OptionOfNotionalPrincipalStockAtBeginning` varchar(36,4) NOT NULL COMMENT '场外期权期初存量名义本金(亿元)', +`OptionIncreasedOriginalTransactionNominalCapitalAtThisMonth` varchar(36,4) NOT NULL COMMENT '场外期权本月新增初始交易名义本金(亿元)', +`OptionNotionalPrincipalAmountAllowedToBeTerminatedAtThisMonth` varchar(36,4) NOT NULL COMMENT '场外期权本月终止交易名义本金(亿元)', +`OptionOfNotionalPrincipalStockAtEnding` varchar(36,4) NOT NULL COMMENT '场外期权期末存量名义本金(亿元)', +`NominalPrincipalOfOptionClassHasBeenAddedToInitialTransaction` varchar(36,4) NOT NULL COMMENT '场外期权本年累计新增初始交易名义本金(亿元)', +`StockOfSwapContractsAtBeginning` varchar(20) NOT NULL COMMENT '收益互换合约数量期初存量(笔)', +`NumberOfNewSwapInitialTradingContractsAtThisMonth` varchar(20) NOT NULL COMMENT '收益互换本月新增初始交易合约数量(笔)', +`NumberOfSwapContractsToTerminateAtThisMonth` varchar(20) NOT NULL COMMENT '收益互换本月终止交易合约数量(笔)', +`StockOfSwapContractsAtEnding` varchar(20) NOT NULL COMMENT '收益互换合约数量期末存量(笔)', +`NumberOfSwapContractsIncreasedByThisYear` varchar(20) NOT NULL COMMENT '收益互换本年累计新增初始交易合约数量(笔)', +`StockOfOptionContractsAtBeginning` varchar(20) NOT NULL COMMENT '场外期权合约数量期初存量(笔)', +`NumberOfNewOptionInitialTradingContractsAtThisMonth` varchar(20) NOT NULL COMMENT '场外期权本月新增初始交易合约数量(笔)', +`NumberOfOptionContractsToTerminateAtThisMonth` varchar(20) NOT NULL COMMENT '场外期权本月终止交易合约数量(笔)', +`StockOfOptionContractsAtEnding` varchar(20) NOT NULL COMMENT '场外期权合约数量期末存量(笔)', +`NumberOfOptionContractsHasIncreasedInitialTransaction` varchar(20) NOT NULL COMMENT '场外期权本年累计新增初始交易合约数量(笔)', +`SwapSignedWithTheCustomerThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换已签约客户(家)', +`NumberOfSwapTradingAccountsAtThisPeriodThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换当期参与交易的账户数量(个)', +`NumberOfSwapTradingClientStockThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换存量交易客户数量(家)', +`SwapSignedWithTheCustomerLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换已签约客户(家)', +`NumberOfSwapTradingAccountsLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换当期参与交易的账户数量(个)', +`NumberOfSwapTradingClientStockLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换存量交易客户数量(家)', +`OptionSignedWithTheCustomerThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权已签约客户(家)', +`NumberOfOptionTradingAccountsThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权当期参与交易的账户数量(个)', +`NumberOfOptionTradingClientStockThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权存量交易客户数量(家)', +`OptionSignedWithTheCustomerLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权已签约客户(家)', +`NumberOfOptionTradingAccountsLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权当期参与交易的账户数量(个)', +`NumberOfOptionTradingClientStockLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权存量交易客户数量(家)', +`SignedTotalCustomer` varchar(20) NOT NULL COMMENT '已签约客户合计(家)', +`TotalNumberOfTradingAccountsAtThisPeriod` varchar(20) NOT NULL COMMENT '当期参与交易的账户数量合计(个)', +`TotalNumberOfTradingClientAccounts` varchar(20) NOT NULL COMMENT '存量交易客户数量合计(家)', +`SignedTotalCustomerLastMonth` varchar(20) NOT NULL COMMENT '上月末已签约客户合计(家)', +`TotalNumberOfTradingAccountsAtThisPeriodLastMonth` varchar(20) NOT NULL COMMENT '上月末当期参与交易的账户数量合计(个)', +`TotalNumberOfTradingClientAccountsLastMonth` varchar(20) NOT NULL COMMENT '上月末存量交易客户数量合计(家)', +`TotalNominalPrincipalAmountOfSwapThisMonth` varchar(37) NOT NULL COMMENT '本月末收益互换存量名义本金总额(亿元)', +`TotalNominalPrincipalAmountOfSwapLastMonth` varchar(37) NOT NULL COMMENT '上月末收益互换存量名义本金总额(亿元)', +`TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth` varchar(37) NOT NULL COMMENT '本月末收益互换存量交易对应履约担保品价值(元)', +`TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth` varchar(37) NOT NULL COMMENT '上月末收益互换存量交易对应履约担保品价值(元)', +`SwapCashCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末收益互换现金担保物价值(元)', +`SwapCashCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末收益互换现金担保物价值(元)', +`SwapSecuritiesCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末收益互换证券担保物价值(元)', +`SwapSecuritiesCollateralValueLastMonthThisMonth` varchar(37) NOT NULL COMMENT '上月末收益互换证券担保物价值(元)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull` varchar(37) NOT NULL COMMENT '本月末收益互换业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull` varchar(37) NOT NULL COMMENT '上月末收益互换业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet` varchar(37) NOT NULL COMMENT '本月末收益互换业务整体履约担保比例(净额)(%)', +`ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet` varchar(37) NOT NULL COMMENT '上月末收益互换业务整体履约担保比例(净额)(%)', +`SwapNumberOfDefaultCustomersAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换本月违约客户数(家)', +`SwapNumberOfDefaultCustomersAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换本月违约客户数(家)', +`SwapDefaultTransactionNumberAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换本月违约交易数(笔)', +`SwapDefaultTransactionNumberAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换本月违约交易数(笔)', +`TotalSwapDefaultCustomerNumberInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换本年累计违约客户数(家)', +`TotalSwapDefaultCustomerNumberInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换本年累计违约客户数(家)', +`SwapNumberOfDefaultCustomersInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末收益互换本年累计违约交易数(笔)', +`SwapNumberOfDefaultCustomersInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末收益互换本年累计违约交易数(笔)', +`TotalNominalPrincipalAmountOfOTCOptionsThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权存量名义本金总额(亿元)', +`TotalNominalPrincipalAmountOfOTCOptionsLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权存量名义本金总额(亿元)', +`TheValueOfTheStockOTCOptionsCorrespondingPerformanceGuaranteeThisMonth` varchar(37) NOT NULL COMMENT '上月末场外期权存量名义本金总额(元)', +`TheValueOfTheStockOTCOptionsCorrespondingPerformanceGuaranteeLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权存量交易对应履约担保品价值(元)', +`OTCOptionsCashCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权现金担保物价值(元)', +`OTCOptionsCashCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权现金担保物价值(元)', +`OTCOptionsSecuritiesCollateralValueThisMonth` varchar(37) NOT NULL COMMENT '本月末场外期权证券担保物价值(元)', +`OTCOptionsSecuritiesCollateralValueLastMonth` varchar(37) NOT NULL COMMENT '上月末场外期权证券担保物价值(元)', +`ProportionOfTheOverallPerformanceOfTheOTCOptionsBusinessThisMonthFull` varchar(37) NOT NULL COMMENT '本月末场外期权业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheOTCOptionsBusinessLastMonthFull` varchar(37) NOT NULL COMMENT '上月末场外期权业务整体履约担保比例(全额)(%)', +`ProportionOfTheOverallPerformanceOfTheOTCOptionsBusinessThisMonthNet` varchar(37) NOT NULL COMMENT '本月末场外期权业务整体履约担保比例(净额)(%)', +`ProportionOfTheOverallPerformanceOfTheOTCOptionsBusinessLastMonthNet` varchar(37) NOT NULL COMMENT '上月末场外期权业务整体履约担保比例(净额)(%)', +`OTCOptionsNumberOfDefaultCustomersAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本月违约客户数(家)', +`OTCOptionsNumberOfDefaultCustomersAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本月违约客户数(家)', +`OTCOptionsTransactionNumberAtThisMonthThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本月违约交易数(家)', +`OTCOptionsTransactionNumberAtThisMonthLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本月违约交易数(家)', +`TotalOTCOptionsDefaultCustomerNumberInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本年累计违约客户数(家)', +`TotalOTCOptionsDefaultCustomerNumberInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本年累计违约客户数(家)', +`OTCOptionsNumberOfDefaultCustomersInThisYearThisMonth` varchar(20) NOT NULL COMMENT '本月末场外期权本年累计违约交易数(家)', +`OTCOptionsNumberOfDefaultCustomersInThisYearLastMonth` varchar(20) NOT NULL COMMENT '上月末场外期权本年累计违约交易数(家)', +`StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末存量交易对应履约担保品价值(元)', +`StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末存量交易对应履约担保品价值(元)', +`CashBalanceAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有现金余额(元)', +`CashBalanceAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有现金余额(元)', +`HoldStockMarketValueAtEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有股票市值(元)', +`HoldStockMarketValueAtEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有股票市值(元)', +`HoldMarketValueOfBondsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有债券市值(元)', +`HoldMarketValueOfBondsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有债券市值(元)', +`OwnedAssetManagementProductsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有证券公司资产管理产品(元)', +`OwnedAssetManagementProductsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有证券公司资产管理产品(元)', +`OwnedBankFinanceAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有银行理财(元)', +`OwnedBankFinanceAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有银行理财(元)', +`HoldTrustProductAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有信托产品(元)', +`HoldTrustProductAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有信托产品(元)', +`InsuranceProductsAreHeldAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有保险产品(元)', +`InsuranceProductsAreHeldAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有保险产品(元)', +`HoldOtherProductsAtTheEndOfThisMonth` varchar(37) NOT NULL COMMENT '本月末持有其他产品(元)', +`HoldOtherProductsAtTheEndOfLastMonth` varchar(37) NOT NULL COMMENT '上月末持有其他产品(元)', +`SettledSwapItemsAtThisMonth` varchar(20) NOT NULL COMMENT '互换本月了结笔数(笔)', +`SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth` varchar(37) NOT NULL COMMENT '互换本月了结交易涉及名义本金(亿元)', +`SwapIncomeCashFlow` varchar(37) NOT NULL COMMENT '互换收入现金流(万元)', +`SwapExpensesCashFlow` varchar(37) NOT NULL COMMENT '互换支出现金流(万元)', +`CashFlowCorrespondingToNetIncomeOnSwapMargin` varchar(37) NOT NULL COMMENT '互换使用保证金形成的净收益对应现金流(万元)', +`SwapHedgeCost` varchar(37) NOT NULL COMMENT '互换对冲成本(万元)', +`SettledOptionItemsAtThisMonth` varchar(20) NOT NULL COMMENT '期权本月了结笔数(笔)', +`SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth` varchar(37) NOT NULL COMMENT '期权本月了结交易涉及名义本金(亿元)', +`OptionPremiumIncome` varchar(37) NOT NULL COMMENT '期权权利金收入(万元)', +`OptionHedgeCost` varchar(37) NOT NULL COMMENT '期权对冲成本(万元)', +`BalanceOfSwapRealizedGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '互换合约端损益本月发生额(万元)', +`BalanceOfOptionRealizedGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '期权合约端损益本月发生额(万元)', +`BalanceOfSwapRealizedGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '互换合约端损益本年累计额(万元)', +`BalanceOfOptionRealizedGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '期权合约端损益本年累计额(万元)', +`BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth` varchar(37) NOT NULL COMMENT '互换对冲端损益本月发生额(万元)', +`BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth` varchar(37) NOT NULL COMMENT '期权对冲端损益本月发生额(万元)', +`BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear` varchar(37) NOT NULL COMMENT '互换对冲端损益本年累计额(万元)', +`BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear` varchar(37) NOT NULL COMMENT '期权对冲端损益本年累计额(万元)', +`BalanceOfSwapTotalGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '互换损益合计本月发生额(万元)', +`BalanceOfOptionTotalGainsAndLossesAtThisMonth` varchar(37) NOT NULL COMMENT '期权损益合计本月发生额(万元)', +`BalanceOfSwapTotalGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '互换损益合计本年累计额(万元)', +`BalanceOfOptionTotalGainsAndLossesAtThisYear` varchar(37) NOT NULL COMMENT '期权损益合计本年累计额(万元)', + + PRIMARY KEY (`id`) +) COMMENT = 'ISDA月报'; +CREATE TABLE `A1013_ISDATargetCaseAndHedge` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`InvestmentTargetType` varchar(2) NULL COMMENT '标的分类', +`InvestmentTarget` varchar(100) NULL COMMENT '标的名称(或品种名称)', +`UnderlyingCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`BuyingImpulseVolume` varchar(37) NULL COMMENT '买入对冲交易量(元)', +`SellingImpulseVolume` varchar(37) NULL COMMENT '卖出对冲交易量(元)', +`ImpulseVolume` varchar(37) NULL COMMENT '对冲交易量(元)(买入+卖出)', +`PositionAtTheEndOfThisMonth` varchar(37) NULL COMMENT '本月末持仓规模(或合约价值)(元)', +`TheNumberOfPositionsHeldAtTheEndOfThisMonth` varchar(37) NULL COMMENT '本月末持仓数量(股/手)', +`AveragePriceAtTheEndOfTheMonth` varchar(37) NULL COMMENT '本月末持仓平均价格(元)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '标的情况与对冲'; +CREATE TABLE `A1013_ISDAInventoryBusinessDetailsAtTheEndOfThisMonth` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手名称(全称)', +`NameOfCounterpartyProduct` varchar(100) NULL COMMENT '交易对手产品名称(如有)', +`TradeConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(双方约定)', +`TransactionConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(报告库编号)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`NotionalPrincipalAmountLNotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(或多头名义本金)(元)', +`SNotionalPrincipalAmount` varchar(37) NULL COMMENT '空头名义本金(元)(多空组合填写)', +`StartDay` varchar(10) NULL COMMENT '起始日', +`DueDate` varchar(10) NULL COMMENT '到期日', +`InvestmentTargetType` varchar(2) NULL COMMENT '标的类型', +`UndrlygAssetName` varchar(200) NULL COMMENT '标的名称', +`UndrlygAssetCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`OptionObjectSecondClass` varchar(2) NULL COMMENT '场外期权标的小类(场外期权填写)', +`SwapObjectSecondClass` varchar(2) NULL COMMENT '收益互换标的小类(收益互换填写)', +`NonAnnualOptionFee` varchar(6) NULL COMMENT '期权费(非年化)(%)(场外期权填写)', +`OptionType` varchar(6) NULL COMMENT '期权类型(场外期权填写)', +`MaitainMarginRation` varchar(37) NULL COMMENT '本月末维持保证金比例(%)', +`CorrelationCoefficient` varchar(20) NULL COMMENT '标的相关系数', +`LongPositionContractValue` varchar(37) NULL COMMENT '多头合约价值(元)', +`ShortPositionContractValue` varchar(37) NULL COMMENT '空头合约价值(元)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '本月末存量业务明细'; +CREATE TABLE `A1013_ISDAIncreaseBusinessDetailsThisMonth` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `ExceID` varchar(28) NOT NULL COMMENT '业务数据流水号:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);', + `ReportDate` date NOT NULL COMMENT '报送日期', + `NameOfSecuritiesCompany` varchar(100) NULL COMMENT '报送机构名称(全称)', +`NameOfCounterparty` varchar(100) NULL COMMENT '交易对手名称(全称)', +`NameOfCounterpartyProduct` varchar(100) NULL COMMENT '交易对手产品名称(如有)', +`TradeConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(双方约定)', +`TransactionConfirmationNumber` varchar(100) NULL COMMENT '交易确认书编号(报告库编号)', +`BusinessType` varchar(2) NULL COMMENT '业务类型', +`NotionalPrincipalAmountLNotionalPrincipalAmount` varchar(37) NULL COMMENT '名义本金(或多头名义本金)(元)', +`SNotionalPrincipalAmount` varchar(37) NULL COMMENT '空头名义本金(元)(多空组合填写)', +`StartDay` varchar(10) NULL COMMENT '起始日', +`DueDate` varchar(10) NULL COMMENT '到期日', +`InvestmentTargetType` varchar(2) NULL COMMENT '标的类型', +`UndrlygAssetName` varchar(200) NULL COMMENT '标的名称', +`UndrlygAssetCode` varchar(200) NULL COMMENT '标的编码', +`UndrlygAssetTradgPlc` varchar(200) NULL COMMENT '标的交易场所', +`OptionObjectSecondClass` varchar(2) NULL COMMENT '场外期权标的小类(场外期权填写)', +`SwapObjectSecondClass` varchar(2) NULL COMMENT '收益互换标的小类(收益互换填写)', +`NonAnnualOptionFee` varchar(6) NULL COMMENT '期权费(非年化)(%)(场外期权填写)', +`OptionType` varchar(6) NULL COMMENT '期权类型(场外期权填写)', +`Index` text NULL COMMENT '序号', + + PRIMARY KEY (`id`) +) COMMENT = '本月新增业务明细'; + */ \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs index 5f3fa441..822f4c2e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Common/Sac_TranslateHelper.cs @@ -5,7 +5,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common { class Sac_TranslateHelper { - private static SacMap Map = null; + private static SacMap? Map = null; private static List GetSacInfo(PropertyInfo[] properties) { @@ -71,6 +71,44 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common } return map; } + + public static string TranslateFieldName(string fieldName, string fileType = "") + { + if (Map == null) + { + Init(); + } + SacMap map = Map; + return getFieldName_CN(map, fieldName, fileType); + } + private static string getFieldName_CN(SacMap map, string fieldName, string fileType = "") + { + if (map.FieldName == fieldName) + { + return map.FieldName_CN; + } + + if (map.SubMaps.Count > 0) + { + foreach (var m in map.SubMaps) + { + if (map.FieldName == "Body") + { + if (!string.IsNullOrWhiteSpace(fileType) && m.FieldName != fileType) + { + continue; + } + } + var ret = getFieldName_CN(m, fieldName, fileType); + if (!string.IsNullOrWhiteSpace(ret)) + { + return ret; + } + } + } + return ""; + + } } /// @@ -197,9 +235,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common FieldLength = info.FieldLength; FieldDescription = info.FieldDescription; Required = info.Required; - if (SubMaps != null) + if (this.SubMaps != null && this.SubMaps.Count > 0) { - SubMaps.ForEach(O => + SubMaps?.ForEach(O => { if (O == null) { @@ -210,4 +248,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Common } } } + + + public class ExceptionExtensionInfo + { + public List Tag { get; set; } + + public string ErrFilePath { get; set; } + } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ConfirmationAttModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ConfirmationAttModel.cs new file mode 100644 index 00000000..3fe818db --- /dev/null +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ConfirmationAttModel.cs @@ -0,0 +1,101 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Xml.Serialization; +using YLErp.Modules.SuperviseReportModule.SAC.Common; +using static YLErp.DBModels.Consts.ConsReport; + +namespace YLErp.Modules.SuperviseReportModule.SAC.Model +{ + /// + /// 交易确认书附件 + /// + [Table("A1019_ConfirmationAtt")] + public class ConfirmationAttModel : ReportBaseModel + { + /// + /// 交易确认书编号(双方约定) + /// 长度:100 + /// 必填:是 + /// 说明:双方约定 + /// + [CheckStringMaxLength(MaxLength = 100)] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号(双方约定)", "100", true, "双方约定;")] + public string ConfirmationNo { get; set; } + /// + /// 操作标识 + /// 长度:1 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [SacDescription("OperationType", "操作标识", "1", true, "")] + public OptFlagsEnum OperationType { get; set; } + /// + /// 交易确认书附件 + /// 长度:1 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [SacDescription("ConfirmationAtt", "交易确认书附件", "1", true, "说明:校验规则:只支持PDF格式")] + public string ConfirmationAtt { get; set; } + /// + /// 交易确认书附件 + /// 长度:1 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [SacDescription("ConfirmationFiles", "交易确认书附件", "1", true, "说明:校验规则:只支持PDF格式")] + public string ConfirmationFiles { get; set; } + /// + /// 交易确认书附件 + /// 长度: + /// 必填:是 + /// 说明:多附件; + /// + [CheckIEnumerableTMinCount(MinCount = 1)] + [XmlElement] + [NotMapped] + [SacDescription("ConfirmationFilesTuple", "交易确认书附件", "", true, "多附件;")] + public List ConfirmationFilesTuple { get; set; } + } + + public class ConfirmationFilesTupleModel + { + /// + /// 是否为收益互换 + /// + //[CheckStringInMap(Map = new[] { "true", "false" })] + [XmlIgnore] + public string IsSwap { get; set; } + /// + /// 场外期权交易确认书附件 + /// 长度:100 + /// 必填:是 + /// 说明:校验规则:只支持PDF格式 + /// + [CheckConditionStringValue(ConditionName = "IsSwap", ConditionValue = "false", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringValue(ConditionName = "IsSwap", ConditionValue = "true", CheckHandleNameArr = new[] { "B" })] + [CheckStringEndsWith(EndsWithString = ".pdf", CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("ConfirmationAtt", "交易确认书附件", "100", true, "校验规则:只支持PDF格式;")] + public string ConfirmationAtt { get; set; } + + /// + /// 收益互换交易确认书附件 + /// 长度:100 + /// 必填:是 + /// 说明:校验规则:只支持PDF格式 + /// + [CheckConditionStringValue(ConditionName = "IsSwap", ConditionValue = "true", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringValue(ConditionName = "IsSwap", ConditionValue = "false", CheckHandleNameArr = new[] { "B" })] + [CheckStringEndsWith(EndsWithString = ".pdf", CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("ConfirmationFiles", "交易确认书附件", "100", true, "校验规则:只支持PDF格式;")] + public string ConfirmationFiles { get; set; } + } +} \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtModel.cs index b4afe496..9735afcb 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +9,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 主协议 /// + [Table("A1001_MasterAgrmt")] public class MasterAgrmtModel : ReportBaseModel { /// @@ -44,7 +46,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("MasterAgrmtNo", "主协议编号(双方约定)", "100", true, "双方约定;")] public string MasterAgrmtNo { get; set; } /// - /// 签署时间 + /// 签订时间 /// 长度:10 /// 必填:是 /// 说明:校验规则:必须是yyyy-MM-dd @@ -52,7 +54,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] [DefaultValue("")] - [SacDescription("SigningDate", "签署时间", "10", true, "校验规则:必须是yyyy-MM-dd;")] + [SacDescription("SigningDate", "签订时间", "10", true, "校验规则:必须是YYYY-MM-DD;")] public string SigningDate { get; set; } /// /// 主协议版本 @@ -75,28 +77,28 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("FillParty", "填报方角色", "2", true, "")] public string FillParty { get; set; } /// - /// 交易对手方名称 + /// 交易对手方名称(全称) /// 长度:200 /// 必填:是 /// 说明: /// [CheckStringMaxLength(MaxLength = 200)] [DefaultValue("")] - [SacDescription("NameOfCounterparty", "交易对手方名称", "200", true, "")] + [SacDescription("NameOfCounterparty", "交易对手方名称(全称)", "200", true, "")] public string NameOfCounterparty { get; set; } /// /// 统一社会信用代码 /// 长度:18 - /// 必填:是 + /// 必填:否 /// 说明:校验规则:字段长度18位;当交易对手方类型是除了境外金融机构、境外非金融机构外的机构时,必填 /// [CheckConditionStringInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "14", "15" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "14", "15" }, CheckHandleNameArr = new[] { "B" })] [CheckStringMaxLength(MaxLength = 18, CheckHandleName = "A", Required = false)] - [CheckStringMinLength(MinLength = 18, CheckHandleName = "B")] + [CheckStringMinLength(MinLength = 1, CheckHandleName = "B")] [CheckStringMaxLength(MaxLength = 18, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("CODS", "统一社会信用代码", "18", true, "校验规则:字段长度18位;\r\n当交易对手方类型是除了境外金融机构、境外非金融机构外的机构时,必填;")] + [SacDescription("CODS", "统一社会信用代码", "18", false, "校验规则:字段长度18位;\r\n当交易对手方类型是除了境外金融机构、境外非金融机构外的机构时,必填;")] public string CODS { get; set; } /// /// 交易对手编码 @@ -112,13 +114,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// LEI码 /// 长度:20 /// 必填:否 - /// 说明:校验规则:当交易对手方类型是境外金融机构、境外非金融机构外的机构时,必填 + /// 说明:校验规则:当交易对手方类型是境外金融机构、境外非金融机构时,必填 /// [CheckConditionStringInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "14", "15" }, CheckHandleNameArr = new[] { "A" })] [CheckStringMinLength(MinLength = 1, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 20, CheckHandleName = "A")] [DefaultValue("")] - [SacDescription("LEI", "LEI码", "20", false, "校验规则:当交易对手方类型是境外金融机构、境外非金融机构外的机构时,必填;")] + [SacDescription("LEI", "LEI码", "20", false, "校验规则:当交易对手方类型是境外金融机构、境外非金融机构时,必填;")] public string LEI { get; set; } /// /// 交易对手类别 @@ -144,14 +146,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 非金融机构行业代码 /// 长度:20 /// 必填:否 - /// 说明:校验规则:交易对手方类型为非金融机构时必填;参照国家统计局发布的《国民经济行业分类》 + /// 说明:校验规则:当“交易对手方类型”选择境内非金融机构时,必填;参照国家统计局发布的《国民经济行业分类》 /// - [CheckConditionStringInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "13", "15" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "13", "15" }, CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "13" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(CounterpartyType), ConditionMap = new[] { "13" }, CheckHandleNameArr = new[] { "B" })] [CheckStringMaxLength(MaxLength = 20, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 20, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("NFICode", "非金融机构行业代码", "20", false, "校验规则:交易对手方类型为非金融机构时必填;\r\n参照国家统计局发布的《国民经济行业分类》;")] + [SacDescription("NFICode", "非金融机构行业代码", "20", false, "校验规则:当“交易对手方类型”选择境内非金融机构时,必填;\r\n参照国家统计局发布的《国民经济行业分类》;")] public string NFICode { get; set; } /// /// 交易对手方注册资本(万元) @@ -161,7 +163,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("CounterpartyRegdCptl", "交易对手方注册资本(万元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("CounterpartyRegdCptl", "交易对手方注册资本(万元)", "36,2", false, "校验规则:必须两位小数以内")] public string CounterpartyRegdCptl { get; set; } /// /// 主协议备注 @@ -201,6 +203,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckIEnumerableTMinCount(MinCount = 1)] [XmlElement] + [NotMapped] [SacDescription("CounterpartyInformationTuple", "填报方业务代表明细", "", false, "")] public List CounterpartyInformationTuple { get; set; } } @@ -208,8 +211,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 填报方业务代表明细 /// - public class CounterpartyInfomationModel + [Table("A1001_CounterpartyInfomation")] + public class CounterpartyInfomationModel : ReportSubBaseModel { + /// + /// 主协议编号 + /// 长度:200 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + public string MasterAgrmtNo { get; set; } /// /// 填报方业务代表姓名 /// 长度:200 diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtProductModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtProductModel.cs index 2bc91c2d..ce2fb705 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtProductModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/MasterAgrmtProductModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +9,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 主协议关联产品 /// + [Table("A1002_MasterAgrmtProduct")] public class MasterAgrmtProductModel : ReportBaseModel { /// @@ -52,11 +54,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 产品名称 /// 长度:100 - /// 必填:是 + /// 必填:否 /// /// 说明:校验规则: /// 1 主协议交易对手方身份为产品管理人时必填; - /// 2 主协议交易对手方身份为自营时禁止填值; + /// 2 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -64,26 +66,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 100, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("ProductName", "产品名称", "100", true, "校验规则:\r\n1 主协议交易对手方身份为产品管理人时必填;\r\n2 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("ProductName", "产品名称", "100", false, "校验规则:\r\n1 主协议交易对手方身份为产品管理人时必填;\r\n2 主协议交易对手方身份为自营禁止填值;")] public string ProductName { get; set; } /// /// 交易对手码(产品) /// 长度:20 - /// 必填:是 - /// 说明:应当符合标准规范 + /// 必填:否 + /// 说明:校验规则:1、主协议交易对手方身份为产品管理人必填;2、主协议交易对手方身份为自营禁止填值;3、应当符合标准规范 /// [CheckStringMaxLength(MaxLength = 20)] [DefaultValue("")] - [SacDescription("CounterpartyCodeProducts", "交易对手码(产品)", "20", true, "应当符合标准规范;")] + [SacDescription("CounterpartyCodeProducts", "交易对手码(产品)", "20", false, "校验规则:\r\n1、主协议交易对手方身份为产品管理人必填;\r\n2、主协议交易对手方身份为自营禁止填值;\r\n3、应当符合标准规范;")] public string CounterpartyCodeProducts { get; set; } /// /// 产品投资经理姓名 /// 长度:100 - /// 必填:是 + /// 必填:否 /// /// 说明:校验规则: - /// 1 主协议交易对手方身份为产品管理人时必填; - /// 2 主协议交易对手方身份为自营时禁止填值; + /// 1 主协议交易对手方身份为产品管理人必填; + /// 2 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -91,16 +93,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 100, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("ManagerName", "产品投资经理姓名", "100", true, "校验规则:\r\n1 主协议交易对手方身份为产品管理人时必填;\r\n2 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("ManagerName", "产品投资经理姓名", "100", false, "校验规则:\r\n1 主协议交易对手方身份为产品管理人必填;\r\n2 主协议交易对手方身份为自营禁止填值;")] public string ManagerName { get; set; } /// /// 投资经理联系电话 /// 长度:20 - /// 必填:是 + /// 必填:否 /// /// 说明:校验规则: - /// 1 主协议交易对手方身份为产品管理人时必填; - /// 2 主协议交易对手方身份为自营时禁止填值; + /// 1 主协议交易对手方身份为产品管理人必填; + /// 2 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -108,7 +110,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 20, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("InvestmentManagerContactNumber", "投资经理联系电话", "20", true, "校验规则:\r\n1 主协议交易对手方身份为产品管理人时必填;\r\n2 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("InvestmentManagerContactNumber", "投资经理联系电话", "20", false, "校验规则:\r\n1 主协议交易对手方身份为产品管理人必填;\r\n2 主协议交易对手方身份为自营禁止填值;")] public string InvestmentManagerContactNumber { get; set; } /// /// 托管机构(如有) @@ -116,7 +118,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:否 /// /// 说明:校验规则: - /// 1 主协议交易对手方身份为自营时禁止填值; + /// 1 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -124,17 +126,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 200, Required = false, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("TrusteeAgency", "托管机构(如有)", "200", false, "校验规则:\r\n1 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("TrusteeAgency", "托管机构(如有)", "200", false, "校验规则:\r\n1 主协议交易对手方身份为自营禁止填值;")] public string TrusteeAgency { get; set; } /// /// 入表日期 /// 长度:10 - /// 必填:是 + /// 必填:否 /// /// 说明:校验规则: - /// 1 必须是yyyy-MM-dd; - /// 2 主协议交易对手方身份为产品管理人时必填; - /// 3 主协议交易对手方身份为自营时禁止填值; + /// 1 必须是YYYY-MM-DD; + /// 2 主协议交易对手方身份为产品管理人必填; + /// 3 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -143,17 +145,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd", CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("TheDateTable", "入表日期", "10", true, "校验规则:\r\n1 必须是yyyy-MM-dd;\r\n2 主协议交易对手方身份为产品管理人时必填;\r\n3 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("TheDateTable", "入表日期", "10", false, "校验规则:\r\n1 必须是YYYY-MM-DD;\r\n2 主协议交易对手方身份为产品管理人必填;\r\n3 主协议交易对手方身份为自营禁止填值;")] public string TheDateTable { get; set; } /// /// 代签产品附件 /// 长度:10 - /// 必填:是 + /// 必填:否 /// /// 说明:校验规则: /// 1 只支持PDF格式; - /// 2 主协议交易对手方身份为产品管理人时必填; - /// 3 主协议交易对手方身份为自营时禁止填值; + /// 2 主协议交易对手方身份为产品管理人必填; + /// 3 主协议交易对手方身份为自营禁止填值; /// /// [CheckConditionStringInMap(ConditionName = nameof(ClientType), ConditionMap = new[] { "产品", "产品管理人" }, CheckHandleNameArr = new[] { "A" })] @@ -161,7 +163,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringEndsWith(EndsWithString = ".pdf", CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("SuchProducts", "代签产品附件", "10", true, "校验规则:\r\n1 只支持PDF格式;\r\n2 主协议交易对手方身份为产品管理人时必填;\r\n3 主协议交易对手方身份为自营时禁止填值;")] + [SacDescription("SuchProducts", "代签产品附件", "10", false, "校验规则:\r\n1 只支持PDF格式;\r\n2 主协议交易对手方身份为产品管理人必填;\r\n3 主协议交易对手方身份为自营禁止填值;")] public string SuchProducts { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionConfirmationModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionConfirmationModel.cs index 0fe504d6..a7f0f9cf 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionConfirmationModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionConfirmationModel.cs @@ -1,4 +1,8 @@ -using System.ComponentModel; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +12,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 期权交易确认书 /// + [Table("A1004_OptionConfirmation")] public class OptionConfirmationModel : ReportBaseModel { /// @@ -45,10 +50,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:否 /// 说明:校验规则:补正时必填 /// - [CheckConditionStringValue(ConditionName = nameof(OperationType), ConditionValue = "A", CheckHandleNameArr = new[] { "B" })] - [CheckConditionStringNEQValue(ConditionName = nameof(OperationType), ConditionValue = "A", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringValue(ConditionName = nameof(OperationType), ConditionValue = "A", + CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringNEQValue(ConditionName = nameof(OperationType), ConditionValue = "A", + CheckHandleNameArr = new[] { "A" })] [CheckStringMaxLength(MaxLength = 32, CheckHandleName = "A")] - [CheckStringMaxLength(MaxLength = 32, Required = false, CheckHandleName = "B")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("ConfirmationID", "交易确认书编号", "32", false, "校验规则:补正时必填;")] public string ConfirmationID { get; set; } @@ -70,7 +77,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringInMap(Map = new[] { "0", "1" })] [DefaultValue("")] - [SacDescription("ConfirmationType", "交易确认书类型", "2", true, "")] + [SacDescription("ConfirmationType", "交易确认书类型", "2", true, "校验规则:首次提交时填0,补正时填1")] public string ConfirmationType { get; set; } /// /// 填报方角色 @@ -102,28 +109,32 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("OptionDirection", "期权方向", "2", true, "")] public string OptionDirection { get; set; } + /// /// 期权结构类型 /// 长度:2 /// 必填:是 - /// 说明: + /// 说明:选择期权结构类型后填写对应的【期权结构类型详情】 /// - [CheckStringInMap(Map = new[] { "0", "1", "2", "4", "5", "6", "7", "99" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" })] [DefaultValue("")] - [SacDescription("OptionStructureType", "期权结构类型", "2", true, "")] + [SacDescription("OptionStructureType", "期权结构类型", "2", true, "选择期权结构类型后填写对应的【期权结构类型详情】")] public string OptionStructureType { get; set; } + /// - /// 期权结构 + /// 期权结构类型 /// 长度:2000 /// 必填:否 /// 说明:校验规则:=其他时,该字段必填 /// - [CheckConditionStringValue(ConditionName = nameof(OptionStructureType), ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNEQValue(ConditionName = nameof(OptionStructureType), ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringValue(ConditionName = nameof(OptionStructureType), ConditionValue = "99", + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(OptionStructureType), ConditionValue = "99", + CheckHandleNameArr = new[] { "B" })] [CheckStringMaxLength(MaxLength = 2000, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("OptionStructure", "期权结构", "2000", false, "校验规则:期权结构类型=其他时,该字段必填;")] + [SacDescription("OptionStructure", "期权结构类型", "2000", false, "校验规则:期权结构类型选择为其他时,该字段必填;")] public string OptionStructure { get; set; } /// /// 行权方式 @@ -148,7 +159,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] [DefaultValue("")] - [SacDescription("StartDate", "起始日", "10", true, "交易条款开始执行的日期.\r\n校验规则:\r\n1 起始日不能大于到期日日期;\r\n2 必须是yyyy-MM-dd;")] + [SacDescription("StartDate", "起始日", "10", true, "交易条款开始执行的日期.\r\n校验规则:\r\n1 起始日不能大于到期日日期;\r\n2 必须是YYYY-MM-DD;")] public string StartDate { get; set; } /// /// 到期日 @@ -164,7 +175,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] [DefaultValue("")] - [SacDescription("DueDate", "到期日", "10", true, "指定交易结束的日期.\r\n校验规则:\r\n1 到期日不能小于起始日日期;\r\n2 必须是yyyy-MM-dd;\r\n3 补正时,如果该交易还有未被废除的存续期记录(包括展期,终止数据),到期日字段不能修改;")] + [SacDescription("DueDate", "到期日", "10", true, + "指定交易结束的日期.\r\n校验规则:\r\n1 到期日不能小于起始日日期;\r\n2 必须是YYYY-MM-DD;\r\n3 补正时,如果该交易还有未被废除的存续期记录(包括展期,终止数据),到期日字段不能修改;")] public string DueDate { get; set; } /// /// 结算日 @@ -178,50 +190,75 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10, Required = false)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd", Required = false)] [DefaultValue("")] - [SacDescription("SettlementDate", "结算日", "10", false, "指定的进行结算金额收付的日期.\r\n校验规则:必须是yyyy-MM-dd;")] + [SacDescription("SettlementDate", "结算日", "10", false, "指定的进行结算金额收付的日期.\r\n校验规则:必须是YYYY-MM-DD;")] public string SettlementDate { get; set; } + /// - /// 期权费(非年化)% + /// 期权费(非年化)(%) /// 长度:6 /// 必填:是 - /// 说明:校验规则:1 数值处于0~100之间最多两位小数;2 百分比处于0~100之间整数带% + /// 说明:校验规则:1 数值处于0~100之间最多两位小数;2 百分比处于0~100之间整数不带% /// - [CheckStringIntOrPercentRange( - BeforePointMaxLength_Percent = 3, - AfterPointMaxLength_Percent = 0, - MinValue_Percent = 0, - MaxValue_Percent = 100, - BeforePointMaxLength_Number = 3, - AfterPointMaxLength_Number = 2, - MinValue_Number = 0, - MaxValue_Number = 100 - )] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0)] [DefaultValue("")] - [SacDescription("OptionPremium", "期权费(非年化)%", "6", true, "校验规则:\r\n1 数值处于0~100之间最多两位小数;\r\n2 百分比处于0~100之间整数带%;")] + [SacDescription("OptionPremium", "期权费(非年化)(%)", "6", true, "校验规则:\r\n1 数值处于0至100之间最多两位小数;\r\n2 百分比处于0至100之间整数;")] public string OptionPremium { get; set; } /// + /// 年化天数 + /// 长度:3 + /// 必填:是 + /// 说明:正整数 + /// + [CheckStringIntMaxLength(AfterPointMaxLength = 0, BeforePointMaxLength = 3, MinValue = 0)] + [DefaultValue("")] + [SacDescription("AnnualizedDays", "年化天数", "3", true, "填写不为零的正整数")] + public string AnnualizedDays { get; set; } + + /// + /// 定价波动率(%) + /// 长度:5,2 + /// 必填:是 + /// 说明: + /// + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2)] + [DefaultValue("")] + [SacDescription("PricingVolatility", "定价波动率(%)", "5,2", true, "期权期初估值定价时的波动率")] + public string PricingVolatility { get; set; } + + /// + /// 无风险利率(%) + /// 长度:5,2 + /// 必填:是 + /// 说明: + /// + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2)] + [DefaultValue("")] + [SacDescription("RiskFreeInterestRates", "无风险利率(%)", "5,2", true, "期权期初估值定价时的无风险利率")] + public string RiskFreeInterestRates { get; set; } + /// /// 结算货币 /// 长度:2 /// 必填:是 - /// 说明: + /// 说明: /// - [CheckStringMaxLength(MaxLength = 3)] + [CheckStringMaxLength(MaxLength = 2)] [DefaultValue("")] - [SacDescription("Currency", "结算货币", "2", true, "")] + [SacDescription("Currency", "结算货币", "2", true, "使用货币通用代码(大写)")] public string Currency { get; set; } /// - /// 名义金额(人民币) + /// 名义本金(元) /// 长度:36,2 /// 必填:是 /// /// 说明:控件提示:单位元,小数点后保留两位. - /// 校验规则:1 必须两位小数; - /// 2 补正时,如果该交易还有未被废除的存续期记录(包括展期,终止数据),名义本金额(人民币)字段不能修改; + /// 校验规则:1 必须两位小数;2 名义本金为标的期初价格乘以数量乘以乘数; + /// 3 补正时,如果该交易还有未被废除的存续期记录(包括展期,终止数据),名义本金额(人民币)字段不能修改; /// /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("NotinalPrincipleAmt", "名义金额(人民币)", "36,2", true, "控件提示:单位元,小数点后保留两位.\r\n校验规则:\r\n1 必须两位小数;\r\n2 补正时,如果该交易还有未被废除的存续期记录(包括展期,终止数据),名义本金额(人民币)字段不能修改;")] + [SacDescription("NotinalPrincipleAmt", "名义本金(元)", "36,2", true, + "控件提示:单位元,小数点后保留两位.\r\n校验规则:\r\n1 保留两位小数;\r\n2 名义本金为标的期初价格乘以数量乘以乘数;\r\n3 补正时,如果该交易还有未被废除的存续期记录(包括展期、终止数据),名义本金(人民币)字段不能修改;")] public string NotinalPrincipleAmt { get; set; } /// /// 清算机构 @@ -244,31 +281,44 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("TradingPlace", "交易场所", "2", true, "")] public string TradingPlace { get; set; } /// - /// 业务模式类型 - /// 长度:2 - /// 必填:是 - /// 说明: + /// 交易场所(其他) + /// 长度:200 + /// 必填:否 + /// 说明:当"交易场所"选择"其他交易场所"时,必填;选其他选项时不能填写 /// - [CheckStringInMap(Map = new[] { "1" })] + [CheckConditionStringValue(ConditionName = nameof(TradingPlace), ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(TradingPlace), ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 200, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("BusinessModelType", "业务模式类型", "2", true, "")] - public string BusinessModelType { get; set; } + [SacDescription("TradingPlaceOther", "交易场所(其他)", "200", false, "当\"交易场所\"选择\"其他交易场所\"时,必填;\r\n选其他选项时不能填写;")] + public string TradingPlaceOther { get; set; } + ///// + ///// 业务模式类型 + ///// 长度:2 + ///// 必填:是 + ///// 说明: + ///// + //// [CheckStringInMap(Map = new[] { "1" })] + //// [DefaultValue("")] + //// [SacDescription("BusinessModelType", "业务模式类型", "2", true, "")] + //// public string BusinessModelType { get; set; } + ///// + ///// 交易确认书附件 + ///// + //[CheckIEnumerableTMinCount(MinCount = 1)] + //[XmlElement] + //[SacDescription("ConfirmationAttTuple", "交易确认书附件", "", false, "")] + //public List ConfirmationAttTuple { get; set; } /// - /// 交易确认书附件 - /// - [CheckIEnumerableTMinCount(MinCount = 1)] - [XmlElement] - [SacDescription("ConfirmationAttTuple", "交易确认书附件", "", false, "")] - public List ConfirmationAttTuple { get; set; } - /// - /// 备注 + /// 基本信息备注 /// 长度:1024 /// 必填:否 /// 说明:填写上述字段或交易确认书中不能包含的信息 /// [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] - [SacDescription("ConfirmationRemark", "备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] + [SacDescription("ConfirmationRemark", "基本信息备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] public string ConfirmationRemark { get; set; } /// /// 标的类型 @@ -301,14 +351,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("ProfitCalculationInfo", "期权收益计算说明", "1024", true, "")] public string ProfitCalculationInfo { get; set; } /// - /// 备注 + /// 备注/收益备注 /// 长度:1024 /// 必填:否 /// 说明:填写上述字段或交易确认书中不能包含的信息 /// [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] - [SacDescription("ProfitRemark", "备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] + [SacDescription("ProfitRemark", "备注/收益备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] public string ProfitRemark { get; set; } /// /// 标的详情 @@ -318,8 +368,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckIEnumerableTMinCount(MinCount = 1)] [XmlElement] - [SacDescription("UndrlygAssetTuple", "标的详情", "", false, "数组结构支持新增多条;")] + [NotMapped] + [SacDescription("UndrlygAssetTuple", "标的详情", "", false, "数组结构,支持新增多条;")] public List UndrlygAssetTuple { get; set; } + /// /// 履约担保类型 /// 长度:2 @@ -330,152 +382,219 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("PerformanceGuaranteeType", "履约担保类型", "2", true, "")] public string PerformanceGuaranteeType { get; set; } + /// /// 履约担保品提供方 /// 长度:2 /// 必填:否 - /// 说明: + /// 说明:校验规则:当“履约担保类型”选择部分担保、全额担保时,必填; /// - [CheckStringInMap(Map = new[] { "0", "1", "2", "3" }, Required = false)] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollProvider", "履约担保品提供方", "2", false, "")] + [SacDescription("PerformanceCollProvider", "履约担保品提供方", "2", false, "校验规则:当“履约担保类型”选择部分担保、全额担保时,必填;")] public string PerformanceCollProvider { get; set; } + /// /// 担保品收取方是否可使用担保品 /// 长度:5 /// 必填:否 - /// 说明: + /// 说明:校验规则:当“履约担保类型”选择部分担保、全额担保时,必填; /// - [CheckStringInMap(Map = new[] { "true", "false" }, Required = false)] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "true", "false" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PartyUseColl", "担保品收取方是否可使用担保品", "5", false, "")] + [SacDescription("PartyUseColl", "担保品收取方是否可使用担保品", "5", false, "校验规则:当“履约担保类型”选择部分担保、全额担保时,必填;")] public string PartyUseColl { get; set; } + /// /// 担保品使用说明 /// 长度:1024 /// 必填:否 - /// 说明:校验规则:当履约保障类型()选择部分担保或全额担保时必填; + /// 说明:检验规则:当“担保品收取方是否可使用担保品”选择“是”时,必填; /// - [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringValue(ConditionName = nameof(PartyUseColl), ConditionValue = "true", + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(PartyUseColl), ConditionValue = "true", + CheckHandleNameArr = new[] { "B" })] [CheckStringMaxLength(MaxLength = 1024, IgnoreNullOrEmpty = false, CheckHandleName = "A")] - [CheckStringMaxLength(MaxLength = 1024, Required = false, CheckHandleName = "B")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("CollInstruction", "担保品使用说明", "1024", false, "校验规则:当履约保障类型选择部分担保或全额担保时必填;")] + [SacDescription("CollInstruction", "担保品使用说明", "1024", false, "检验规则:当“担保品收取方是否可使用担保品”选择“是”时,必填;")] public string CollInstruction { get; set; } + /// /// 是否计算担保品价值产生利息 /// 长度:5 /// 必填:否 - /// 说明: + /// 说明:校验规则:当“履约担保类型”选择部分担保、全额担保时,必填 /// - [CheckStringInMap(Map = new[] { "true", "false" }, Required = false)] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "true", "false" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("CalculateCollInterest", "是否计算担保品价值产生利息", "5", false, "")] + [SacDescription("CalculateCollInterest", "是否计算担保品价值产生利息", "5", false, "校验规则:当“履约担保类型”选择部分担保、全额担保时,必填")] public string CalculateCollInterest { get; set; } + /// /// 履约担保品初始比率(%) /// 长度:5,2 /// 必填:否 /// - /// 说明:校验规则: - /// 1 当履约保障类型()选择部分担保或全额担保时必填; - /// 2 请输入0~100之间的最多两位小数的数字; + /// 说明:校验规则:1.当“履约担保类型”选择部分担保、全额担保时,必填;2.大于等于0的数字,保留两位小数,该值为100%时,填写100.00; /// /// - [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, CheckHandleName = "A")] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, Required = false, CheckHandleName = "B")] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MinValue = 0, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollInitialRatio", "履约担保品初始比率(%)", "5,2", false, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 请输入0~100之间的最多两位小数的数字;")] + [SacDescription("PerformanceCollInitialRatio", "履约担保品初始比率(%)", "5,2", false, + "校验规则:\r\n1.当“履约担保类型”选择部分担保、全额担保时,必填;\r\n2.大于等于0的数字,保留两位小数,该值为100%时,填写100.00;")] public string PerformanceCollInitialRatio { get; set; } + + /// + /// 履约担保品初始比率(现金部分)(%) + /// 长度:5,2 + /// 必填:否 + /// + /// 说明:校验规则:1、当“履约担保类型”选择部分担保、全额担保时,必填;2、大于等于0 的数字,保留两位小数,该值为100% 时 , 填写100.00 + /// + /// + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MinValue = 0, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("PerformanceCollInitialRatioCash", "履约担保品初始比率(现金部分)(%)", "5,2", false, + "校验规则:\r\n1、当“履约担保类型”选择部分担保、全额担保时,必填;\r\n2、大于等于0 的数字,保留两位小数,该值为100% 时 , 填写100.00")] + public string PerformanceCollInitialRatioCash { get; set; } + /// /// 履约担保品追保比率(%) /// 长度:5,2 /// 必填:否 - /// - /// 说明:校验规则: - /// 1 当履约保障类型()选择部分担保或全额担保时必填; - /// 2 请输入0~100之间的最多两位小数的数字; - /// + /// 校验规则:1.当“履约担保类型”选择部分担保、全额担保时,必填;2.大于等于0的数字,保留两位小数,该值为100%时,填写100.00; /// - [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, CheckHandleName = "A")] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, Required = false, CheckHandleName = "B")] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MinValue = 0, + CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollAddtlRatio", "履约担保品追保比率(%)", "5,2", false, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 请输入0~100之间的最多两位小数的数字;")] + [SacDescription("PerformanceCollAddtlRatio", "履约担保品追保比率(%)", "5,2", false, + "校验规则:\r\n1.当“履约担保类型”选择部分担保、全额担保时,必填;\r\n2.大于等于0的数字,保留两位小数,该值为100%时,填写100.00;")] public string PerformanceCollAddtlRatio { get; set; } + /// /// 履约担保品平仓比率(%) /// 长度:5,2 /// 必填:否 - /// - /// 说明:校验规则: - /// 1 当履约保障类型()选择部分担保或全额担保时必填; - /// 2 请输入0~100之间的最多两位小数的数字; - /// 备注:强行平仓时比率 - /// + /// 校验规则:1、当“履约担保类型”选择部分担保、全额担保时,必填;2、大于等于0的数字,保留两位小数,该值为100%时,填写100.00; /// - [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, CheckHandleName = "A")] - [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, Required = false, CheckHandleName = "B")] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MinValue = 0, + CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollOffsetRatio", "履约担保品平仓比率(%)", "5,2", false, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 请输入0~100之间的最多两位小数的数字;\r\n备注:强行平仓时比率;")] + [SacDescription("PerformanceCollOffsetRatio", "履约担保品平仓比率(%)", "5,2", false, + "校验规则:\r\n1、当“履约担保类型”选择部分担保、全额担保时,必填;\r\n2、大于等于0的数字,保留两位小数,该值为100%时,填写100.00;")] public string PerformanceCollOffsetRatio { get; set; } + /// - /// 备注 + /// 维持担保比率(%) + /// 长度:5,2 + /// 必填:否 + /// 校验规则:当"履约担保类型"选择部分担保、全额担保 时必填;选其他选项时不能填写; + /// + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntMaxLength(BeforePointMaxLength = 5, AfterPointMaxLength = 2, MinValue = 0, + CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("MaintainGuaranteeRatio", "维持担保比率(%)", "5,2", false, + "校验规则:当\"履约担保类型\"选择部分担保、全额担保 时必填;选其他选项时不能填写;")] + public string MaintainGuaranteeRatio { get; set; } + + /// + /// 备注/履约担保备注 /// 长度:1024 /// 必填:否 /// 说明:校验规则:填写上述字段或交易确认书中不能包含的信息 /// [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] - [SacDescription("PerformanceGuaranteeRemark", "备注", "1024", false, "校验规则:填写上述字段或交易确认书中不能包含的信息;")] + [SacDescription("PerformanceGuaranteeRemark", "备注/履约担保备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] public string PerformanceGuaranteeRemark { get; set; } /// - /// 履约保障书附件附件 + /// 履约担保附件 /// 长度: /// 必填:否 /// 说明:校验规则:只支持PDF格式 /// [CheckStringEndsWith(EndsWithString = ".pdf", Required = false)] [DefaultValue("")] - [SacDescription("PerformanceGuaranteeAtt", "履约保障书附件附件", "", false, "校验规则:只支持PDF格式;")] + [SacDescription("PerformanceGuaranteeAtt", "履约担保附件", "", false, "校验规则:只支持PDF格式;")] public string PerformanceGuaranteeAtt { get; set; } /// /// 履约担保品详情 /// 长度: /// 必填: - /// 说明:校验规则:当履约保障类型()选择部分担保或全额担保时必填; /// 说明:数组结构,支持新增多条 /// - [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] - [CheckIEnumerableTMinCount(CheckHandleName = "A", MinCount = 1)] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "B" })] + [CheckIEnumerableTMinCount(MinCount = 1, CheckHandleName = "A")] + [CheckIEnumerableTMaxCount(MaxCount = 0, CheckHandleName = "B", Required = false)] [XmlElement] - [SacDescription("PerformanceCollTuple", "履约担保品详情", "", false, "校验规则:当履约保障类型选择部分担保或全额担保时必填;\r\n数组结构,支持新增多条;")] + [NotMapped] + [SacDescription("PerformanceCollTuple", "履约担保品详情", "", false, "数组结构,支持新增多条;")] public List PerformanceCollTuple { get; set; } /// - /// 备注 + /// 备注/其他信息备注 /// 长度:1024 /// 必填:否 /// 说明:填写上述字段或交易确认书中不能包含的信息填写上述字段或交易确认书中不能包含的信息 /// [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] - [SacDescription("Remark", "备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息填写上述字段或交易确认书中不能包含的信息;")] + [SacDescription("Remark", "备注/其他信息备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息填写上述字段或交易确认书中不能包含的信息;")] public string Remark { get; set; } /// - /// 有效名义本金(人民币) + /// 有效名义本金(元) /// 长度:36,2 /// 必填:是 - /// 说明:有效名义本金是指期权参与率为100%且剔除了年化系数影响之后的名义本金, 校验规则:保留两位小数; + /// 说明: /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("ValidNotinalPrincipleAmt", "有效名义本金(人民币)", "36,2", true, "有效名义本金是指期权参与率为100%且剔除了年化系数影响之后的名义本金;\r\n校验规则:保留两位小数;")] + [SacDescription("ValidNotinalPrincipleAmt", "有效名义本金(元)", "36,2", true, + "")] public string ValidNotinalPrincipleAmt { get; set; } /// /// 合规意见书 @@ -487,168 +606,1894 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("ComplianceOpinion", "合规意见书", "", false, "校验规则:只支持PDF格式;")] public string ComplianceOpinion { get; set; } - /// - /// 行权价格1 - /// 长度:36,2 - /// 必填:是 - /// 说明:校验规则:保留两位小数; - /// - [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] - [DefaultValue("")] - [SacDescription("ExercisePriceOne", "行权价格1", "36,2", true, "校验规则:保留两位小数;")] - public string ExercisePriceOne { get; set; } - /// - /// 行权价格2 - /// 长度:36,2 - /// 必填:否 - /// 说明:校验规则:保留两位小数; - /// - [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] - [DefaultValue("")] - [SacDescription("ExercisePriceTwo", "行权价格2", "36,2", false, "校验规则:保留两位小数;")] - public string ExercisePriceTwo { get; set; } + + // /// + // /// 行权价格1 + // /// 长度:36,2 + // /// 必填:是 + // /// 说明:校验规则:保留两位小数; + // /// + // [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] + // [DefaultValue("")] + // [SacDescription("ExercisePriceOne", "行权价格1", "36,2", true, "校验规则:保留两位小数;")] + // public string ExercisePriceOne { get; set; } + // /// + // /// 行权价格2 + // /// 长度:36,2 + // /// 必填:否 + // /// 说明:校验规则:保留两位小数; + // /// + // [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] + // [DefaultValue("")] + // [SacDescription("ExercisePriceTwo", "行权价格2", "36,2", false, "校验规则:保留两位小数;")] + // public string ExercisePriceTwo { get; set; } /// /// 甲方代签产品名称 - /// 长度:200 + /// 长度:100 /// 必填:否 - /// 说明:校验规则:1 如甲方代签产品名称或甲方代签产品代码填值,则乙方代签产品名称和乙方代签产品代码禁止填值;2 甲方代签产品名称必须在主协议关联产品列表-产品名称中存在; + /// 说明:校验规则:1、如甲方代签产品名称或甲方交易对手方码(产品)填值,则乙方代签产品名称和乙方交易对手码(产品)禁止填值;2、甲方代签产品名称必须在主协议关联产品列表-产品名称中存在; /// - [CheckStringMaxLength(MaxLength = 200, Required = false)] + [CheckStringMaxLength(MaxLength = 100, Required = false)] [DefaultValue("")] - [SacDescription("PtyAPdctName", "甲方代签产品名称", "200", false, "校验规则:\r\n1 如甲方代签产品名称或甲方代签产品代码填值,则乙方代签产品名称和乙方代签产品代码禁止填值;\r\n2 甲方代签产品名称必须在主协议关联产品列表-产品名称中存在;")] + [SacDescription("PtyAPdctName", "甲方代签产品名称", "100", false, + "校验规则:\r\n1、如甲方代签产品名称或甲方交易对手方码(产品)填值,则乙方代签产品名称和乙方交易对手码(产品)禁止填值;\r\n2、甲方代签产品名称必须在主协议关联产品列表-产品名称中存在;")] public string PtyAPdctName { get; set; } /// - /// 甲方代签产品代码 + /// 甲方交易对手码(产品) /// 长度:20 /// 必填:否 - /// 说明:校验规则:如甲方代签产品名称或甲方代签产品代码填值,则乙方代签产品名称和乙方代签产品代码禁止填值; + /// 说明:校验规则:如甲方代签产品名称或甲方交易对手方码(产品)填值,则乙方代签产品名称和乙方交易对手码(产品)禁止填值; /// [CheckStringMaxLength(MaxLength = 20, Required = false)] [DefaultValue("")] - [SacDescription("PytAPdctCode", "甲方代签产品代码", "20", false, "校验规则:如甲方代签产品名称或甲方代签产品代码填值,则乙方代签产品名称和乙方代签产品代码禁止填值;")] + [SacDescription("PytAPdctCode", "甲方交易对手码(产品)", "20", false, "校验规则:如甲方代签产品名称或甲方交易对手方码(产品)填值,则乙方代签产品名称和乙方交易对手码(产品)禁止填值;")] public string PytAPdctCode { get; set; } /// /// 乙方代签产品名称 - /// 长度:200 + /// 长度:100 /// 必填:否 - /// 说明:校验规则:1 如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值;2 乙方代签产品名称必须在主协议关联产品列表-产品名称中存在; + /// 说明:校验规则:1、如乙方代签产品名称或乙方交易对手方码(产品)填值,则甲方代签产品名称和甲方交易对手码(产品)禁止填值;2、乙方代签产品名称必须在主协议关联产品列表-产品名称中存在; /// - [CheckStringMaxLength(MaxLength = 200, Required = false)] + [CheckStringMaxLength(MaxLength = 100, Required = false)] [DefaultValue("")] - [SacDescription("PtyBPdctName", "乙方代签产品名称", "200", false, "校验规则:\r\n1 如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值;\r\n2 乙方代签产品名称必须在主协议关联产品列表-产品名称中存在;")] + [SacDescription("PtyBPdctName", "乙方代签产品名称", "100", false, + "校验规则:\r\n1、如乙方代签产品名称或乙方交易对手方码(产品)填值,则甲方代签产品名称和甲方交易对手码(产品)禁止填值;\r\n2、乙方代签产品名称必须在主协议关联产品列表-产品名称中存在;")] public string PtyBPdctName { get; set; } /// - /// 乙方代签产品代码 + /// 乙方交易对手码(产品) /// 长度:20 /// 必填:否 - /// 说明:校验规则:如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值; + /// 说明:校验规则:如乙方代签产品名称或乙方交易对手方码(产品)填值,则甲方代签产品名称和甲方交易对手码(产品)禁止填值; /// [CheckStringMaxLength(MaxLength = 20, Required = false)] [DefaultValue("")] - [SacDescription("PytBPdctCode", "乙方代签产品代码", "20", false, "校验规则:如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值;")] + [SacDescription("PytBPdctCode", "乙方交易对手码(产品)", "20", false, "校验规则:如乙方代签产品名称或乙方交易对手方码(产品)填值,则甲方代签产品名称和甲方交易对手码(产品)禁止填值;")] public string PytBPdctCode { get; set; } + + /// + /// 是否为跨境交易 + /// 长度:5 + /// 必填:是 + /// 说明: + /// + [CheckStringInMap(Map = new[] { "true", "false" })] + [DefaultValue("")] + [SacDescription("CrossBorderTransactions", "是否为跨境交易", "5", true, "")] + public string CrossBorderTransactions { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// [XmlIgnore] [DefaultValue("")] - [SacDescription("TradeId", "乙方代签产品代码", "20", false, "校验规则:如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值;")] - public string TradeId { get; set; } - } + [SacDescription("Blank1", "空白1", "", false, "")] + public string Blank1 { get; set; } - /// - /// 交易确认书附件 - /// - public class ConfirmationAttModel - { /// - /// 交易确认书附件 + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: /// - [CheckStringEndsWith(EndsWithString = ".pdf")] + [XmlIgnore] [DefaultValue("")] - [SacDescription("ConfirmationAtt", "交易确认书附件", "", false, "")] - public string ConfirmationAtt { get; set; } + [SacDescription("Blank2", "空白2", "", false, "")] + public string Blank2 { get; set; } + + #region 香草及其组合 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string VanillaOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填;")] + public string VanillaStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及2个执行价时,必填;")] + public string VanillaStrikePriceCoefficientTwo { get; set; } + + /// + /// 行权价格系数3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaStrikePriceCoefficientThree", "行权价格系数3(%)", "5,2", false, "当期权涉及3个执行价时,必填;")] + public string VanillaStrikePriceCoefficientThree { get; set; } + + /// + /// 行权价格系数4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及4个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaStrikePriceCoefficientFour", "行权价格系数4(%)", "5,2", false, "当期权涉及4个执行价时,必填;")] + public string VanillaStrikePriceCoefficientFour { get; set; } + + /// + /// 参与率1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaEngagementRateOne", "参与率1(%)", "5,2", false, "当期权涉及1个参与率时,必填;")] + public string VanillaEngagementRateOne { get; set; } + + /// + /// 参与率2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaEngagementRateTwo", "参与率2(%)", "5,2", false, "当期权涉及2个参与率时,必填;")] + public string VanillaEngagementRateTwo { get; set; } + + /// + /// 参与率3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaEngagementRateThree", "参与率3(%)", "5,2", false, "当期权涉及3个参与率时,必填;")] + public string VanillaEngagementRateThree { get; set; } + + /// + /// 参与率4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及4个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaEngagementRateFour", "参与率4(%)", "5,2", false, "当期权涉及4个参与率时,必填;")] + public string VanillaEngagementRateFour { get; set; } + + /// + /// 封底收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限亏损时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaBackCoverYield", "封底收益率(非年化)(%)", "5,2", false, "当期权涉及有限亏损时,必填;")] + public string VanillaBackCoverYield { get; set; } + + /// + /// 封顶收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限收益时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaCappingYield", "封顶收益率(非年化)(%)", "5,2", false, "当期权涉及有限收益时,必填;")] + public string VanillaCappingYield { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaBlank1", "空白1", "", false, "")] + public string VanillaBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "0", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("VanillaBlank2", "空白2", "", false, "")] + public string VanillaBlank2 { get; set; } + + #endregion + + #region 二元及其组合 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string DigitalOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填;")] + public string DigitalStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及2个执行价时,必填;")] + public string DigitalStrikePriceCoefficientTwo { get; set; } + + /// + /// 行权价格系数3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalStrikePriceCoefficientThree", "行权价格系数3(%)", "5,2", false, "当期权涉及3个执行价时,必填;")] + public string DigitalStrikePriceCoefficientThree { get; set; } + + /// + /// 参与率1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalEngagementRateOne", "参与率1(%)", "5,2", false, "当期权涉及1个参与率时,必填;")] + public string DigitalEngagementRateOne { get; set; } + + /// + /// 参与率2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalEngagementRateTwo", "参与率2(%)", "5,2", false, "当期权涉及2个参与率时,必填;")] + public string DigitalEngagementRateTwo { get; set; } + + /// + /// 参与率3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个参与率时,必填; + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalEngagementRateThree", "参与率3(%)", "5,2", false, "当期权涉及3个参与率时,必填;")] + public string DigitalEngagementRateThree { get; set; } + + /// + /// 收益率1(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以获得的行权收益,当期权涉及1个收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalYieldOneNonAnnualized", "收益率1(非年化)(%)", "5,2", false, "期权买方可以获得的行权收益,当期权涉及1个收益率时,必填;")] + public string DigitalYieldOneNonAnnualized { get; set; } + + /// + /// 收益率2(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalYieldTwoNonAnnualized", "收益率2(非年化)(%)", "5,2", false, "当期权涉及2个收益率时,必填;")] + public string DigitalYieldTwoNonAnnualized { get; set; } + + /// + /// 收益率3(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalYieldThreeNonAnnualized", "收益率3(非年化)(%)", "5,2", false, "当期权涉及3个收益率时,必填;")] + public string DigitalYieldThreeNonAnnualized { get; set; } + + /// + /// 收益率4(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及4个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00, */Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalYieldFourNonAnnualized", "收益率4(非年化)(%)", "5,2", false, "当期权涉及4个收益率时,必填;")] + public string DigitalYieldFourNonAnnualized { get; set; } + + ///// + ///// 最低收益率(年化)(%) + ///// 长度:5,2 + ///// 必填:否 + ///// 说明:期权存在最低保底收益时,必填 + ///// + //[CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + //[CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + //[CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + //[CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + //[DefaultValue("")] + //[SacDescription("DigitalMinimumYieldAnnualized", "最低收益率(年化)(%)", "5,2", false, "期权存在最低保底收益时,必填;")] + //public string DigitalMinimumYieldAnnualized { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalBlank1", "空白1", "", false, "")] + public string DigitalBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "1", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DigitalBlank2", "空白2", "", false, "")] + public string DigitalBlank2 { get; set; } + + #endregion + + #region 障碍及其组合 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string BarrierOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产的价格,当期权涉及1个执行价时,必填;")] + public string BarrierStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及2个执行价时,必填;")] + public string BarrierStrikePriceCoefficientTwo { get; set; } + + /// + /// 参与率1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierEngagementRateOne", "参与率1(%)", "5,2", false, "当期权涉及1个参与率时,必填;")] + public string BarrierEngagementRateOne { get; set; } + + /// + /// 参与率2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierEngagementRateTwo", "参与率2(%)", "5,2", false, "当期权涉及2个参与率时,必填;")] + public string BarrierEngagementRateTwo { get; set; } + + /// + /// 敲入价格系数(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:存在敲入障碍价格时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierKnockInPriceCoefficient", "敲入价格系数(%)", "5,2", false, "存在敲入障碍价格时,必填;")] + public string BarrierKnockInPriceCoefficient { get; set; } + + /// + /// 敲出价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个敲出障碍价格时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierKnockOutPriceCoefficientOne", "敲出价格系数1(%)", "5,2", false, "当期权涉及1个敲出障碍价格时,必填;")] + public string BarrierKnockOutPriceCoefficientOne { get; set; } + + /// + /// 敲出收益率1(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个敲出收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierKnockOutYieldOneNonAnnualized", "敲出收益率1(非年化)(%)", "5,2", false, + "当期权涉及1个敲出收益率时,必填;")] + public string BarrierKnockOutYieldOneNonAnnualized { get; set; } + + /// + /// 敲出价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个敲出障碍价格时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierKnockOutPriceCoefficientTwo", "敲出价格系数2(%)", "5,2", false, "当期权涉及2个敲出障碍价格时,必填;")] + public string BarrierKnockOutPriceCoefficientTwo { get; set; } + + /// + /// 敲出收益率2(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个敲出收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0.00,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierKnockOutYieldTwoNonAnnualized", "敲出收益率2(非年化)(%)", "5,2", false, "当期权涉及2个敲出收益率时,必填;")] + public string BarrierKnockOutYieldTwoNonAnnualized { get; set; } + + /// + /// 观察类型 + /// 长度:2 + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2" }, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierObservationType", "观察类型", "2", false, "")] + public string BarrierObservationType { get; set; } + + /// + /// 封底收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限亏损时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierBackCoverYield", "封底收益率(非年化)(%)", "5,2", false, "当期权涉及有限亏损时,必填;")] + public string BarrierBackCoverYield { get; set; } + + /// + /// 未敲入收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及未敲入收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierUnknockedYield", "未敲入收益率(非年化)(%)", "5,2", false, "当期权涉及未敲入收益率时,必填;")] + public string BarrierUnknockedYield { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierBlank1", "空白1", "", false, "")] + public string BarrierBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "2", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("BarrierBlank2", "空白2", "", false, "")] + public string BarrierBlank2 { get; set; } + + #endregion + + #region 自动赎回 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string AutoCallableOptionStructureSubclass { get; set; } + + /// + /// 参与率(%) + /// 长度:5,2 + /// 必填:是 + /// 说明:当期权涉及1个参与率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0.00, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableEngagementRate", "参与率(%)", "5,2", true, "当期权涉及1个参与率时,必填;")] + public string AutoCallableEngagementRate { get; set; } + + /// + /// 行权价格系数(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:用于计算行权价格;当“期权结构小类”选择“非保本普通型雪球”“非保本要素(敲入、敲出、收益率)可变型雪球”“非保本普通型凤凰”“非保本要素(敲入、敲出、收益率)可变型凤凰”时,必填; + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "2", "3", "4", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "2", "3", "4", "5", "6" }, CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "6" }, CheckHandleNameArr = new[] { "C" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, CheckHandleName = "A")] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "C")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableStrikePriceCoefficient", "行权价格系数(%)", "5,2", false, "用于计算行权价格;\r\n当“期权结构小类”选择“非保本普通型雪球”“非保本要素(敲入、敲出、收益率)可变型雪球”“非保本普通型凤凰”“非保本要素(敲入、敲出、收益率)可变型凤凰”时,必填;")] + public string AutoCallableStrikePriceCoefficient { get; set; } + + /// + /// 敲出价格系数(%) + /// 长度:1024 + /// 必填:是 + /// 说明:正数,保留两位小数;当期权涉及敲出价格系数时,必填,以数组形式提交,半角字符,数组元素以分号隔开,示例:(95.00;90.00;85.00) + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockOutPriceCoefficient", "敲出价格系数(%)", "1024", true, + "当期权涉及敲出价格系数时,必填,以数组形式提交,半角字符,数组元素以分号隔开,示例:(95.00;90.00;85.00);")] + public string AutoCallableKnockOutPriceCoefficient { get; set; } + + /// + /// 敲出收益率(年化)(%) + /// 长度:1024 + /// 必填:是 + /// 说明:合约中既定的收益利率;当标的物触及敲出障碍价时的所得收益将通过该数值计算,以数组形式提交,半角字符,数组元素以分号隔开,示例:(10.00;10.00;10.00) + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockOutYieldAnnualized", "敲出收益率(年化)(%)", "1024", true, + "合约中既定的收益利率;当标的物触及敲出障碍价时的所得收益将通过该数值计算,以数组形式提交,半角字符,数组元素以分号隔开,示例:(10.00;10.00;10.00);")] + public string AutoCallableKnockOutYieldAnnualized { get; set; } + + /// + /// 敲出观察日 + /// 长度:2048 + /// 必填:是 + /// 说明:YYYY-MM-DD;半角字符,以数组形式提交,数组元素以分号隔开;示例:(2023-01-01;2023-02-01;2023-03-01) + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 2048, CheckHandleName = "A")] + // [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockOutObservationDay", "敲出观察日", "2048", true, + "半角字符,以数组形式提交,数组元素以分号隔开;示例:(2023-01-01;2023-02-01;2023-03-01)")] + public string AutoCallableKnockOutObservationDay { get; set; } + + /// + /// 敲出结算日 + /// 长度:2048 + /// 必填:是 + /// 说明:半角字符,以数组形式提交,数组元素以分号隔开;示例:(2023-01-02;2023-02-02;2023-03-02) + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 2048, CheckHandleName = "A")] + // [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockOutSettlementDay", "敲出结算日", "2048", true, + "半角字符,以数组形式提交,数组元素以分号隔开;示例:(2023-01-02;2023-02-02;2023-03-02)")] + public string AutoCallableKnockOutSettlementDay { get; set; } + + /// + /// 敲入价格系数(%) + /// 长度:1024 + /// 必填:否 + /// 说明:当“期权结构小类”选择 “保本雪球(三元)”“非保本普通型雪球”“非保本要素(敲入、敲出、收益率)可变型雪球”“非保本普通型凤凰”“非保本要素(敲入、敲出、收益率)可变型凤凰”或涉及敲入障碍价格时,必填;涉及多个时以数组形式提交,半角字符,数组元素以分号隔开,示例:(95.00;90.00;85.00) + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "1", "2", "3", "4", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "1", "2", "3", "4", "5", "6" }, CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "6" }, CheckHandleNameArr = new[] { "C" })] + [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [CheckStringMaxLength(MaxLength = 1024, Required = false, CheckHandleName = "C")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockInPriceCoefficient", "敲入价格系数(%)", "1024", false, + "当“期权结构小类”选择 “保本雪球(三元)”“非保本普通型雪球”“非保本要素(敲入、敲出、收益率)可变型雪球”“非保本普通型凤凰”“非保本要素(敲入、敲出、收益率)可变型凤凰”或涉及敲入障碍价格时,必填;\r\n涉及多个时以数组形式提交,半角字符,数组元素以分号隔开,示例:(95.00;90.00;85.00)")] + public string AutoCallableKnockInPriceCoefficient { get; set; } + + /// + /// 敲入观察日 + /// 长度:1024 + /// 必填:否 + /// 说明:当期权涉及到多个敲入价格系数(%)时,必填;半角字符,以时间区间的数组形式提交,数组元素以分号隔开,示例:(2023-01-01:2023-12-31;2024-01-01:2024-12-31;2025-01-01:2025-12-31); + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 1024, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableKnockInObservationDay", "敲入观察日", "1024", false, + "当期权涉及到多个敲入价格系数(%)时,必填;\r\n半角字符,以时间区间的数组形式提交,数组元素以分号隔开,示例:(2023-01-01:2023-12-31;2024-01-01:2024-12-31;2025-01-01:2025-12-31);")] + public string AutoCallableKnockInObservationDay { get; set; } + + /// + /// 红利收益率(年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当"期权结构小类"选择"保本雪球(二元)"或"保本雪球(三元)"时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "0", "1" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "0", "1" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, IgnoreNullOrEmpty = false, + CheckHandleName = "A")] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, + CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableDividendYieldAnnualized", "红利收益率(年化)(%)", "5,2", false, + "当\"期权结构小类\"选择\"保本雪球(二元)\"或\"保本雪球(三元)\"时,必填;")] + public string AutoCallableDividendYieldAnnualized { get; set; } + + /// + /// 最低收益率(年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当“期权结构小类”选择“保本雪球(三元)”时,必填;当“是否为FCN型”字段选择“是”时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "1" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableWhetherFixedCouponNote), + ConditionMap = new[] { "0" }, CheckHandleNameArr = new[] { "C" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "1" }, CheckHandleNameArr = new[] { "B" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableWhetherFixedCouponNote), + ConditionMap = new[] { "0" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, IgnoreNullOrEmpty = false, + CheckHandleName = "A")] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, IgnoreNullOrEmpty = false, + CheckHandleName = "C")] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, IgnoreNullOrEmpty = false, + Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableMinimumYieldAnnualized", "最低收益率(年化)(%)", "5,2", false, + "当“期权结构小类”选择“保本雪球(三元)”时,必填;\r\n当“是否为FCN型”字段选择“是”时,必填;")] + public string AutoCallableMinimumYieldAnnualized { get; set; } + + /// + /// 最低本金保障比例(%) + /// 长度:5,2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableMinimumPrincipalProtectionRatio", "最低本金保障比例(%)", "5,2", true, "")] + public string AutoCallableMinimumPrincipalProtectionRatio { get; set; } + + /// + /// 是否为折价建仓型 + /// 长度:2 + /// 必填:是 + /// 说明:当期权涉及到敲入后转线性结构的情形时,填"是" + /// + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false)] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherDiscountedWarehouseType", "是否为折价建仓型", "2", true, + "当期权涉及到敲入后转线性结构的情形时,填\"是\"")] + public string AutoCallableWhetherDiscountedWarehouseType { get; set; } + + /// + /// 是否为收益增强型 + /// 长度:2 + /// 必填:是 + /// 说明:当期权涉及到敲出时收益增强的情形时,填"是" + /// + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false)] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherRevenueEnhancedType", "是否为收益增强型", "2", true, "当期权涉及到敲出时收益增强的情形时,填\"是\"")] + public string AutoCallableWhetherRevenueEnhancedType { get; set; } + + /// + /// 是否为FCN型 + /// 长度:2 + /// 必填:是 + /// 说明:当期权为FCN结构时,填“是” + /// + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false)] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherFixedCouponNote", "是否为FCN型", "2", true, "当期权为FCN结构时,填“是”")] + public string AutoCallableWhetherFixedCouponNote { get; set; } + + /// + /// 敲入价格系数是否可变 + /// 长度:2 + /// 必填:否 + /// 说明:当"期权结构小类"选择"非保本要素(敲入、敲出、收益率)可变型雪球"或"非保本要素(敲入、敲出、收益率)可变型凤凰"时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherKnockInPriceCoefficientIsVariable", "敲入价格系数是否可变", "2", false, + "当\"期权结构小类\"选择\"非保本要素(敲入、敲出、收益率)可变型雪球\"或\"非保本要素(敲入、敲出、收益率)可变型凤凰\"时,必填;")] + public string AutoCallableWhetherKnockInPriceCoefficientIsVariable { get; set; } + + /// + /// 敲出价格系数是否可变 + /// 长度:2 + /// 必填:否 + /// 说明:当"期权结构小类"选择"非保本要素(敲入、敲出、收益率)可变型雪球"或"非保本要素(敲入、敲出、收益率)可变型凤凰"时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherKnockOutPriceCoefficientIsVariable", "敲出价格系数是否可变", "2", false, + "当\"期权结构小类\"选择\"非保本要素(敲入、敲出、收益率)可变型雪球\"或\"非保本要素(敲入、敲出、收益率)可变型凤凰\"时,必填;")] + public string AutoCallableWhetherKnockOutPriceCoefficientIsVariable { get; set; } + + /// + /// 敲出收益率是否可变 + /// 长度:2 + /// 必填:否 + /// 说明:当"期权结构小类"选择"非保本要素(敲入、敲出、收益率)可变型雪球"或"非保本要素(敲入、敲出、收益率)可变型凤凰"时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherKnockOutYieldIsVariable", "敲出收益率是否可变", "2", false, + "当\"期权结构小类\"选择\"非保本要素(敲入、敲出、收益率)可变型雪球\"或\"非保本要素(敲入、敲出、收益率)可变型凤凰\"时,必填;")] + public string AutoCallableWhetherKnockOutYieldIsVariable { get; set; } + + /// + /// 红利收益率是否可变 + /// 长度:2 + /// 必填:否 + /// 说明:当"期权结构小类"选择"非保本要素(敲入、敲出、收益率)可变型雪球"或"非保本要素(敲入、敲出、收益率)可变型凤凰"时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(AutoCallableOptionStructureSubclass), + ConditionMap = new[] { "3", "5" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1" }, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableWhetherDividendYieldIsVariable", "红利收益率是否可变", "2", false, + "当\"期权结构小类\"选择\"非保本要素(敲入、敲出、收益率)可变型雪球\"或\"非保本要素(敲入、敲出、收益率)可变型凤凰\"时,必填;")] + public string AutoCallableWhetherDividendYieldIsVariable { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableBlank1", "空白1", "", false, "")] + public string AutoCallableBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "3", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AutoCallableBlank2", "空白2", "", false, "")] + public string AutoCallableBlank2 { get; set; } + + #endregion + + #region 区间累计 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string RangeAccrualOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填;")] + public string RangeAccrualStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及到2个执行价时,必填;")] + public string RangeAccrualStrikePriceCoefficientTwo { get; set; } + + /// + /// 行权价格系数3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到3个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualStrikePriceCoefficientThree", "行权价格系数3(%)", "5,2", false, "当期权涉及到3个执行价时,必填;")] + public string RangeAccrualStrikePriceCoefficientThree { get; set; } + + /// + /// 行权价格系数4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到4个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualStrikePriceCoefficientFour", "行权价格系数4(%)", "5,2", false, "当期权涉及到4个执行价时,必填;")] + public string RangeAccrualStrikePriceCoefficientFour { get; set; } + + /// + /// 参与率(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到1个参与率时,必须为正数;每份合约中参与率的大小决定了实际名义本金的数额 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualEngagementRate", "参与率(%)", "5,2", false, + "当期权涉及到1个参与率时,必须为正数;\r\n每份合约中参与率的大小决定了实际名义本金的数额;")] + public string RangeAccrualEngagementRate { get; set; } + + /// + /// 收益率1(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以获得的行权收益,当期权涉及到1个收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualOneNonAnnualized", "收益率1(非年化)(%)", "5,2", false, + "期权买方可以获得的行权收益,当期权涉及到1个收益率时,必填;")] + public string RangeAccrualOneNonAnnualized { get; set; } + + /// + /// 收益率2(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualTwoNonAnnualized", "收益率2(非年化)(%)", "5,2", false, "当期权涉及到2个收益率时,必填;")] + public string RangeAccrualTwoNonAnnualized { get; set; } + + /// + /// 收益率3(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualThreeNonAnnualized", "收益率3(非年化)(%)", "5,2", false, "当期权涉及到3个收益率时,必填;")] + public string RangeAccrualThreeNonAnnualized { get; set; } + + /// + /// 收益率4(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个收益率时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, /*MinValue = 0,*/ Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualFourNonAnnualized", "收益率4(非年化)(%)", "5,2", false, "当期权涉及到4个收益率时,必填;")] + public string RangeAccrualFourNonAnnualized { get; set; } + + ///// + ///// 最低收益率(年化)(%) + ///// 长度:5,2 + ///// 必填:否 + ///// 说明:期权存在最低保底收益时,必填;无论标的合约价格如何变动,投资者可以获得的最低收益 + ///// + //[CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + //[CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + //[CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + //[CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + //[DefaultValue("")] + //[SacDescription("RangeAccrualMinimumYieldAnnualized", "最低收益率(年化)(%)", "5,2", false, + // "期权存在最低保底收益时,必填;无论标的合约价格如何变动,投资者可以获得的最低收益;")] + //public string RangeAccrualMinimumYieldAnnualized { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualBlank1", "空白1", "", false, "")] + public string RangeAccrualBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "4", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("RangeAccrualBlank2", "空白2", "", false, "")] + public string RangeAccrualBlank2 { get; set; } + + #endregion + + #region 安全气囊 + + /// + /// 期权结构小类 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagOptionStructureSubclass", "期权结构小类", "2", true, "")] + public string AirbagOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填;")] + public string AirbagStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及到2个执行价时,必填;")] + public string AirbagStrikePriceCoefficientTwo { get; set; } + + /// + /// 行权价格系数3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到3个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagStrikePriceCoefficientThree", "行权价格系数3(%)", "5,2", false, "当期权涉及到3个执行价时,必填;")] + public string AirbagStrikePriceCoefficientThree { get; set; } + + /// + /// 行权价格系数4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到4个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagStrikePriceCoefficientFour", "行权价格系数4(%)", "5,2", false, "当期权涉及到4个执行价时,必填;")] + public string AirbagStrikePriceCoefficientFour { get; set; } + + /// + /// 参与率1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagEngagementRateOne", "参与率1(%)", "5,2", false, "当期权涉及1个参与率时,必须为正数;")] + public string AirbagEngagementRateOne { get; set; } + + /// + /// 参与率2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagEngagementRateTwo", "参与率2(%)", "5,2", false, "当期权涉及2个参与率时,必须为正数;")] + public string AirbagEngagementRateTwo { get; set; } + + /// + /// 参与率3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagEngagementRateThree", "参与率3(%)", "5,2", false, "当期权涉及3个参与率时,必须为正数;")] + public string AirbagEngagementRateThree { get; set; } + + /// + /// 敲入价格系数(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:存在敲入障碍价格时,必填,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagKnockInPriceCoefficient", "敲入价格系数(%)", "5,2", false, "存在敲入障碍价格时,必填,必须为正数;")] + public string AirbagKnockInPriceCoefficient { get; set; } + + ///// + ///// 上端封顶收益率(非年化)(%) + ///// 长度:5,2 + ///// 必填:否 + ///// 说明:上端封顶类安全气囊类期权,必填 + ///// + //[CheckConditionStringInMap(ConditionName = nameof(AirbagOptionStructureSubclass), + // ConditionMap = new[] { "4" }, CheckHandleNameArr = new[] { "A" })] + //[CheckConditionStringNotInMap(ConditionName = nameof(AirbagOptionStructureSubclass), + // ConditionMap = new[] { "4" }, CheckHandleNameArr = new[] { "B" })] + //[CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, CheckHandleName = "A")] + //[CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + //[DefaultValue("")] + //[SacDescription("AirbagTopCapYieldAnnualized", "上端封顶收益率(非年化)(%)", "5,2", false, "上端封顶类安全气囊类期权,必填;")] + //public string AirbagTopCapYieldAnnualized { get; set; } + + ///// + ///// 最低收益率(年化)(%) + ///// 长度:5,2 + ///// 必填:否 + ///// 说明:期权存在最低保底收益时,必填 + ///// + //[CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + //[CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + //[CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + //[CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + //[DefaultValue("")] + //[SacDescription("AirbagMinimumYieldAnnualized", "最低收益率(年化)(%)", "5,2", false, "期权存在最低保底收益时,必填;")] + //public string AirbagMinimumYieldAnnualized { get; set; } + + /// + /// 封底收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限亏损时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagBackCoverYield", "封底收益率(非年化)(%)", "5,2", false, "当期权涉及有限亏损时,必填;")] + public string AirbagBackCoverYield { get; set; } + + /// + /// 封顶收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限收益时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagCappingYield", "封顶收益率(非年化)(%)", "5,2", false, "当期权涉及有限收益时,必填;")] + public string AirbagCappingYield { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagBlank1", "空白1", "", false, "")] + public string AirbagBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "5", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("AirbagBlank2", "空白2", "", false, "")] + public string AirbagBlank2 { get; set; } + + #endregion + + #region 其他 + + /// + /// 期权结构类型 + /// 长度:1024 + /// 必填:是 + /// 说明:必填,请以文字形式描述期权结构类型名称 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersOptionStructureSubclass", "期权结构类型", "1024", true, "必填,请以文字形式描述期权结构类型名称;")] + public string OthersOptionStructureSubclass { get; set; } + + /// + /// 行权价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersStrikePriceCoefficientOne", "行权价格系数1(%)", "5,2", false, + "期权买方可以买入或卖出标的资产价格,当期权涉及到1个执行价时,必填;")] + public string OthersStrikePriceCoefficientOne { get; set; } + + /// + /// 行权价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersStrikePriceCoefficientTwo", "行权价格系数2(%)", "5,2", false, "当期权涉及到2个执行价时,必填;")] + public string OthersStrikePriceCoefficientTwo { get; set; } + + /// + /// 行权价格系数3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到3个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersStrikePriceCoefficientThree", "行权价格系数3(%)", "5,2", false, "当期权涉及到3个执行价时,必填;")] + public string OthersStrikePriceCoefficientThree { get; set; } + + /// + /// 行权价格系数4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到4个执行价时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersStrikePriceCoefficientFour", "行权价格系数4(%)", "5,2", false, "当期权涉及到4个执行价时,必填;")] + public string OthersStrikePriceCoefficientFour { get; set; } + + /// + /// 参与率1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及1个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersEngagementRateOne", "参与率1(%)", "5,2", false, "当期权涉及1个参与率时,必须为正数;")] + public string OthersEngagementRateOne { get; set; } + + /// + /// 参与率2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及2个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersEngagementRateTwo", "参与率2(%)", "5,2", false, "当期权涉及2个参与率时,必须为正数;")] + public string OthersEngagementRateTwo { get; set; } + + /// + /// 参与率3(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及3个参与率时,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersEngagementRateThree", "参与率3(%)", "5,2", false, "当期权涉及3个参与率时,必须为正数;")] + public string OthersEngagementRateThree { get; set; } + + /// + /// 参与率4(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及4个参与率时,必填,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersEngagementRateFour", "参与率4(%)", "5,2", false, "当期权涉及4个参与率时,必填,必须为正数;")] + public string OthersEngagementRateFour { get; set; } + + /// + /// 障碍价格系数1(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到1个障碍价格时,必填,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersBarrierPricesCoefficientOne", "障碍价格系数1(%)", "5,2", false, "当期权涉及到1个障碍价格时,必填,必须为正数;")] + public string OthersBarrierPricesCoefficientOne { get; set; } + + /// + /// 障碍价格系数2(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及到2个障碍价格时,必填,必须为正数 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersBarrierPricesCoefficientTwo", "障碍价格系数2(%)", "5,2", false, "当期权涉及到2个障碍价格时,必填,必须为正数;")] + public string OthersBarrierPricesCoefficientTwo { get; set; } + + /// + /// 封底收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限亏损时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersBackCoverYield", "封底收益率(非年化)(%)", "5,2", false, "当期权涉及有限亏损时,必填")] + public string OthersBackCoverYield { get; set; } + + /// + /// 封顶收益率(非年化)(%) + /// 长度:5,2 + /// 必填:否 + /// 说明:当期权涉及有限收益时,必填 + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 5, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersCappingYield", "封顶收益率(非年化)(%)", "5,2", false, "当期权涉及有限收益时,必填")] + public string OthersCappingYield { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersBlank1", "空白1", "", false, "")] + public string OthersBlank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [CheckConditionStringValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "OptionStructureType", ConditionValue = "99", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 9999, Required = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OthersBlank2", "空白2", "", false, "")] + public string OthersBlank2 { get; set; } + + #endregion } - /// - /// 标的详情 - /// - public class UndrlygAssetModel + // + // 标的详情 + // + [Table("A1004_UndrlygAsset")] + public class UndrlygAssetModel : ReportSubBaseModel { /// /// 标的小类 /// 长度:2 /// 必填:是 - /// 说明: + /// 说明: /// - [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "99" })] + [CheckStringInMap(Map = new[] + { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", + "99" + })] [DefaultValue("")] [SacDescription("UndrlygAssetDtldType", "标的小类", "2", true, "")] public string UndrlygAssetDtldType { get; set; } /// - /// 挂钩标的名称 + /// 标的名称 /// 长度:200 /// 必填:是 /// 说明: /// [CheckStringMaxLength(MaxLength = 200)] [DefaultValue("")] - [SacDescription("UndrlygAssetName", "挂钩标的名称", "200", true, "")] + [SacDescription("UndrlygAssetName", "标的名称", "200", true, "")] public string UndrlygAssetName { get; set; } /// /// 标的交易场所 /// 长度:2 /// 必填:是 - /// 说明: + ///// 说明: /// - [CheckStringInMap(Map = new[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "99" })] + //[CheckStringInMap(Map = new[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "99" })] + [CheckStringMaxLength(MaxLength = 200)] [DefaultValue("")] - [SacDescription("UndrlygAssetTradgPlc", "标的交易场所", "2", true, "")] + [SacDescription("UndrlygAssetTradgPlc", "标的交易场所", "200", true, "")] public string UndrlygAssetTradgPlc { get; set; } /// - /// 标的代码 - /// 长度:32 + /// 标的编码 + /// 长度:200 /// 必填:是 /// 说明: /// - [CheckStringMaxLength(MaxLength = 32)] + [CheckStringMaxLength(MaxLength = 200)] [DefaultValue("")] - [SacDescription("UndrlygAssetCode", "标的代码", "32", true, "")] + [SacDescription("UndrlygAssetCode", "标的编码", "200", true, "")] public string UndrlygAssetCode { get; set; } /// /// 标的数量 + /// 长度:36,6 + /// 必填:是 + /// 说明:校验规则:六位小数且大于0 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 6)] + [DefaultValue("")] + [SacDescription("UndrlygAssetAmt", "标的数量", "36,6", true, "校验规则:六位小数且大于0;")] + public string UndrlygAssetAmt { get; set; } + + /// + /// 合约乘数 + /// 长度:36,6 + /// 必填:是 + /// 说明:校验规则:整数 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 0)] + [DefaultValue("")] + [SacDescription("ContractMultiplier", "合约乘数", "36", true, "校验规则:整数;")] + public string ContractMultiplier { get; set; } + + /// + /// 标的个数 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [CheckStringInMap(Map = new[] { "0", "1" })] + [DefaultValue("")] + [SacDescription("UndrlygAssetNo", "标的个数", "2", true, "")] + public string UndrlygAssetNo { get; set; } + + /// + /// 多标的期权类型 /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:必须两位小数以内; + /// 说明:多标的期权必填; /// - [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] + [CheckConditionStringValue(ConditionName = "UndrlygAssetNo", ConditionValue = "1", + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = "UndrlygAssetNo", ConditionValue = "1", + CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 2, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("UndrlygAssetAmt", "标的数量", "36,2", false, "校验规则:必须两位小数以内;")] - public string UndrlygAssetAmt { get; set; } + [SacDescription("MultiOrderOptionType", "多标的期权类型", "2", false, "多标的期权必填;")] + public string MultiOrderOptionType { get; set; } + + /// + /// 标的名义本金(元) + /// 长度:36,2 + /// 必填:是 + /// 说明:包含多个标的的期权交易,每个标的须填写一份标的详情表 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("UndrlygAssetNotinalPrincipleAmtRMB", "标的名义本金(元)", "36,2", true, "包含多个标的的期权交易,每个标的须填写一份标的详情表")] + public string UndrlygAssetNotinalPrincipleAmtRMB { get; set; } + + /// + /// 标的价格 + /// 长度:36,4 + /// 必填:是 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 4)] + [DefaultValue("")] + [SacDescription("OpeningPrice", "标的价格", "36,4", true, "")] + public string OpeningPrice { get; set; } + + /// + /// 标的类型 + /// 长度:2 + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("UndrlygAssetType", "标的类型", "2", false, "")] + public string UndrlygAssetType { get; set; } + + /// + /// 标的价格货币 + /// 长度:2 + /// 必填:否 + /// 说明:当“标的类型”选择“权益类”“大宗商品”“利率”“信用类”“其他”时,必填 + /// + [CheckConditionStringInMap(ConditionName = nameof(UndrlygAssetType), + ConditionMap = new[] { "0", "1", "2", "3", "99" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(UndrlygAssetType), + ConditionMap = new[] { "0", "1", "2", "3", "99" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 2, IgnoreNullOrEmpty = false, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("OpeningPriceCurrency", "标的价格货币", "2", false, "当标的类型选择权益类、大宗商品、利率、信用类、其他时,必填")] + public string OpeningPriceCurrency { get; set; } + + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "关联交易确认书编号", "32", false, "")] + public string ConfirmationNo { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank1", "空白1", "", false, "")] + public string Blank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank2", "空白2", "", false, "")] + public string Blank2 { get; set; } + + } - /// - /// 履约担保品详情 - /// - public class PerformanceGuaranteeAttModel + // + // 履约担保品详情 + // + [Table("A1004_PerformanceGuaranteeAtt")] + public class PerformanceGuaranteeAttModel : ReportSubBaseModel { /// /// 履约担保品类型 /// 长度:2 /// 必填:否 - /// 说明:校验规则:当履约保障类型()选择部分担保或全额担保时必填; - /// 说明: + /// 说明:校验规则:当“履约担保类型”选择部分担保、全额担保时,必填; /// - [CheckStringInMap(Map = new[] { "0", "1", "99" })] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "99" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollType", "履约担保品类型", "2", false, "校验规则:当履约保障类型选择部分担保或全额担保时必填;")] + [SacDescription("PerformanceCollType", "履约担保品类型", "2", false, "校验规则:当“履约担保类型”选择部分担保、全额担保时,必填;")] public string PerformanceCollType { get; set; } + + /// + /// 履约担保类型 + /// 长度:2 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [CheckStringInMap(Map = new[] { "1", "2", "3" })] + [DefaultValue("")] + [SacDescription("PerformanceGuaranteeType", "履约担保类型", "2", true, "")] + public string PerformanceGuaranteeType { get; set; } + /// /// 担保品担保范围 /// 长度:2 /// 必填:否 - /// 说明: + /// 说明:校验规则:当“履约担保类型”选择部分担保、全额担保时,必填; /// - [CheckStringInMap(Map = new[] { "0", "1", "2" }, Required = false)] + [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, + CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), + ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2" }, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollRange", "担保品担保范围", "2", false, "")] + [SacDescription("PerformanceCollRange", "担保品担保范围", "2", false, "校验规则:当“履约担保类型”选择部分担保、全额担保时,必填;")] public string PerformanceCollRange { get; set; } /// /// 多笔担保交易确认书编号 @@ -660,5 +2505,23 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("MultiConfirmationID", "多笔担保交易确认书编号", "1024", false, "")] public string MultiConfirmationID { get; set; } + + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "关联交易确认书编号", "32", false, "")] + public string ConfirmationNo { get; set; } + + /// + /// 备注 + /// 长度:1024 + /// 必填:否 + /// 说明: + /// + [CheckStringMaxLength(MaxLength = 1024, Required = false)] + [DefaultValue("")] + [SacDescription("Remarks", "备注", "", false, "")] + public string Remarks { get; set; } } + + } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionTerminationModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionTerminationModel.cs index 01346e46..4fdf7652 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionTerminationModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OptionTerminationModel.cs @@ -1,10 +1,18 @@ -using System.ComponentModel; +using Newtonsoft.Json; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; namespace YLErp.Modules.SuperviseReportModule.SAC.Model { + + /// + /// 了结确认书 + /// + [Table("A1007_OptionTermination")] public class OptionTerminationModel : ReportBaseModel { /// @@ -30,6 +38,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("BizID", "业务编号", "50", false, "校验规则:补正时必填;")] public new string BizID { get; set; } /// + /// 操作事件编号 + /// 长度:6 + /// 必填:是 + /// + /// 说明:存续期发生相关事件时,必填; + /// 同一笔交易确认书下应当保证唯一性,并按照事件发生顺序进行编号,起始编号为0000. + /// 如一笔交易下依次发生展期\调仓\终止事件,编号应当分别为0000\0001\0002, + /// 场外业务报告系统返回编号分别为E0000\R0001\T0002 + /// + /// + [CheckStringLengthInMap(Map = new[] { 4, 5 })] + [DefaultValue("")] + [SacDescription("DurationEventNO", "操作事件编号", "6", true, "存续期发生相关事件时,必填;\r\n同一笔交易确认书下应当保证唯一性,并按照事件发生顺序进行编号,起始编号为0000.\r\n如一笔交易下依次发生展期、调仓、终止事件,编号应当分别为0000、0001、0002,\r\n场外业务报告系统返回编号分别为E0000、R0001、T0002;")] + public new string DurationEventNO { get; set; } + /// /// 交易确认书编号(双方约定) /// 长度:100 /// 必填:是 @@ -37,53 +60,37 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringMaxLength(MaxLength = 100)] [DefaultValue("")] - [SacDescription("ConfirmationNo", "交易确认书编号", "100", true, "双方约定;")] + [SacDescription("ConfirmationNo", "交易确认书编号(双方约定)", "100", true, "双方约定;")] public string ConfirmationNo { get; set; } /// - /// 终止日期 + /// 存续期操作类型 + /// 长度:2 + /// 必填:是 + /// 说明:敲入、敲出只限于自动赎回、安全气囊、障碍及其组合类期权填写 + /// + [CheckStringInMap(Map = new[] { "01", "02", "03", "05", "06" })] + [DefaultValue("")] + [SacDescription("DurationOperationType", "存续期操作类型", "2", true, "敲入、敲出只限于自动赎回、安全气囊、障碍及其组合类期权填写")] + public string DurationOperationType { get; set; } + /// + /// 操作发生日期 /// 长度:10 /// 必填:是 - /// 说明:校验规则:1 当存续期操作类型,选择终止\违约终止时必填;2 必须是yyyy-MM-dd;3 不存在展期数据:不得等于晚于原合约到期日;4 存在展期数据:不得等于晚于最新展期日期;5 新增终止:一个日期只能存在一条终止数据; + /// 说明:分别为“确定进行展期日期”“合约终止日期”“交易发生违约日期”“发生敲入事件日期”“发生敲出事件日期” /// - [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringMaxLength(MaxLength = 10, CheckHandleName = "A")] - [CheckStringIsDateTimeFormat(CheckHandleName = "A")] - [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] + // [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] + // [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 10)] + [CheckStringIsDateTimeFormat()] + // [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("ExpirationDate", "终止日期", "10", true, "校验规则:\r\n1 当存续期操作类型,选择终止、违约终止时必填;\r\n2 必须是yyyy-MM-dd;\r\n3 不存在展期数据:不得等于晚于原合约到期日;\r\n4 存在展期数据:不得等于晚于最新展期日期;\r\n5 新增终止:一个日期只能存在一条终止数据;")] + [SacDescription("ExpirationDate", "操作发生日期", "10", true, "分别为“确定进行展期日期”“合约终止日期”“交易发生违约日期”“发生敲入事件日期”“发生敲出事件日期”")] public string ExpirationDate { get; set; } /// - /// 违约方 - /// 长度:2 - /// 必填:否 - /// 说明: 校验规则:存续期操作类型为违约终止时必填; - /// - [CheckConditionStringValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNEQValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "B" })] - [CheckStringInMap(Map = new[] { "01", "02" }, CheckHandleName = "A")] - [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] - [DefaultValue("")] - [SacDescription("DefaultingParty", "违约方", "2", false, "校验规则:存续期操作类型为违约终止时必填;")] - public string DefaultingParty { get; set; } - /// - /// 违约事件说明 - /// 长度:1024 - /// 必填:否 - /// 说明:校验规则:存续期操作类型为违约终止时必填; - /// - [CheckConditionStringValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNEQValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "B" })] - [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] - [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] - [DefaultValue("")] - [SacDescription("DefaultEvent", "违约事件说明", "1024", false, "校验规则:存续期操作类型为违约终止时必填;")] - public string DefaultEvent { get; set; } - /// - /// 展期日期 + /// 展期后到期日 /// 长度:10 /// 必填:否 - /// 说明:校验规则:1 存续期操作类型为展期时必填;2 必须是yyyy-MM-dd;3 不存在展期数据:不得早于等于原合约到期日;4 存在展期数据:不得早于等于最新展期日期;5 新增终止:一个日期只能存在一条终止数据; + /// 说明:当“存续期操作类型”为“展期”时,必填;不存在展期操作数据,不得早于原合约到期日;存在展期操作数据,不得早于最近一次展期数据的“展期后到期日” /// [CheckConditionStringValue(ConditionName = nameof(DurationOperationType), ConditionValue = "01", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(DurationOperationType), ConditionValue = "01", CheckHandleNameArr = new[] { "B" })] @@ -91,57 +98,120 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringIsDateTimeFormat(CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("RenewalDate", "展期日期", "10", false, "校验规则:\r\n1 存续期操作类型为展期时必填;\r\n2 必须是yyyy-MM-dd;\r\n3 不存在展期数据:不得早于等于原合约到期日;\r\n4 存在展期数据:不得早于等于最新展期日期;\r\n5 新增终止:一个日期只能存在一条终止数据;")] + [SacDescription("RenewalDate", "展期后到期日", "10", false, "当“存续期操作类型”为“展期”时,必填;不存在展期操作数据,不得早于原合约到期日;存在展期操作数据,不得早于最近一次展期数据的“展期后到期日”")] public string RenewalDate { get; set; } /// - /// 存续期操作类型 + /// 违约方 /// 长度:2 - /// 必填:是 - /// 说明: - /// - [CheckStringInMap(Map = new[] { "01", "02", "03" })] - [DefaultValue("")] - [SacDescription("DurationOperationType", "存续期操作类型", "2", true, "")] - public string DurationOperationType { get; set; } - /// - /// 本次终止金额 - /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:1 当存续期操作类型,选择终止\违约终止时必填;2 保留两位小数;3 TODO 选展期时,该字段不能填,否则报送失败.4 大于0且小于等于上次余额; + /// 说明:当"存续期操作类型"为"违约终止"时,必填 /// - [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] - [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 34, MinValue = 0.01, CheckHandleName = "A")] + [CheckConditionStringValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1" }, CheckHandleName = "A")] [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("TerminationAmount", "本次终止金额", "36,2", false, "校验规则:\r\n1 当存续期操作类型,选择终止、违约终止时必填;\r\n2 保留两位小数;\r\n3 TODO 选展期时,该字段不能填,否则报送失败.4 大于0且小于等于上次余额;")] + [SacDescription("DefaultingParty", "违约方", "2", false, "当存续期操作类型为违约终止时,必填;")] + public string DefaultingParty { get; set; } + /// + /// 违约事件说明 + /// 长度:1024 + /// 必填:否 + /// 说明:当"存续期操作类型"为"违约终止"时,必填 + /// + [CheckConditionStringValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(DurationOperationType), ConditionValue = "03", CheckHandleNameArr = new[] { "B" })] + [CheckStringMaxLength(MaxLength = 1024, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("DefaultEvent", "违约事件说明", "1024", false, "当存续期操作类型为违约终止时,必填;")] + public string DefaultEvent { get; set; } + /// + /// 名义本金变动(元) + /// 长度:36,2 + /// 必填:否 + /// 说明:当"存续期操作类型"选择"终止""违约终止"时,必填,数值必须为负数 + /// + [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, MaxValue = 0, CheckHandleName = "A")] + [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("TerminationAmount", "名义本金变动(元)", "36,2", false, "当存续期操作类型选择终止、违约终止时,必填,数值必须为负数;")] public string TerminationAmount { get; set; } /// - /// 余额 + /// 存量名义本金(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:1 保留两位小数;2 值等于该交易上次余额-本次终止金额; + /// 说明:大于等于 0 的数字 /// - [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 34, MinValue = 0)] + [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 36, MinValue = 0)] [DefaultValue("")] - [SacDescription("Balance", "余额", "36,2", true, "校验规则:\r\n1 保留两位小数;\r\n2 值等于该交易上次余额-本次终止金额;")] + [SacDescription("Balance", "存量名义本金(元)", "36,2", true, "大于等于 0 的数字")] public string Balance { get; set; } /// - /// 本次支付金额 + /// 本次支付金额(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:1 当存续期操作类型,选择终止\违约终止时必填;2 保留两位小数;3 TODO 选展期时,该字段不能填,否则报送失败; + /// 说明:校验规则:1 当存续期操作类型,选择终止\违约终止时必填;2 支付为正,收取为负 /// [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 34, CheckHandleName = "A")] - [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] + [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 36, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("AmountPaidThisTime", "本次支付金额", "36,2", false, "校验规则:\r\n1 当存续期操作类型,选择终止、违约终止时必填;\r\n2 保留两位小数;\r\n3 TODO 选展期时,该字段不能填,否则报送失败;")] + [SacDescription("AmountPaidThisTime", "本次支付金额(元)", "36,2", false, "校验规则:\r\n1 当存续期操作类型,选择终止、违约终止时必填;\r\n2 支付为正,收取为负;")] public string AmountPaidThisTime { get; set; } + /// + /// 已了结交易实际收益率(%) + /// 长度:8,2 + /// 必填:否 + /// 说明:当“存续期操作类型”选择“终止”“违约终止”时,必填; + /// + [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new string[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] + [CheckStringIntLength(AfterPointLength = 2, BeforePointMaxLength = 8, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 0, Required = false, CheckHandleName = "B")] + [DefaultValue("")] + [SacDescription("ClosedTransactionsRealRateReturn", "已了结交易实际收益率(%)", "8,2", false, "当“存续期操作类型”选择“终止”“违约终止”时,必填;")] + public string ClosedTransactionsRealRateReturn { get; set; } + /// + /// 存续期信息附件 + /// 长度: + /// 必填:否 + /// 说明:校验规则:只支持 PDF 格式 + /// + [CheckStringEndsWith(EndsWithString = ".pdf", Required = false)] + [DefaultValue("")] + [SacDescription("OptionDurationManagementAtt", "存续期信息附件", "", false, "校验规则:只支持 PDF 格式")] + public string OptionDurationManagementAtt { get; set; } + /// + /// 障碍事件状态 + /// 长度:2 + /// 必填:否 + /// 说明:根据存续期操作类型中 05 敲入、06 敲出的填写情况,由系统自动取值,填报方无需填写报送 + /// + [CheckStringMaxLength(MaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("BarrierEventStatus", "障碍事件状态", "2", false, "根据存续期操作类型中 05 敲入、06 敲出的填写情况,由系统自动取值,填报方无需填写报送")] + public string BarrierEventStatus { get; set; } [XmlIgnore] [DefaultValue("")] [SacDescription("TradeId", "本次支付金额", "36,2", false, "校验规则:\r\n1 当存续期操作类型,选择终止、违约终止时必填;\r\n2 保留两位小数;\r\n3 TODO 选展期时,该字段不能填,否则报送失败;")] public string TradeId { get; set; } + /// + /// 空白1 + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank1", "空白1", "", false, "")] + public string Blank1 { get; set; } + /// + /// 空白2 + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank2", "空白2", "", false, "")] + public string Blank2 { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OtherReportModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OtherReportModel.cs index 1ccaa8ae..adc8e1ec 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OtherReportModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/OtherReportModel.cs @@ -50,7 +50,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("Telephone", "手机", "11", true, "校验规则:手机号")] public string Telephone { get; set; } /// - /// 固定电话 + /// 手机 /// 长度:200 /// 必填:否 /// 说明: diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PerformanceGuaranteeAgrmtModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PerformanceGuaranteeAgrmtModel.cs index ec31aea3..5f2a8fe3 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PerformanceGuaranteeAgrmtModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PerformanceGuaranteeAgrmtModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +9,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 履约保证书 /// + [Table("A1008_PerformanceGuaranteeAgrmt")] public class PerformanceGuaranteeAgrmtModel : ReportBaseModel { /// @@ -72,7 +74,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] [DefaultValue("")] - [SacDescription("SigningDate", "签署时间", "10", true, "校验规则:必须是yyyy-MM-dd;")] + [SacDescription("SigningDate", "签署时间", "10", true, "校验规则:必须是YYYY-MM-DD;")] public string SigningDate { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportISDAModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportISDAModel.cs index 8e8225e3..ecf049b8 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportISDAModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportISDAModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -683,55 +684,55 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 上月末收益互换存量交易对应履约担保品价值(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:保留四位小数; + /// 说明:校验规则:保留两位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth", "上月末收益互换存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留四位小数;")] + [SacDescription("TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth", "上月末收益互换存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth { get; set; } /// /// 本月末收益互换现金担保物价值(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:保留四位小数; + /// 说明:校验规则:保留两位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("SwapCashCollateralValueThisMonth", "本月末收益互换现金担保物价值(元)", "36,2", true, "校验规则:保留四位小数;")] + [SacDescription("SwapCashCollateralValueThisMonth", "本月末收益互换现金担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapCashCollateralValueThisMonth { get; set; } /// /// 上月末收益互换现金担保物价值(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:保留四位小数; + /// 说明:校验规则:保留两位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("SwapCashCollateralValueLastMonth", "上月末收益互换现金担保物价值(元)", "36,2", true, "校验规则:保留四位小数;")] + [SacDescription("SwapCashCollateralValueLastMonth", "上月末收益互换现金担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapCashCollateralValueLastMonth { get; set; } /// /// 本月末收益互换证券担保物价值(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:保留四位小数; + /// 说明:校验规则:保留两位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("SwapSecuritiesCollateralValueThisMonth", "本月末收益互换证券担保物价值(元)", "36,2", true, "校验规则:保留四位小数;")] + [SacDescription("SwapSecuritiesCollateralValueThisMonth", "本月末收益互换证券担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapSecuritiesCollateralValueThisMonth { get; set; } /// /// 上月末收益互换证券担保物价值(元) /// 长度:36,2 /// 必填:是 - /// 说明:校验规则:保留四位小数; + /// 说明:校验规则:保留两位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("SwapSecuritiesCollateralValueLastMonthThisMonth", "上月末收益互换证券担保物价值(元)", "36,2", true, "校验规则:保留四位小数;")] + [SacDescription("SwapSecuritiesCollateralValueLastMonthThisMonth", "上月末收益互换证券担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapSecuritiesCollateralValueLastMonthThisMonth { get; set; } /// @@ -1329,14 +1330,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string SwapExpensesCashFlow { get; set; } /// - /// 互换使用预付金形成的净收益对应现金流(万元) + /// 互换使用保证金形成的净收益对应现金流(万元) /// 长度:36,4 /// 必填:是 /// 说明:校验规则:保留四位小数; /// [CheckStringIntLength(BeforePointMaxLength = 32, AfterPointLength = 4)] [DefaultValue("")] - [SacDescription("CashFlowCorrespondingToNetIncomeOnSwapMargin", "互换使用预付金形成的净收益对应现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] + [SacDescription("CashFlowCorrespondingToNetIncomeOnSwapMargin", "互换使用保证金形成的净收益对应现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] public string CashFlowCorrespondingToNetIncomeOnSwapMargin { get; set; } /// @@ -1560,7 +1561,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 标的情况与对冲 /// - public class ISDATargetCaseAndHedgeModel + public class ISDATargetCaseAndHedgeModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -1621,7 +1622,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 标的交易场所 /// 长度:200 /// 必填:否 - /// 说明: + /// 说明:股指期货和大宗商品买入对冲包括开多仓和平空仓;保留两位小数 /// [CheckStringMaxLength(MaxLength = 200, Required = false)] [DefaultValue("")] @@ -1674,13 +1675,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 本月末持仓数量(股/手) - /// 长度:36,4 + /// 长度:36,6 /// 必填:否 - /// 说明:校验规则:大于等于0;\r\n权益类填写股数 + /// 说明:校验规则:大于等于0;\r\n权益类填写股数; /// - [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4, Required = false)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 6, Required = false)] [DefaultValue("")] - [SacDescription("TheNumberOfPositionsHeldAtTheEndOfThisMonth", "本月末持仓数量(股/手)", "36,4", false, "校验规则:大于等于0;\r\n权益类填写股数;")] + [SacDescription("TheNumberOfPositionsHeldAtTheEndOfThisMonth", "本月末持仓数量(股/手)", "36,6", false, "校验规则:大于等于0;\r\n权益类填写股数;")] public string TheNumberOfPositionsHeldAtTheEndOfThisMonth { get; set; } /// @@ -1693,12 +1694,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("AveragePriceAtTheEndOfTheMonth", "本月末持仓平均价格(元)", "36,2", false, "校验规则:保留两位小数;")] public string AveragePriceAtTheEndOfTheMonth { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } /// /// 本月末存量业务明细 /// - public class ISDAInventoryBusinessDetailsAtTheEndOfThisMonthModel + public class ISDAInventoryBusinessDetailsAtTheEndOfThisMonthModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -1769,22 +1779,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金(或多头名义本金)(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位;")] public string NotionalPrincipalAmountLNotionalPrincipalAmount { get; set; } /// /// 空头名义本金(元)(多空组合填写) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位;")] public string SNotionalPrincipalAmount { get; set; } /// @@ -1859,7 +1869,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 场外期权标的小类(场外期权填写) /// 长度:2 /// 必填:否 - /// 说明: + /// 说明: /// [CheckStringMaxLength(MaxLength = 2, Required = false)] [DefaultValue("")] @@ -1897,24 +1907,27 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:否 /// 说明:校验规则:当"业务类型"为"场外期权"时,必填 /// - [CheckStringMaxLength(MaxLength = 2, Required = false)] + [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("OptionType", "期权类型(场外期权填写)", "5,2", false, "校验规则:当业务类型为场外期权时,必填;")] public string OptionType { get; set; } /// - /// 本月末维持预付金比例(%) + /// 本月末维持保证金比例(%) /// 长度:36,2 /// 必填:否 /// - /// 说明:指月末维持预付金加浮动盈亏占合约存续名义本金的比例; - /// 对于多空互换,指维持预付金加浮动盈亏占多头名义本金和空头名义本金孰高的比例. - /// 例如维持预付金比例为50%,填写50.00 + /// 说明:指月末维持保证金加浮动盈亏占合约存续名义本金的比例; + /// 对于多空互换,指维持保证金加浮动盈亏占多头名义本金和空头名义本金孰高的比例. + /// 例如维持保证金比例为50%,填写50.00 /// /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("MaitainMarginRation", "本月末维持预付金比例(%)", "36,2", false, "指月末维持预付金加浮动盈亏占合约存续名义本金的比例;\r\n对于多空互换,指维持预付金加浮动盈亏占多头名义本金和空头名义本金孰高的比例.\r\n例如维持预付金比例为50%,填写50.00;")] + [SacDescription("MaitainMarginRation", "本月末维持保证金比例(%)", "36,2", false, "指月末维持保证金加浮动盈亏占合约存续名义本金的比例;\r\n对于多空互换,指维持保证金加浮动盈亏占多头名义本金和空头名义本金孰高的比例.\r\n例如维持保证金比例为50%,填写50.00;")] public string MaitainMarginRation { get; set; } /// @@ -1958,12 +1971,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("ShortPositionContractValue", "空头合约价值(元)", "36,2", false, "客户空头、多空组合收益互换需填写;\r\n保留两位小数;")] public string ShortPositionContractValue { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } /// /// 本月新增业务明细 /// - public class ISDAIncreaseBusinessDetailsThisMonthModel + public class ISDAIncreaseBusinessDetailsThisMonthModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -2034,22 +2056,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金(或多头名义本金)(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,多空组合填写多头名义本; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留2位小数,多空组合填写多头;")] public string NotionalPrincipalAmountLNotionalPrincipalAmount { get; set; } /// /// 空头名义本金(元)(多空组合填写) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数, /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留2位小数;")] public string SNotionalPrincipalAmount { get; set; } /// @@ -2109,11 +2131,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("UndrlygAssetCode", "标的编码", "200", false, "")] public string UndrlygAssetCode { get; set; } + /// + /// 标的交易场所 + /// 长度:200 + /// 必填:否 + /// 说明: + /// + [CheckStringMaxLength(MaxLength = 200, Required = false)] + [DefaultValue("")] + [SacDescription("UndrlygAssetTradgPlc", "标的交易场所", "200", false, "")] + public string UndrlygAssetTradgPlc { get; set; } + /// /// 场外期权标的小类(场外期权填写) /// 长度:2 /// 必填:否 - /// 说明: + /// 说明: /// [CheckStringMaxLength(MaxLength = 2, Required = false)] [DefaultValue("")] @@ -2151,9 +2184,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:否 /// 说明: /// - [CheckStringMaxLength(MaxLength = 2, Required = false)] + [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("OptionType", "期权类型(场外期权填写)", "5,2", false, "")] public string OptionType { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportNAFMIIModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportNAFMIIModel.cs index 58b41bf0..eb20a00f 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportNAFMIIModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportNAFMIIModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -812,10 +813,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 其他交易明细表 /// - public class ScheduleOfOtherTransactionModel + public class ScheduleOfOtherTransactionModel : ReportSubBaseModel { /// - /// 交易日期 + /// 起始日 /// 长度:10 /// 必填:否 /// 说明:校验规则:必须是YYYY-MM-DD; @@ -823,7 +824,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 10, Required = false)] [CheckStringIsDateTimeFormat] [DefaultValue("")] - [SacDescription("TradingDate", "交易日期", "10", false, "校验规则:必须是YYYY-MM-DD;")] + [SacDescription("TradingDate", "起始日", "10", false, "校验规则:必须是YYYY-MM-DD;")] public string TradingDate { get; set; } /// @@ -907,11 +908,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留4位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmount", "名义本金(元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmount", "名义本金(元)", "36,2", false, "校验规则:保留4位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string NotionalPrincipalAmount { get; set; } /// @@ -960,15 +961,25 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("ContractExpirationDate", "合约到期日", "10", false, "校验规则:必须是YYYY-MM-DD;\r\n合约到期日不能小于合约起始日;")] public string ContractExpirationDate { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } + } /// /// 利率期权明细 /// - public class InterestRateOptionDetailModel + public class InterestRateOptionDetailModel : ReportSubBaseModel { /// - /// 交易日期 + /// 起始日 /// 长度:10 /// 必填:否 /// 说明:校验规则:必须是YYYY-MM-DD; @@ -976,7 +987,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 10, Required = false)] [CheckStringIsDateTimeFormat] [DefaultValue("")] - [SacDescription("TradingDate", "交易日期", "10", false, "校验规则:必须是YYYY-MM-DD;")] + [SacDescription("TradingDate", "起始日", "10", false, "校验规则:必须是YYYY-MM-DD;")] public string TradingDate { get; set; } /// @@ -1152,12 +1163,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("ContractExpirationDate", "合约到期日", "10", false, "校验规则:必须是YYYY-MM-DD;\r\n合约到期日不能小于合约起始日;")] public string ContractExpirationDate { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } /// /// 利率互换明细 /// - public class InterestRateSwapDetailModel + public class InterestRateSwapDetailModel : ReportSubBaseModel { /// /// 交易日期 @@ -1263,11 +1283,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金金额 /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 15, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmount", "名义本金金额", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmount", "名义本金金额", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string NotionalPrincipalAmount { get; set; } /// @@ -1309,11 +1329,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 固定利率 /// 长度:8,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位; /// [CheckStringIntLength(BeforePointMaxLength = 8, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("FixedRate", "固定利率", "8,2", false, "校验规则:保留两位小数;")] + [SacDescription("FixedRate", "固定利率", "8,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为18位;")] public string FixedRate { get; set; } /// @@ -1404,5 +1424,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("FirstInterestPaymentDay", "首次利息支付(互换)日", "10", false, "校验规则:必须是YYYY-MM-DD;")] public string FirstInterestPaymentDay { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportSACModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportSACModel.cs index e1fbf706..24bca18d 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportSACModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/PeriodicReportSACModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -1348,7 +1349,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("TotalNominalPrincipalAmountOfSwapThisMonth", "本月末互换存量名义本金总额(亿元)", "36,4", true, "校验规则:保留四位小数;")] public string TotalNominalPrincipalAmountOfSwapThisMonth { get; set; } @@ -1359,7 +1360,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("TotalNominalPrincipalAmountOfSwapLastMonth", "上月末互换存量名义本金总额(亿元)", "36,4", true, "校验规则:保留四位小数;")] public string TotalNominalPrincipalAmountOfSwapLastMonth { get; set; } @@ -1370,7 +1371,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth", "本月末互换存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth { get; set; } @@ -1381,7 +1382,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth", "上月末互换存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth { get; set; } @@ -1392,7 +1393,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("SwapCashCollateralValueThisMonth", "本月末互换现金担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapCashCollateralValueThisMonth { get; set; } @@ -1403,7 +1404,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("SwapCashCollateralValueLastMonth", "上月末互换现金担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapCashCollateralValueLastMonth { get; set; } @@ -1414,7 +1415,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("SwapSecuritiesCollateralValueThisMonth", "本月末互换证券担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapSecuritiesCollateralValueThisMonth { get; set; } @@ -1425,7 +1426,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("SwapSecuritiesCollateralValueLastMonthThisMonth", "上月末互换证券担保物价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string SwapSecuritiesCollateralValueLastMonthThisMonth { get; set; } @@ -1436,7 +1437,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull", "本月末互换业务整体履约担保比例(全额)(%)", "36,2", true, "校验规则:保留两位小数;")] public string ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull { get; set; } @@ -1447,7 +1448,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull", "上月末互换业务整体履约担保比例(全额)(%)", "36,2", true, "校验规则:保留两位小数;")] public string ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull { get; set; } @@ -1458,7 +1459,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet", "本月末互换业务整体履约担保比例(净额)(%)", "36,2", true, "校验规则:保留两位小数;")] public string ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet { get; set; } @@ -1469,7 +1470,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet", "上月末互换业务整体履约担保比例(净额)(%)", "36,2", true, "校验规则:保留两位小数;")] public string ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet { get; set; } @@ -1568,7 +1569,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth", "本月末存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth { get; set; } @@ -1579,7 +1580,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth", "上月末存量交易对应履约担保品价值(元)", "36,2", true, "校验规则:保留两位小数;")] public string StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth { get; set; } @@ -1590,7 +1591,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("CashBalanceAtEndOfThisMonth", "本月末持有现金余额(元)", "36,2", true, "校验规则:保留两位小数;")] public string CashBalanceAtEndOfThisMonth { get; set; } @@ -1601,7 +1602,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("CashBalanceAtEndOfLastMonth", "上月末持有现金余额(元)", "36,2", true, "校验规则:保留两位小数;")] public string CashBalanceAtEndOfLastMonth { get; set; } @@ -1612,7 +1613,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldStockMarketValueAtEndOfThisMonth", "本月末持有股票市值(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldStockMarketValueAtEndOfThisMonth { get; set; } @@ -1623,7 +1624,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldStockMarketValueAtEndOfLastMonth", "上月末持有股票市值(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldStockMarketValueAtEndOfLastMonth { get; set; } @@ -1634,7 +1635,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldMarketValueOfBondsAtTheEndOfThisMonth", "本月末持有债券市值(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldMarketValueOfBondsAtTheEndOfThisMonth { get; set; } @@ -1645,7 +1646,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldMarketValueOfBondsAtTheEndOfLastMonth", "上月末持有债券市值(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldMarketValueOfBondsAtTheEndOfLastMonth { get; set; } @@ -1656,7 +1657,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("OwnedAssetManagementProductsAtTheEndOfThisMonth", "本月末持有证券公司资产管理产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string OwnedAssetManagementProductsAtTheEndOfThisMonth { get; set; } @@ -1667,7 +1668,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("OwnedAssetManagementProductsAtTheEndOfLastMonth", "上月末持有证券公司资产管理产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string OwnedAssetManagementProductsAtTheEndOfLastMonth { get; set; } @@ -1678,7 +1679,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("OwnedBankFinanceAtTheEndOfThisMonth", "本月末持有银行理财(元)", "36,2", true, "校验规则:保留两位小数;")] public string OwnedBankFinanceAtTheEndOfThisMonth { get; set; } @@ -1689,7 +1690,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("OwnedBankFinanceAtTheEndOfLastMonth", "上月末持有银行理财(元)", "36,2", true, "校验规则:保留两位小数;")] public string OwnedBankFinanceAtTheEndOfLastMonth { get; set; } @@ -1700,7 +1701,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldTrustProductAtTheEndOfThisMonth", "本月末持有信托产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldTrustProductAtTheEndOfThisMonth { get; set; } @@ -1711,7 +1712,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldTrustProductAtTheEndOfLastMonth", "上月末持有信托产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldTrustProductAtTheEndOfLastMonth { get; set; } @@ -1722,7 +1723,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("InsuranceProductsAreHeldAtTheEndOfThisMonth", "本月末持有保险产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string InsuranceProductsAreHeldAtTheEndOfThisMonth { get; set; } @@ -1733,7 +1734,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("InsuranceProductsAreHeldAtTheEndOfLastMonth", "上月末持有保险产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string InsuranceProductsAreHeldAtTheEndOfLastMonth { get; set; } @@ -1744,7 +1745,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldOtherProductsAtTheEndOfThisMonth", "本月末持有其他产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldOtherProductsAtTheEndOfThisMonth { get; set; } @@ -1755,7 +1756,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留两位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 2)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] [SacDescription("HoldOtherProductsAtTheEndOfLastMonth", "上月末持有其他产品(元)", "36,2", true, "校验规则:保留两位小数;")] public string HoldOtherProductsAtTheEndOfLastMonth { get; set; } @@ -1777,7 +1778,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth", "互换本月了结交易涉及名义本金(亿元)", "36,4", true, "校验规则:保留四位小数;")] public string SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth { get; set; } @@ -1788,7 +1789,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("SwapIncomeCashFlow", "互换收入现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] public string SwapIncomeCashFlow { get; set; } @@ -1799,20 +1800,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("SwapExpensesCashFlow", "互换支出现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] public string SwapExpensesCashFlow { get; set; } /// - /// 互换使用预付金形成的净收益对应现金流(万元) + /// 互换使用保证金形成的净收益对应现金流(万元) /// 长度:36,4 /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] - [SacDescription("CashFlowCorrespondingToNetIncomeOnSwapMargin", "互换使用预付金形成的净收益对应现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] + [SacDescription("CashFlowCorrespondingToNetIncomeOnSwapMargin", "互换使用保证金形成的净收益对应现金流(万元)", "36,4", true, "校验规则:保留四位小数;")] public string CashFlowCorrespondingToNetIncomeOnSwapMargin { get; set; } /// @@ -1821,7 +1822,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("SwapHedgeCost", "互换对冲成本(万元)", "36,4", true, "校验规则:保留四位小数;")] public string SwapHedgeCost { get; set; } @@ -1843,7 +1844,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth", "期权本月了结交易涉及名义本金(亿元)", "36,4", true, "校验规则:保留四位小数;")] public string SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth { get; set; } @@ -1854,7 +1855,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("OptionPremiumIncome", "期权权利金收入(万元)", "36,4", true, "校验规则:保留四位小数;")] public string OptionPremiumIncome { get; set; } @@ -1865,7 +1866,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("OptionHedgeCost", "期权对冲成本(万元)", "36,4", true, "校验规则:保留四位小数;")] public string OptionHedgeCost { get; set; } @@ -1876,7 +1877,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapRealizedGainsAndLossesAtThisMonth", "互换合约端损益本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapRealizedGainsAndLossesAtThisMonth { get; set; } @@ -1887,7 +1888,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionRealizedGainsAndLossesAtThisMonth", "期权合约端损益本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionRealizedGainsAndLossesAtThisMonth { get; set; } @@ -1898,7 +1899,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapRealizedGainsAndLossesAtThisYear", "互换合约端损益本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapRealizedGainsAndLossesAtThisYear { get; set; } @@ -1909,7 +1910,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionRealizedGainsAndLossesAtThisYear", "期权合约端损益本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionRealizedGainsAndLossesAtThisYear { get; set; } @@ -1920,7 +1921,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth", "互换对冲端损益本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth { get; set; } @@ -1931,7 +1932,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth", "期权对冲端损益本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth { get; set; } @@ -1942,7 +1943,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear", "互换对冲端损益本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear { get; set; } @@ -1953,7 +1954,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear", "期权对冲端损益本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear { get; set; } @@ -1964,7 +1965,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapTotalGainsAndLossesAtThisMonth", "互换损益合计本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapTotalGainsAndLossesAtThisMonth { get; set; } @@ -1975,7 +1976,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionTotalGainsAndLossesAtThisMonth", "期权损益合计本月发生额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionTotalGainsAndLossesAtThisMonth { get; set; } @@ -1986,7 +1987,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfSwapTotalGainsAndLossesAtThisYear", "互换损益合计本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfSwapTotalGainsAndLossesAtThisYear { get; set; } @@ -1997,7 +1998,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 必填:是 /// 说明:校验规则:保留四位小数; /// - [CheckStringIntLength(BeforePointMaxLength = 34, AfterPointLength = 4)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 4)] [DefaultValue("")] [SacDescription("BalanceOfOptionTotalGainsAndLossesAtThisYear", "期权损益合计本年累计额(万元)", "36,4", true, "校验规则:保留四位小数;")] public string BalanceOfOptionTotalGainsAndLossesAtThisYear { get; set; } @@ -2033,14 +2034,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public List TargetCaseAndHedgeTuple { get; set; } /// - /// 收益互换整体业务存量对应预付金(元)+ 期权费(元) + /// 收益互换整体业务存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginOfSubsistSwap", "收益互换整体业务存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginOfSubsistSwap", "收益互换整体业务存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginOfSubsistSwap { get; set; } /// @@ -2066,14 +2067,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string LeverageRatiOfSwap { get; set; } /// - /// 收益互换股指标的存量对应预付金(元)+ 期权费(元) + /// 收益互换股指标的存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginOfSubsistStockIndexSwap", "收益互换股指标的存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginOfSubsistStockIndexSwap", "收益互换股指标的存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginOfSubsistStockIndexSwap { get; set; } /// @@ -2099,14 +2100,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string LeverageRatioOfStockIndexSwap { get; set; } /// - /// 收益互换个股标的存量对应预付金(元)+ 期权费(元) + /// 收益互换个股标的存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginOfSubsistStockSwap", "收益互换个股标的存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginOfSubsistStockSwap", "收益互换个股标的存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginOfSubsistStockSwap { get; set; } /// @@ -2132,14 +2133,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string LeverageRatioOfStockSwap { get; set; } /// - /// 场外期权整体业务存量对应预付金(元)+ 期权费(元) + /// 场外期权整体业务存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginandPremiumOfSubsistOption", "场外期权整体业务存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginandPremiumOfSubsistOption", "场外期权整体业务存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginandPremiumOfSubsistOption { get; set; } /// @@ -2165,14 +2166,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string LeverageRatioOfOption { get; set; } /// - /// 场外期权股指标的存量对应预付金(元)+ 期权费(元) + /// 场外期权股指标的存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginandPremiumOfSubsistStockIndexOption", "场外期权股指标的存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginandPremiumOfSubsistStockIndexOption", "场外期权股指标的存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginandPremiumOfSubsistStockIndexOption { get; set; } /// @@ -2198,14 +2199,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string LeverageRatioOfStockIndexOption { get; set; } /// - /// 场外期权个股标的存量对应预付金(元)+ 期权费(元) + /// 场外期权个股标的存量对应保证金(元)+ 期权费(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:保留两位小数 /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginandPremiumOfSubsistStockOption", "场外期权个股标的存量对应预付金(元)+", "36,2", true, "校验规则:保留两位小数;")] + [SacDescription("MarginandPremiumOfSubsistStockOption", "场外期权个股标的存量对应保证金(元)+ 期权费(元)", "36,2", true, "校验规则:保留两位小数;")] public string MarginandPremiumOfSubsistStockOption { get; set; } /// @@ -2454,7 +2455,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 标的情况与对冲 /// - public class TargetCaseAndHedgeModel + public class TargetCaseAndHedgeModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -2576,7 +2577,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 权益类填写股数 /// /// - [CheckStringIntLength(MinValue = 0, BeforePointMaxLength = 36, AfterPointLength = 6, Required = false)] + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 6, Required = false)] [DefaultValue("")] [SacDescription("TheNumberOfPositionsHeldAtTheEndOfThisMonth", "本月末持仓数量(股/手)", "36,6", false, "校验规则:大于等于0;\r\n权益类填写股数;")] public string TheNumberOfPositionsHeldAtTheEndOfThisMonth { get; set; } @@ -2591,12 +2592,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("AveragePriceAtTheEndOfTheMonth", "本月末持仓平均价格(元)", "36,2", false, "校验规则:保留两位小数;")] public string AveragePriceAtTheEndOfTheMonth { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } /// /// 本月末存量业务明细 /// - public class InventoryBusinessDetailsAtTheEndOfThisMonthModel + public class InventoryBusinessDetailsAtTheEndOfThisMonthModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -2667,22 +2677,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金(或多头名义本金)(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string NotionalPrincipalAmountLNotionalPrincipalAmount { get; set; } /// /// 空头名义本金(元)(多空组合填写) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string SNotionalPrincipalAmount { get; set; } /// @@ -2754,12 +2764,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 期权标的小类(场外期权填写) /// 长度:2 /// 必填:否 - /// 说明:校验规则:如业务类型为期权,需填写本字段; + /// 说明:校验规则:如业务类型为期权,需填写本字段; /// [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] - [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "99" }, CheckHandleName = "A")] - [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "99" }, Required = false, CheckHandleName = "B")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("OptionSumInvestmentTargetType", "期权标的小类(场外期权填写)", "2", false, "校验规则:如业务类型为期权,需填写本字段;")] public string OptionSumInvestmentTargetType { get; set; } @@ -2793,27 +2803,27 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string OptionFee { get; set; } /// - /// 期权类型 + /// 期权结构类型(期权填写) /// 长度:2 /// 必填:否 /// 说明: 校验规则:如业务类型为期权,需填写本字段; /// [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] - [CheckStringInMap(Map = new[] { "0", "1", "2", "4", "5", "6", "7", "99" }, CheckHandleName = "A")] - [CheckStringInMap(Map = new[] { "0", "1", "2", "4", "5", "6", "7", "99" }, Required = false, CheckHandleName = "B")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("OptionType", "期权类型", "2", false, "校验规则:如业务类型为期权,需填写本字段;")] + [SacDescription("OptionType", "期权结构类型(期权填写)", "2", false, "校验规则:如业务类型为期权,需填写本字段;")] public string OptionType { get; set; } /// - /// 本月末维持预付金比例(%) + /// 本月末维持保证金比例(%) /// 长度:36,2 /// 必填:否 /// - /// 说明:指月末维持预付金加浮动盈亏占合约存续名义本金的比例; - /// 对于多空互换,指维持预付金加浮动盈亏占多头名义本金和空头名义本金孰高的比例. - /// 例如维持预付金比例为50%,填写50.00 + /// 说明:指月末维持保证金加浮动盈亏占合约存续名义本金的比例; + /// 对于多空互换,指维持保证金加浮动盈亏占多头名义本金和空头名义本金孰高的比例. + /// 例如维持保证金比例为50%,填写50.00 /// /// [CheckConditionStringInMap(ConditionName = nameof(BusinessType), ConditionMap = new[] { "11", "12" }, CheckHandleNameArr = new[] { "A" })] @@ -2821,7 +2831,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, CheckHandleName = "A")] [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("MaitainMarginRation", "本月末维持预付金比例(%)", "36,2", false, "指月末维持预付金加浮动盈亏占合约存续名义本金的比例;\r\n对于多空互换,指维持预付金加浮动盈亏占多头名义本金和空头名义本金孰高的比例.\r\n例如维持预付金比例为50%,填写50.00;")] + [SacDescription("MaitainMarginRation", "本月末维持保证金比例(%)", "36,2", false, "指月末维持保证金加浮动盈亏占合约存续名义本金的比例;\r\n对于多空互换,指维持保证金加浮动盈亏占多头名义本金和空头名义本金孰高的比例.\r\n例如维持保证金比例为50%,填写50.00;")] public string MaitainMarginRation { get; set; } /// /// 标的相关系数 @@ -2870,12 +2880,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("ShortPositionContractValue", "空头合约价值(元)", "36,2", false, "客户空头、多空组合收益互换需填写;\r\n保留两位小数;")] public string ShortPositionContractValue { get; set; } + + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } /// /// 本月新增业务明细 /// - public class IncreaseBusinessDetailsThisMonthModel + public class IncreaseBusinessDetailsThisMonthModel : ReportSubBaseModel { /// /// 报送机构名称(全称) @@ -2949,22 +2969,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 名义本金(或多头名义本金)(元) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留4位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("NotionalPrincipalAmountLNotionalPrincipalAmount", "名义本金(或多头名义本金)(元)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string NotionalPrincipalAmountLNotionalPrincipalAmount { get; set; } /// /// 空头名义本金(元)(多空组合填写) /// 长度:36,2 /// 必填:否 - /// 说明:校验规则:保留两位小数; + /// 说明:校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位; /// [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, Required = false)] [DefaultValue("")] - [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留两位小数;")] + [SacDescription("SNotionalPrincipalAmount", "空头名义本金(元)(多空组合填写)", "36,2", false, "校验规则:保留2位小数,同时总的字符长度不能超过20,即整数位最多可为15位;")] public string SNotionalPrincipalAmount { get; set; } /// @@ -3030,12 +3050,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 期权标的小类(场外期权填写) /// 长度:2 /// 必填:否 - /// 说明:校验规则:如业务类型为场外期权,需填写本字段; + /// 说明:校验规则:如业务类型为场外期权,需填写本字段; /// [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] - [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "99" }, CheckHandleName = "A")] - [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "99" }, Required = false, CheckHandleName = "B")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("OptionObjectSecondClass", "期权标的小类(场外期权填写)", "2", false, "校验规则:如业务类型为场外期权,需填写本字段;")] public string OptionObjectSecondClass { get; set; } @@ -3072,17 +3092,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model public string NonAnnualOptionFee { get; set; } /// - /// 期权类型(期权填写) + /// 期权结构类型(期权填写) /// 长度:2 /// 必填:否 /// 说明:校验规则:如业务类型为期权,需填写本字段; /// [CheckConditionStringValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(BusinessType), ConditionValue = "02", CheckHandleNameArr = new[] { "B" })] - [CheckStringInMap(Map = new[] { "0", "1", "2", "4", "5", "6", "7", "99" }, Required = false, CheckHandleName = "A")] - [CheckStringInMap(Map = new[] { "0", "1", "2", "4", "5", "6", "7", "99" }, Required = false, CheckHandleName = "B")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "0", "1", "2", "3", "4", "5", "99" }, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("OptionType", "期权类型(期权填写)", "2", false, "校验规则:如业务类型为期权,需填写本字段;")] + [SacDescription("OptionType", "期权结构类型(期权填写)", "2", false, "校验规则:如业务类型为期权,需填写本字段;")] public string OptionType { get; set; } + /// + /// 序号 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [SacDescription("Index", "序号", "", false, "")] + public string Index { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportReq.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportReq.cs index 0747b149..1e546bb6 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportReq.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportReq.cs @@ -1,4 +1,6 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -95,6 +97,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 报告类型 /// public List ReportTypes { get; set; } + + /// + /// 证券业报送中定期报告取值模式 + /// 1=Db; + /// 2=Excel模板; + /// 3=Db+Excel模板(该方式中涉及百分比汇总计算时仍使用模板中数据) + /// 4=金仕达视图(该方式只涉及互换确认书及存续期的数据) + /// 5=Db+金仕达视图 + /// 6=Excel+金仕达视图 + /// 7=Db+Excel+金仕达视图 + /// + public SAC_ReportDataSourceEnum DataSource { get; set; } } public class ReportResponse @@ -112,7 +126,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model { return ""; } - return $"OTC_{Infos[0].Header.SenderCode}_{Infos[0].Header.ReceiverCode}_{Infos[0].Header.ReportType}_{Infos[0].Header.SendDate.Replace("-", "")}_{Index.ToString("0000")}"; + return $"OTC_{Infos[0].Header.SenderCode}_{Infos[0].Header.ReceiverCode}_{Infos[0].Header.ReportType}_{Infos[0].Header.SendDate.Replace("-", "")}_{Index.ToString("0000")}{(Infos.Any(O => O.Header.BusiDataType == DataFlagsEnum.A1015) ? "_checked" : "")}"; } } @@ -126,13 +140,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 仅外部数据来源使用 /// [XmlIgnore] + [NotMapped] public bool IgnoreCheck { get; set; } + + [Key] + [XmlIgnore] + public int Id { get; set; } + + /// + /// 报送日期 + /// + [XmlIgnore] + public DateTime ReportDate { get; set; } + /// /// 业务数据流水号 /// 长度:28 /// 必填:是 /// 说明:文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位) /// + [CheckStringLength(Length = 28)] [SacDescription("ExceID", "业务数据流水号", "28", true, "文件创建人代码(6位)+文件接收人代码(6位)+报送日期(8位)+当日顺序编号(8位);")] public string ExceID { get; set; } @@ -143,6 +170,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明:报送时该字段应为Null /// [XmlElement(IsNullable = false)] + [NotMapped] [SacDescription("RetCode", "响应码", "6", true, "报送时该字段应为Null;")] public string RetCode { get; set; } /// @@ -152,6 +180,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明:报送时该字段应为Null /// [XmlElement(IsNullable = false)] + [NotMapped] [SacDescription("RetMsg", "响应描述", "1000", true, "报送时该字段应为Null;")] public string RetMsg { get; set; } /// @@ -162,6 +191,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 报送时该字段应为Null /// [XmlElement(IsNullable = false)] + [NotMapped] [SacDescription("BizID", "报送数据业务编号", "50", false, "报告库接口返回,数据处理异常时为空\r\n报送时该字段应为Null;")] public string BizID { get; set; } /// @@ -172,10 +202,30 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 报送时该字段应为Null /// [XmlElement(IsNullable = false)] + [NotMapped] [SacDescription("DurationEventNO", "操作事件编号", "6", false, "场外证券业务系统接口返回,当报送存续期业务时,返回操作时间编号ID\r\n报送时该字段应为Null;")] public string DurationEventNO { get; set; } } + public abstract class ReportSubBaseModel + { + [Key] + [XmlIgnore] + public int Id { get; set; } + + /// + /// 报送日期 + /// + [XmlIgnore] + public DateTime ReportDate { get; set; } + + /// + /// 来源报送文件 ExceID + /// + [XmlIgnore] + public string ExceID { get; set; } + } + /// /// 报告状态 /// @@ -198,8 +248,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model private long limitFileLength => MaxFileLength - 5242880;//留出5MB余量 - private long _currentLength = 0; - public long CurrentLength => _currentLength; + public long CurrentLength { get; private set; } = 0; public bool Continue { get; private set; } @@ -208,7 +257,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// public void ResetCurrentLength() { - _currentLength = 0; + CurrentLength = 0; Continue = false; } @@ -226,22 +275,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model { return true; } - var length = new FileInfo(path).Length; - if (length > limitFileLength) - { - LogFactory.GetLogger("CheckFileLength").Error($"单一文件大小不应超过30MB,错误文件:{path}"); - throw new ServiceException("单一文件大小不应超过30MB"); - } - _currentLength += length; - if (_currentLength <= limitFileLength) - { - return true; - } - else - { - Continue = true; - return false; - } + //var length = new FileInfo(path).Length; + //if (length > MaxAnnexLength) + //{ + // LogFactory.GetLogger("CheckFileLength").Error($"单一文件大小不应超过30MB,错误文件:{path}"); + // throw new ServiceException("单一文件大小不应超过30MB"); + //} + //CurrentLength += length; + //if (CurrentLength <= limitFileLength) + //{ + return true; + //} + //else + //{ + // Continue = true; + // return false; + //} } /// @@ -252,10 +301,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 缓存是否存在value public bool CheckCacheInfo(string key, string value) { - if (CacheInfo == null) - { - CacheInfo = new Dictionary>(); - } + CacheInfo ??= new Dictionary>(); if (!CacheInfo.ContainsKey(key)) { CacheInfo[key] = new List(); @@ -270,10 +316,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// public ReadOnlyCollection GetCacheInfo(string key) { - if (CacheInfo == null) - { - CacheInfo = new Dictionary>(); - } + CacheInfo ??= new Dictionary>(); if (!CacheInfo.ContainsKey(key)) { CacheInfo[key] = new List(); @@ -288,10 +331,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// public void AddCacheInfo(string key, string value) { - if (CacheInfo == null) - { - CacheInfo = new Dictionary>(); - } + CacheInfo ??= new Dictionary>(); if (!CacheInfo.ContainsKey(key)) { CacheInfo[key] = new List(); diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportRootModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportRootModel.cs index 73ead5f0..048b7543 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportRootModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ReportRootModel.cs @@ -1,4 +1,9 @@ -using System.ComponentModel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using System.Xml; using System.Xml.Serialization; using YLErp.Helpers; @@ -58,30 +63,40 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model private string check(string xml) { var result = xml; - if (Header.BusiDataType == DataFlagsEnum.A1016) + switch (this.Header.BusiDataType) { - try - { - var doc = new System.Xml.XmlDocument(); - doc.LoadXml(xml); - var body = doc.GetElementsByTagName("SwapEquityPayment"); - if (body.Count > 0) + case DataFlagsEnum.A1016: + try { - foreach (XmlElement item in body) + var doc = new System.Xml.XmlDocument(); + doc.LoadXml(xml); + var body = doc.GetElementsByTagName("SwapEquityPayment"); + if (body.Count > 0) { - var taget = item.GetElementsByTagName("DurationEventNO"); - var frist = item.GetElementsByTagName("SwapEquityPaymentTuple"); - if (taget.Count > 0) + foreach (XmlElement item in body) { - item.InsertAfter(taget[0], frist[frist.Count - 1]); + var target = item.GetElementsByTagName("DurationEventNO"); + var frist = item.GetElementsByTagName("SwapEquityPaymentTuple"); + if (target.Count > 0) + { + item.InsertAfter(target[0], frist[frist.Count - 1]); + } } + result = XmlHelper.FormatXml(doc.OuterXml); } - result = XmlHelper.FormatXml(doc.OuterXml); } - } - catch - { - } +#pragma warning disable CS0168 // 声明了变量“ex”,但从未使用过 + catch (Exception ex) +#pragma warning restore CS0168 // 声明了变量“ex”,但从未使用过 + { + } + break; + case DataFlagsEnum.A1004: + if (result.Contains("")) + { + result = result.Replace("", ""); + } + break; } return result; } @@ -161,7 +176,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明: /// [CheckStringInMap(Map = new[] { "A1001", "A1002","A1003","A1004", "A1005", "A1006" ,"A1007", - "A1008", "A1009","A1010", "A1011", "A1012","A1013","A1014","A1015","A1016","A1017" })] + "A1008", "A1009","A1010", "A1011", "A1012","A1013","A1014","A1015","A1016","A1017","A1018","A1019" })] [SacDescription("BusiDataType", "接口标识", "5", true, "")] public DataFlagsEnum BusiDataType { get; set; } /// @@ -241,11 +256,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("SwapEquityPayment", "收益互换交易权益端支付", "", false, "")] public List SwapEquityPayment { get; set; } /// - /// 互换交易确认书附件 + /// 交易确认书附件 /// [XmlElement] - [SacDescription("ConfirmationAtt", "互换交易确认书附件", "", false, "")] - public List ConfirmationAtt { get; set; } + [SacDescription("ConfirmationAtt", "交易确认书附件", "", false, "")] + public List ConfirmationAtt { get; set; } /// /// 期权交易存续期管理 /// @@ -259,6 +274,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("SwapDurationManagement", "收益互换交易存续期管理", "", false, "")] public List SwapDurationManagement { get; set; } /// + /// 场外期权合约估值信息 + /// + [XmlElement] + [SacDescription("ValuationInformation", "场外期权合约估值信息", "", false, "")] + public List ValuationInformation { get; set; } + /// /// 定期报告-SAC模板 /// [XmlElement] diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SupAgrmtModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SupAgrmtModel.cs index 685f1949..2d994a2d 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SupAgrmtModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SupAgrmtModel.cs @@ -1,4 +1,6 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +10,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 补充协议 /// + [Table("A1003_SupAgrmt")] public class SupAgrmtModel : ReportBaseModel { /// @@ -23,14 +26,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 主协议编号(双方约定) /// 长度:100 /// 必填:是 - /// 说明:校验规则:双方约定 + /// 说明:双方约定 /// [CheckStringMaxLength(MaxLength = 100)] [DefaultValue("")] - [SacDescription("MasterAgrmtNo", "主协议编号(双方约定)", "100", true, "校验规则:双方约定;")] + [SacDescription("MasterAgrmtNo", "主协议编号(双方约定)", "100", true, "双方约定;")] public string MasterAgrmtNo { get; set; } /// - /// 补充协议编号 + /// 补充议编号 /// 长度:32 /// 必填:否 /// 说明:校验规则:补正时必填 @@ -40,17 +43,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 32, CheckHandleName = "A")] [CheckStringMaxLength(MaxLength = 32, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("SupAgrmtID", "补充协议编号", "32", false, "校验规则:补正时必填;")] + [SacDescription("SupAgrmtID", "补充议编号", "32", false, "校验规则:补正时必填;")] public string SupAgrmtID { get; set; } /// /// 补充协议编号(双方约定) /// 长度:100 /// 必填:是 - /// 说明:校验规则:双方约定 + /// 说明:双方约定 /// [CheckStringMaxLength(MaxLength = 100)] [DefaultValue("")] - [SacDescription("SupAgrmtNo", "补充协议编号(双方约定)", "100", true, "校验规则:双方约定;")] + [SacDescription("SupAgrmtNo", "补充协议编号(双方约定)", "100", true, "双方约定;")] public string SupAgrmtNo { get; set; } /// /// 补充协议类型 @@ -61,7 +64,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 2)] [DefaultValue("")] [SacDescription("SupAgrmtType", "补充协议类型", "2", true, "")] - public string SupAgrmtType { get; set; } + public string? SupAgrmtType { get; set; } /// /// 签署时间 /// 长度:10 @@ -71,7 +74,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringLength(Length = 10)] [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] [DefaultValue("")] - [SacDescription("SigningDate", "签署时间", "10", true, "校验规则:必须是yyyy-MM-dd;")] + [SacDescription("SigningDate", "签署时间", "10", true, "校验规则:必须是YYYY-MM-DD;")] public string SigningDate { get; set; } /// /// 补充协议备注 @@ -82,7 +85,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] [SacDescription("SupAgrmtRemark", "补充协议备注", "1024", false, "上述所有字段未能包含的信息;")] - public string SupAgrmtRemark { get; set; } + public string? SupAgrmtRemark { get; set; } + /// + /// 补充协议附件 + /// 长度:1024 + /// 必填:否 + /// 说明:上述所有字段未能包含的信息 + /// + [XmlIgnore] + public string SupAgrmtAtt { get; set; } + /// + /// 补充协议附件 /// /// 补充协议附件 /// 长度: @@ -90,14 +103,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明: /// [XmlElement] + [NotMapped] [SacDescription("SupAgrmtAttTuple", "补充协议附件", "", true, "")] - public List SupAgrmtAttTuple { get; set; } + public List? SupAgrmtAttTuple { get; set; } } /// /// 补充协议附件 /// - public class SupAgrmtAttModel + public class SupAgrmtAttModel : ReportSubBaseModel { /// /// 补充协议附件 @@ -108,6 +122,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringEndsWith(EndsWithString = ".pdf")] [DefaultValue("")] [SacDescription("SupAgrmtAtt", "补充协议附件", "", true, "校验规则:只支持PDF格式;")] - public string SupAgrmtAtt { get; set; } + public string? SupAgrmtAtt { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationAttModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationAttModel.cs deleted file mode 100644 index b958d902..00000000 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationAttModel.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.ComponentModel; -using System.Xml.Serialization; -using YLErp.Modules.SuperviseReportModule.SAC.Common; -using static YLErp.DBModels.Consts.ConsReport; - -namespace YLErp.Modules.SuperviseReportModule.SAC.Model -{ - /// - /// 互换交易确认书附件 - /// - public class SwapConfirmationAttModel : ReportBaseModel - { - /// - /// 交易确认书编号(双方约定) - /// 长度:100 - /// 必填:是 - /// 说明:双方约定 - /// - [CheckStringMaxLength(MaxLength = 100)] - [DefaultValue("")] - [SacDescription("ConfirmationNo", "交易确认书编号(双方约定)", "100", true, "双方约定;")] - public string ConfirmationNo { get; set; } - /// - /// 操作标识 - /// 长度:1 - /// 必填:是 - /// 说明: - /// - [XmlIgnore] - [SacDescription("OperationType", "操作标识", "1", true, "")] - public OptFlagsEnum OperationType { get; set; } - /// - /// 交易确认书附件 - /// 长度: - /// 必填:是 - /// 说明:多附件; - /// - [CheckIEnumerableTMinCount(MinCount = 1)] - [XmlElement] - [SacDescription("ConfirmationFilesTuple", "交易确认书附件", "", true, "多附件;")] - public List ConfirmationFilesTuple { get; set; } - } - - public class ConfirmationFilesTupleModel - { - /// - /// 交易确认书附件 - /// 长度:100 - /// 必填:是 - /// 说明:校验规则:只支持PDF格式 - /// - [CheckStringEndsWith(EndsWithString = ".pdf")] - [DefaultValue("")] - [SacDescription("ConfirmationFiles", "交易确认书附件", "100", true, "校验规则:只支持PDF格式;")] - public string ConfirmationFiles { get; set; } - } -} \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationModel.cs index 92f81f9e..af73c72e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapConfirmationModel.cs @@ -1,4 +1,6 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +10,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 互换交易确认书 /// + [Table("A1005_SwapConfirmation")] public class SwapConfirmationModel : ReportBaseModel { /// @@ -17,6 +20,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明: /// [XmlIgnore] + [SacDescription("PaymentMethod", "支付方式", "2", true, "")] public string PaymentMethod { get; set; } /// /// 操作标识 @@ -64,7 +68,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 交易确认书编号(双方约定) /// 长度:100 /// 必填:是 - /// 说明:双方约定; + /// 说明:双方约定 /// [CheckStringMaxLength(MaxLength = 100)] [DefaultValue("")] @@ -74,11 +78,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 交易确认书类型 /// 长度:2 /// 必填:是 - /// 说明: + /// 说明:校验规则:首次提交时填0,补正时填1 /// [CheckStringInMap(Map = new[] { "0", "1" })] [DefaultValue("")] - [SacDescription("ConfirmationType", "交易确认书类型", "2", true, "")] + [SacDescription("ConfirmationType", "交易确认书类型", "2", true, "校验规则:首次提交时填0,补正时填1;")] public string ConfirmationType { get; set; } /// /// 填报方角色 @@ -104,34 +108,34 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 起始日 /// 长度:10 /// 必填:是 - /// 说明:校验规则:1 起始日不能大于到期日日期;2 必须是yyyy-MM-dd + /// 说明:校验规则:1 起始日不能大于到期日日期;2 必须是YYYY-MM-DD /// [CheckStringMaxLength(MaxLength = 10)] [CheckStringIsDateTimeFormat] [DefaultValue("")] - [SacDescription("StartDate", "起始日", "10", true, "校验规则:\r\n1 起始日不能大于到期日日期;\r\n2 必须是yyyy-MM-dd;")] + [SacDescription("StartDate", "起始日", "10", true, "校验规则:\r\n1 起始日不能大于到期日日期;\r\n2 必须是YYYY-MM-DD;")] public string StartDate { get; set; } /// /// 到期日 /// 长度:10 /// 必填:是 - /// 说明:指定的进行结算金额收付的日期. 校验规则:1 到期日不能小于起始日日期;2 必须是yyyy-MM-dd;3 补正时,如果该交易还有未被废除的存续期记录(包括展期\终止数据),到期日字段不能修改; + /// 说明:指定的进行结算金额收付的日期. 校验规则:1 到期日不能小于起始日日期;2 必须是YYYY-MM-DD; /// [CheckStringMaxLength(MaxLength = 10)] [CheckStringIsDateTimeFormat] [DefaultValue("")] - [SacDescription("DueDate", "到期日", "10", true, "指定的进行结算金额收付的日期.\r\n校验规则:\r\n1 到期日不能小于起始日日期;\r\n2 必须是yyyy-MM-dd;\r\n3 补正时,如果该交易还有未被废除的存续期记录(包括展期、终止数据),到期日字段不能修改;")] + [SacDescription("DueDate", "到期日", "10", true, "指定的进行结算金额收付的日期.\r\n校验规则:\r\n1 到期日不能小于起始日日期;\r\n2 必须是YYYY-MM-DD;")] public string DueDate { get; set; } /// /// 结算日 /// 长度:10 /// 必填:否 - /// 说明:交易双方在交易有效约定中指定的进行结算金额收付的日期;校验规则:1 必须是yyyy-MM-dd; + /// 说明:校验规则:1 必须是YYYY-MM-DD; /// [CheckStringMaxLength(MaxLength = 10, Required = false)] [CheckStringIsDateTimeFormat(Required = false)] [DefaultValue("")] - [SacDescription("SettlementDate", "结算日", "10", false, "交易双方在交易有效约定中指定的进行结算金额收付的日期;\r\n校验规则:\r\n1 必须是yyyy-MM-dd;")] + [SacDescription("SettlementDate", "结算日", "10", false, "校验规则:\r\n1 必须是YYYY-MM-DD;")] public string SettlementDate { get; set; } /// /// 结算货币 @@ -144,7 +148,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("Currency", "结算货币", "2", true, "使用货币通用代码(大写);")] public string Currency { get; set; } /// - /// 名义本金额(人民币、元) + /// 名义本金(元) /// 长度:36,2 /// 必填:是 /// 说明:校验规则:1 必须两位小数以内;2 补正时,如果该交易还有未被废除的存续期记录(包括展期\终止数据),名义本金额(人民币)字段不能修改; @@ -152,7 +156,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, MinValue = 0)] [DefaultValue("")] - [SacDescription("NotinalPrincipleAmt", "名义本金额(人民币、元)", "36,2", true, "校验规则:\r\n1 必须两位小数以内;\r\n2 补正时,如果该交易还有未被废除的存续期记录(包括展期、终止数据),名义本金额(人民币)字段不能修改;\r\n名义本金为标的期初价格乘以数量乘以乘数;\r\n多空组合填写多头名义本金与空头名义本金孰高;")] + [SacDescription("NotinalPrincipleAmt", "名义本金(元)", "36,2", true, "校验规则:\r\n1 必须两位小数以内;\r\n2 补正时,如果该交易还有未被废除的存续期记录(包括展期、终止数据),名义本金额(人民币)字段不能修改;")] public string NotinalPrincipleAmt { get; set; } /// /// 清算机构 @@ -181,7 +185,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 说明:交易场所选"99:其他交易场所"时,必填 /// [CheckConditionStringValue(ConditionName = nameof(TradingPlace), ConditionValue = "99", CheckHandleNameArr = new[] { "A" })] - [CheckStringMinLength(MinLength = 1, CheckHandleName = "A")] + [CheckStringMaxLength(MaxLength = 200, CheckHandleName = "A")] [DefaultValue("")] [SacDescription("TradingPlaceOther", "交易场所(其他)", "200", false, "交易场所选99:其他交易场所时,必填;")] public string TradingPlaceOther { get; set; } @@ -209,6 +213,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 费用端支付 /// [XmlElement] + [NotMapped] [SacDescription("CostPaymentTuple", "费用端支付", "", false, "")] public List CostPaymentTuple { get; set; } /// @@ -232,26 +237,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringInMap(Map = new[] { "0", "1", "2", "3" }, CheckHandleName = "A")] [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PerformanceCollProvider", "履约担保品提供方", "2", false, "检验规则履约担保类型为部分担保或全额担保时必填;")] + [SacDescription("PerformanceCollProvider", "履约担保品提供方", "2", false, "检验规则:履约担保类型为部分担保或全额担保时必填;")] public string PerformanceCollProvider { get; set; } /// /// 担保品收取方是否可使用担保品 /// 长度:5 /// 必填:否 - /// 说明:检验规则:履约担保类型为部分担保,全额担保时必填; + /// 说明:检验规则:履约担保类型为"部分担保"或"全额担保"时必填; /// [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] [CheckStringInMap(Map = new[] { "true", "false" }, CheckHandleName = "A")] [CheckStringLength(Length = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("PartyUseColl", "担保品收取方是否可使用担保品", "5", false, "检验规则:履约担保类型为部分担保,全额担保时必填;")] + [SacDescription("PartyUseColl", "担保品收取方是否可使用担保品", "5", false, "检验规则:履约担保类型为部分担保或全额担保时必填;")] public string PartyUseColl { get; set; } /// /// 担保品使用说明 /// 长度:1024 /// 必填:否 - /// 说明:检验规则:当担保品收取方是否可使用担保品选择是时必填; + /// 说明:检验规则:当"担保品收取方是否可使用担保品"选择"是"时必填; /// [CheckConditionStringValue(ConditionName = nameof(PartyUseColl), ConditionValue = "true", CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNEQValue(ConditionName = nameof(PartyUseColl), ConditionValue = "true", CheckHandleNameArr = new[] { "B" })] @@ -264,7 +269,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 是否计算担保品价值产生利息 /// 长度:5 /// 必填:否 - /// 说明:检验规则:当"履约担保类型"为"部分担保"\"全额担保"时必填 + /// 说明:检验规则:当"履约担保类型"为"部分担保"、"全额担保"时必填 /// [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] @@ -277,11 +282,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 履约担保品初始比率(%) /// 长度:5,2 /// 必填:是 - /// 说明:校验规则:1 当"履约保障类型"选择"部分担保"或"全额担保"时必填;2 大于等于0的数字,最多2位小数,该值为100%时,填写100.00 + /// 说明:校验规则:大于等于0的数字,最多2位小数,该值为100%时,填写100.00 /// - [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0)] + [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MinValue = 0)] [DefaultValue("")] - [SacDescription("PerformanceCollInitialRatio", "履约担保品初始比率(%)", "5,2", true, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 大于等于0的数字,最多2位小数,该值为100%时,填写100.00;")] + [SacDescription("PerformanceCollInitialRatio", "履约担保品初始比率(%)", "5,2", true, "校验规则:大于等于0的数字,最多2位小数,该值为100%时,填写100.00;")] public string PerformanceCollInitialRatio { get; set; } /// /// 履约担保品追保比率(%) @@ -291,8 +296,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, CheckHandleName = "A")] - [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, Required = false, CheckHandleName = "B")] + [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MinValue = 0, CheckHandleName = "A")] + [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MinValue = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("PerformanceCollAddtlRatio", "履约担保品追保比率(%)", "5,2", false, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 大于等于0的数字,最多2位小数,该值为100%时,填写100.00;")] public string PerformanceCollAddtlRatio { get; set; } @@ -304,8 +309,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringNotInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "B" })] - [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, CheckHandleName = "A")] - [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MaxValue = 100, MinValue = 0, Required = false, CheckHandleName = "B")] + [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MinValue = 0, CheckHandleName = "A")] + [CheckStringIntMaxLength(BeforePointMaxLength = 3, AfterPointMaxLength = 2, MinValue = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] [SacDescription("PerformanceCollOffsetRatio", "履约担保品平仓比率(%)", "5,2", false, "校验规则:\r\n1 当履约保障类型选择部分担保或全额担保时必填;\r\n2 大于等于0的数字,最多2位小数,该值为100%时,填写100.00;")] public string PerformanceCollOffsetRatio { get; set; } @@ -347,6 +352,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckConditionStringInMap(ConditionName = nameof(PerformanceGuaranteeType), ConditionMap = new[] { "1", "2" }, CheckHandleNameArr = new[] { "A" })] [CheckIEnumerableTMinCount(CheckHandleName = "A", MinCount = 1)] [XmlElement] + [NotMapped] [SacDescription("PerformanceCollTuple", "履约担保品", "", false, "数组结构,支持新增多条;\r\n校验规则:字段信息详见收益互换交易确认书【履约担保品】。检验规则:当“履约担保类型”为“部分担保”或“全额担保”时必填;")] public List PerformanceCollTuple { get; set; } /// @@ -373,31 +379,31 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 标的个数 /// 长度:2 /// 必填:是 - /// 说明: 多标的时,权益收益\浮动利率收益固定利率收益信息需新增多个 + /// 说明: 多标的时,权益收益、浮动利率收益、固定利率收益信息需新增多个 /// [CheckStringInMap(Map = new[] { "0", "1" })] [DefaultValue("")] - [SacDescription("PtyAUndrlygAssetNo", "标的个数", "2", true, "多标的时,权益收益、浮动利率收益固定利率收益信息需新增多个;")] + [SacDescription("PtyAUndrlygAssetNo", "标的个数", "2", true, "多标的时,权益收益、浮动利率收益、固定利率收益信息需新增多个;")] public string PtyAUndrlygAssetNo { get; set; } /// /// 收益计算说明 /// 长度:1024 /// 必填:是 - /// 说明:甲方支付乙方,详细说明收益计算方式; + /// 说明:详细说明收益计算方式 /// [CheckStringMaxLength(MaxLength = 1024)] [DefaultValue("")] - [SacDescription("PtyAPrOfitCalculationInfo", "收益计算说明", "1024", true, "甲方支付乙方,详细说明收益计算方式;")] + [SacDescription("PtyAPrOfitCalculationInfo", "收益计算说明", "1024", true, "详细说明收益计算方式;")] public string PtyAPrOfitCalculationInfo { get; set; } /// /// 收益备注 /// 长度:1024 /// 必填:否 - /// 说明:甲方支付乙方,填写上述字段或交易确认书中不能包含的信息; + /// 说明:填写上述字段或交易确认书中不能包含的信息 /// [CheckStringMaxLength(MaxLength = 1024, Required = false)] [DefaultValue("")] - [SacDescription("PtyAProfitRemark", "收益备注", "1024", false, "甲方支付乙方,填写上述字段或交易确认书中不能包含的信息;")] + [SacDescription("PtyAProfitRemark", "收益备注", "1024", false, "填写上述字段或交易确认书中不能包含的信息;")] public string PtyAProfitRemark { get; set; } /// /// 甲方代签产品名称 @@ -451,6 +457,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("PytBPdctCode", "乙方交易对手码(产品)", "20", false, "校验规则:如乙方代签产品名称或乙方代签产品代码填值,则甲方代签产品名称和甲方代签产品代码禁止填值;")] public string PytBPdctCode { get; set; } + //TODO: 2.3互换上线时取消注释 + ///// + ///// 是否为跨境交易 + ///// 长度:5 + ///// 必填:是 + ///// 说明: + ///// + //[CheckStringInMap(Map = new[] { "true", "false" })] + //[DefaultValue("")] + //[SacDescription("CrossBorderTransactions", "是否为跨境交易", "5", true, "")] + //public string CrossBorderTransactions { get; set; } /// /// 空白1 /// @@ -468,7 +485,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 履约担保品详情 /// - public class SwapPerformanceGuaranteeAttModel + [Table("A1005_SwapPerformanceGuaranteeAtt")] + public class SwapPerformanceGuaranteeAttModel : ReportSubBaseModel { /// /// 履约担保品类型 @@ -510,12 +528,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("Remarks", "备注", "1024", false, "")] public string Remarks { get; set; } + + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号", "100", false, "")] + public string ConfirmationNo { get; set; } } /// /// 收益互换交易费用端支付 /// - public class PaymentMethodModel + [Table("A1005_PaymentMethod")] + public class PaymentMethodModel : ReportSubBaseModel { /// /// 支付方式 @@ -612,5 +636,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("Blank2", "空白2", "", false, "")] public string Blank2 { get; set; } + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号", "100", false, "")] + public string ConfirmationNo { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapDurationManagementModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapDurationManagementModel.cs index 04c22f7a..b117dbe1 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapDurationManagementModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapDurationManagementModel.cs @@ -1,4 +1,6 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +10,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 收益互换交易存续期管理 /// + [Table("A1006_SwapDurationManagement")] public class SwapDurationManagementModel : ReportBaseModel { /// @@ -57,12 +60,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 存续期操作类型 /// 长度:2 /// 必填:是 - /// 说明:当"收益互换交易类型"为"多空组合"时,可选"调仓" + /// 说明:当"收益互换交易类型"为"多空组合"时,可选"调仓" /// [CheckConditionStringValue(ConditionName = nameof(SwapType), ConditionValue = "2", CheckHandleNameArr = new[] { "A", "C" })] [CheckConditionStringNEQValue(ConditionName = nameof(SwapType), ConditionValue = "2", CheckHandleNameArr = new[] { "B", "C" })] - [CheckStringInMap(Map = new[] { "01", "04" }, CheckHandleName = "A")] - [CheckStringInMap(Map = new[] { "01", "02", "03" }, CheckHandleName = "B")] + [CheckStringInMap(Map = new[] { "1", "4" }, CheckHandleName = "A")] + [CheckStringInMap(Map = new[] { "1", "2", "3" }, CheckHandleName = "B")] [CheckStringIntMaxLength(MaxValue = 4, MinValue = 1, BeforePointMaxLength = 2, CheckHandleName = "C")] [DefaultValue("")] [SacDescription("DurationOperationType", "存续期操作类型", "2", true, "当收益互换交易类型为多空组合时,可选调仓;")] @@ -131,7 +134,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// 当"存续期操作类型"选择"调仓"时,可增可减 /// /// - [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03", "04" }, CheckHandleNameArr = new[] { "A" })] + [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "04" }, CheckHandleNameArr = new[] { "A" })] [CheckConditionStringInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03" }, CheckHandleNameArr = new[] { "B" })] [CheckConditionStringNotInMap(ConditionName = nameof(DurationOperationType), ConditionMap = new[] { "02", "03", "04" }, CheckHandleNameArr = new[] { "C" })] [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, CheckHandleName = "A")] @@ -170,14 +173,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [SacDescription("AmountPaidThisTime", "本次支付金额(元)", "36,2", false, "当存续期操作类型选择终止、违约终止、调仓时,必填;\r\n支付为正,收取为负;")] public string AmountPaidThisTime { get; set; } /// - /// 预付金比例(%) + /// 保证金比例(%) /// 长度:8,2 /// 必填:是 - /// 说明:为预付金占存量名义本金比例,其中多空组合收益互换存量名义本金为存量多头名义本金和空头名义本金孰大者 + /// 说明:为保证金占存量名义本金比例,其中多空组合收益互换存量名义本金为存量多头名义本金和空头名义本金孰大者 /// [CheckStringIntLength(BeforePointMaxLength = 8, AfterPointLength = 2)] [DefaultValue("")] - [SacDescription("MarginRatio", "预付金比例(%)", "8,2", true, "为预付金占存量名义本金比例,其中多空组合收益互换存量名义本金为存量多头名义本金和空头名义本金孰大者;")] + [SacDescription("MarginRatio", "保证金比例(%)", "8,2", true, "为保证金占存量名义本金比例,其中多空组合收益互换存量名义本金为存量多头名义本金和空头名义本金孰大者;")] public string MarginRatio { get; set; } /// /// 合约持仓明细 @@ -189,6 +192,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckConditionIntInRange(ConditionName = nameof(Balance), MinValue = 0, MaxValue = 0, CheckHandleNameArr = new[] { "B" })] [CheckIEnumerableTMaxCount(CheckHandleName = "A", MaxCount = 0)] [CheckIEnumerableTMaxCount(CheckHandleName = "B", MaxCount = 0)] + [NotMapped] [SacDescription("CurrentPositionDetails", "合约持仓明细", "", false, "校验规则:当存量名义本金(元)为0时,非必填;\r\n展期数据不允许添加合约持仓明细;")] public List CurrentPositionDetails { get; set; } /// @@ -216,7 +220,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 合约持仓明细 /// - public class CurrentPositionDetailModel + [Table("A1006_CurrentPositionDetail")] + public class CurrentPositionDetailModel : ReportSubBaseModel { /// /// 挂钩标的编码 @@ -320,5 +325,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("Blank2", "空白2", "", false, "")] public string Blank2 { get; set; } + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号", "100", false, "")] + public string ConfirmationNo { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapEquityPaymentModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapEquityPaymentModel.cs index a5917a43..162fafff 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapEquityPaymentModel.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/SwapEquityPaymentModel.cs @@ -1,4 +1,8 @@ -using System.ComponentModel; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Xml; +using System.Xml.Schema; using System.Xml.Serialization; using YLErp.Modules.SuperviseReportModule.SAC.Common; using static YLErp.DBModels.Consts.ConsReport; @@ -8,6 +12,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 收益互换交易权益端支付 /// + [Table("A1016_SwapEquityPayment")] public class SwapEquityPaymentModel : ReportBaseModel { /// @@ -27,13 +32,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringMaxLength(MaxLength = 100)] [DefaultValue("")] - [SacDescription("ConfirmationNo", "交易确认书", "100", true, "双方约定;")] + [SacDescription("ConfirmationNo", "交易确认书(双方约定)", "100", true, "双方约定;")] public string ConfirmationNo { get; set; } /// /// 权益端支付 /// [XmlElement] [CheckIEnumerableTMinCount(MinCount = 1)] + [NotMapped] [SacDescription("SwapEquityPaymentTuple", "权益端支付", "", false, "")] public List SwapEquityPaymentTuple { get; set; } /// @@ -50,7 +56,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringLengthInMap(Map = new[] { 4, 5 }, Required = false)] [SacDescription("DurationEventNO", "操作事件编号", "6", false, "首次随交易确认书上报时,不填;\r\n存续期发生相关事件时,必填;\r\n同一笔交易确认书下应当保证唯一性,并按照事件发生顺序进行编号,起始编号为0000.\r\n如一笔交易下依次发生展期、调仓、终止事件,编号应当分别为0000、0001、0002,\r\n场外业务报告系统返回编号分别为E0000、R0001、T0002;")] - public new string DurationEventNO { get; set; } + public new string? DurationEventNO { get; set; } /// /// 空白1 /// @@ -68,7 +74,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// /// 权益端支付 /// - public class SwapEquityPaymentTupleModel + [Table("A1016_SwapEquityPaymentTuple")] + public class SwapEquityPaymentTupleModel : ReportSubBaseModel { /// /// 支付方式 @@ -106,7 +113,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringIsDateTimeFormat] [DefaultValue("")] - [SacDescription("OpenandClosingDate", "标的开/平仓日期", "2", true, "yyyy-MM-dd;")] + [SacDescription("OpenandClosingDate", "标的开/平仓日期", "10", true, "yyyy-MM-dd;")] public string OpenandClosingDate { get; set; } /// /// 标的小类 @@ -197,7 +204,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, MinValue = 0, CheckHandleName = "A")] [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, MinValue = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("LNotinalPrincipleAmt", "多头名义本金", "36,2", false, "标的数量*合约乘数*标的价格;\r\n当支付方式选择权益收益(多头)、浮动利率收益、权益收益多空组合时,必填;")] + [SacDescription("LNotinalPrincipleAmt", "多头名义本金(元)", "36,2", false, "标的数量*合约乘数*标的价格;\r\n当支付方式选择权益收益(多头)、浮动利率收益、权益收益多空组合时,必填;")] public string LNotinalPrincipleAmt { get; set; } /// /// 空头名义本金(元) @@ -210,7 +217,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, MaxValue = 0, CheckHandleName = "A")] [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2, MaxValue = 0, Required = false, CheckHandleName = "B")] [DefaultValue("")] - [SacDescription("SNotinalPrincipleAmt", "空头名义本金", "36,2", false, "-(标的数量*合约乘数* 标的价格)\r\n当支付方式选择权益收益(空头)、浮动利率收益、权益收益多空组合时,必填;")] + [SacDescription("SNotinalPrincipleAmt", "空头名义本金(元)", "36,2", false, "-(标的数量*合约乘数* 标的价格)\r\n当支付方式选择权益收益(空头)、浮动利率收益、权益收益多空组合时,必填;")] public string SNotinalPrincipleAmt { get; set; } /// /// 利率(%) @@ -220,7 +227,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model /// [CheckStringIntLength(BeforePointMaxLength = 8, AfterPointLength = 2, MinValue = 0, Required = false)] [DefaultValue("")] - [SacDescription("InterestRate", "利率", "8,2", false, "校验规则:大于等于0的两位小数,如5.12;")] + [SacDescription("InterestRate", "利率(%)", "8,2", false, "校验规则:大于等于0的两位小数,如5.12;")] public string InterestRate { get; set; } /// /// 空白1 @@ -234,5 +241,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Model [DefaultValue("")] [SacDescription("Blank2", "空白2", "", false, "")] public string Blank2 { get; set; } + [XmlIgnore] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号", "100", false, "")] + public string ConfirmationNo { get; set; } } } \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ValuationInformationModel.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ValuationInformationModel.cs new file mode 100644 index 00000000..837745d2 --- /dev/null +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Model/ValuationInformationModel.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; +using YLErp.Modules.SuperviseReportModule.SAC.Common; +using static YLErp.DBModels.Consts.ConsReport; + +namespace YLErp.Modules.SuperviseReportModule.SAC.Model +{ + /// + /// 场外期权合约估值信息 + /// + [Table("A1018_ValuationInformation")] + public class ValuationInformationModel : ReportBaseModel + { + /// + /// 操作标识 + /// 长度:1 + /// 必填:是 + /// 说明: + /// + [XmlIgnore] + [SacDescription("OperationType", "操作标识", "1", true, "")] + public OptFlagsEnum OperationType { get; set; } + + /// + /// 交易确认书编号(双方约定) + /// 长度:100 + /// 必填:是 + /// 说明:双方约定 + /// + [CheckStringMaxLength(MaxLength = 100)] + [DefaultValue("")] + [SacDescription("ConfirmationNo", "交易确认书编号(双方约定)", "100", true, "双方约定;")] + public string ConfirmationNo { get; set; } + + /// + /// 估值日期 + /// 长度:10 + /// 必填:是 + /// 说明: + /// + [CheckStringLength(Length = 10)] + [CheckStringIsDateTimeFormat(FormatString = "yyyy-MM-dd")] + [DefaultValue("")] + [SacDescription("ValuationDate", "估值日期", "10", true, "")] + public string ValuationDate { get; set; } + + /// + /// 存量名义本金(元) + /// 长度:36,2 + /// 必填:是 + /// 说明:两位小数;大于等于0的数字 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, MinValue = 0)] + [DefaultValue("")] + [SacDescription("Balance", "存量名义本金(元)", "36,2", true, "大于等于0的数字;")] + public string Balance { get; set; } + + /// + /// 保证金比例(%) + /// 长度:8,2 + /// 必填:否 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 8, AfterPointMaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("MarginRatio", "保证金比例(%)", "8,2", false, "")] + public string MarginRatio { get; set; } + + /// + /// 期权估值 + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntLength(BeforePointMaxLength = 36, AfterPointLength = 2)] + [DefaultValue("")] + [SacDescription("OptionValuation", "期权估值", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string OptionValuation { get; set; } + + /// + /// Delta + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("Delta", "Delta", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string Delta { get; set; } + + /// + /// Gamma + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("Gamma", "Gamma", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string Gamma { get; set; } + + /// + /// Vega + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("Vega", "Vega", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string Vega { get; set; } + + /// + /// Theta + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("Theta", "Theta", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string Theta { get; set; } + + /// + /// Rho + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("Rho", "Rho", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string Rho { get; set; } + + /// + /// RhoQ + /// 长度:36,2 + /// 必填:否 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("RhoQ", "RhoQ", "36,2", false, "")] + public string RhoQ { get; set; } + + /// + /// DeltaCash + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("DeltaCash", "DeltaCash", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string DeltaCash { get; set; } + + /// + /// GammaCash + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("GammaCash", "GammaCash", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string GammaCash { get; set; } + + /// + /// VegaCash + /// 长度:36,2 + /// 必填:是 + /// 说明:期权生效后,每个交易日更新,直至期权终止 + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2)] + [DefaultValue("")] + [SacDescription("VegaCash", "VegaCash", "36,2", true, "期权生效后,每个交易日更新,直至期权终止;")] + public string VegaCash { get; set; } + + /// + /// ThetaCash + /// 长度:36,2 + /// 必填:否 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("ThetaCash", "ThetaCash", "36,2", false, "")] + public string ThetaCash { get; set; } + + /// + /// RhoCash + /// 长度:36,2 + /// 必填:否 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("RhoCash", "RhoCash", "36,2", false, "")] + public string RhoCash { get; set; } + + /// + /// RhoQCash + /// 长度:36,2 + /// 必填:否 + /// 说明: + /// + [CheckStringIntMaxLength(BeforePointMaxLength = 36, AfterPointMaxLength = 2, Required = false)] + [DefaultValue("")] + [SacDescription("RhoQCash", "RhoQCash", "36,2", false, "")] + public string RhoQCash { get; set; } + + /// + /// 空白1 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank1", "空白1", "", false, "")] + public string Blank1 { get; set; } + + /// + /// 空白2 + /// 长度: + /// 必填:否 + /// 说明: + /// + [XmlIgnore] + [DefaultValue("")] + [SacDescription("Blank2", "空白2", "", false, "")] + public string Blank2 { get; set; } + } +} \ No newline at end of file diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ContractNumberProcessService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ContractNumberProcessService.cs index 13f3815e..f5f701ec 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ContractNumberProcessService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ContractNumberProcessService.cs @@ -1,4 +1,4 @@ -using System.Data; +using DocumentFormat.OpenXml.Bibliography; using YLErp.DBModels.Enums; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; @@ -19,44 +19,46 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1015; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_ContractNumberProcess; + List noteList = new List(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - model.ContractNumberProcess = new ContractNumberProcessModel(); - model.ContractNumberProcess.MasterAgrmtTuple = new List(); - model.ContractNumberProcess.SupAgrmtTuple = new List(); - model.ContractNumberProcess.OptionConfirmationTuple = new List(); - model.ContractNumberProcess.SwapConfirmationTuple = new List(); - HashSet masterAgrmtTupleId = new HashSet(); - HashSet masterAgrmtTupleNo = new HashSet(); - HashSet supAgrmtTupleId = new HashSet(); - HashSet supAgrmtTupleNo = new HashSet(); - HashSet confirmationTupleId = new HashSet(); - HashSet confirmationTupleNo = new HashSet(); + var model = new BodyModel + { + ContractNumberProcess = new ContractNumberProcessModel + { + MasterAgrmtTuple = new List(), + SupAgrmtTuple = new List(), + OptionConfirmationTuple = new List(), + SwapConfirmationTuple = new List() + } + }; + var masterAgrmtTupleId = new HashSet(); + var masterAgrmtTupleNo = new HashSet(); + var supAgrmtTupleId = new HashSet(); + var supAgrmtTupleNo = new HashSet(); + var confirmationTupleId = new HashSet(); + var confirmationTupleNo = new HashSet(); string id = "", no = ""; if (_excelDataSource != null && _excelDataSource.Tables.Contains("双方约定编号数据明细")) { - DataTable dt = _excelDataSource.Tables["双方约定编号数据明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["双方约定编号数据明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -137,27 +139,44 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.ContractNumberProcess.SwapConfirmationTuple.Add(new ChangeOptionConfirmationModel()); } + ReportService.EditContractNumber(DbContextFactory.GetYLDbContext(), model.ContractNumberProcess, out _); + var note = new SACReportNotes(); + note.IsValid = true; + note.InfoCache = $"{{\"Tag\":\"\"}}"; + note.ExceId = model.ContractNumberProcess.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = BusiDataType.ToString(); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); } return model; } protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model.ContractNumberProcess != null) { - List listRoot = new List(); - CheckHelper helper = new CheckHelper(); - CheckHelper masterAgrmtHelper = new CheckHelper(); - CheckHelper supAgrmtHelper = new CheckHelper(); - CheckHelper optionConfirmationHelper = new CheckHelper(); + var listRoot = new List(); + var helper = new CheckHelper(); + var masterAgrmtHelper = new CheckHelper(); + var supAgrmtHelper = new CheckHelper(); + var optionConfirmationHelper = new CheckHelper(); helper.ExecuteCheck(model.ContractNumberProcess, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.ContractNumberProcess.MasterAgrmtTuple != null) { - for (int i = 0; i < model.ContractNumberProcess.MasterAgrmtTuple.Count; i++) + for (var i = 0; i < model.ContractNumberProcess.MasterAgrmtTuple.Count; i++) { var listItem = new List(); var item = model.ContractNumberProcess.MasterAgrmtTuple[i]; @@ -167,15 +186,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("MasterAgrmtTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("MasterAgrmtTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.ContractNumberProcess.SupAgrmtTuple != null) { - for (int i = 0; i < model.ContractNumberProcess.SupAgrmtTuple.Count; i++) + for (var i = 0; i < model.ContractNumberProcess.SupAgrmtTuple.Count; i++) { var listItem = new List(); var item = model.ContractNumberProcess.SupAgrmtTuple[i]; @@ -185,15 +206,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("SupAgrmtTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("SupAgrmtTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.ContractNumberProcess.OptionConfirmationTuple != null) { - for (int i = 0; i < model.ContractNumberProcess.OptionConfirmationTuple.Count; i++) + for (var i = 0; i < model.ContractNumberProcess.OptionConfirmationTuple.Count; i++) { var listItem = new List(); var item = model.ContractNumberProcess.OptionConfirmationTuple[i]; @@ -203,15 +226,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("OptionConfirmationTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("OptionConfirmationTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.ContractNumberProcess.SwapConfirmationTuple != null) { - for (int i = 0; i < model.ContractNumberProcess.SwapConfirmationTuple.Count; i++) + for (var i = 0; i < model.ContractNumberProcess.SwapConfirmationTuple.Count; i++) { var listItem = new List(); var item = model.ContractNumberProcess.SwapConfirmationTuple[i]; @@ -221,21 +246,42 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("SwapConfirmationTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("SwapConfirmationTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("ContractNumberProcess"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("ContractNumberProcess") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } checkStatus = result.Count > 0; return result; } + + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //这个报告只有新增,不存在后续报送,所以InfoTag中只有报告类型,不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + + public override bool BeforeOfGenerated(out string errMsg) + { + errMsg = ""; + for (int i = 0; i < noteList.Count; i++) + { + base.SaveReportNotes(noteList[i]); + } + return true; + } + } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportBaseService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportBaseService.cs index 70c70cd5..0d14d7a1 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportBaseService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportBaseService.cs @@ -1,4 +1,6 @@ -using Oracle.ManagedDataAccess.Client; +using BaseOUDAL; +using NPOI.OpenXmlFormats.Dml.Diagram; +using Oracle.ManagedDataAccess.Client; using System.Data; using System.Diagnostics; using System.Text; @@ -45,12 +47,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// /// 子系统报送文件目录 /// - protected List xmlAttachmentList = new List(); + protected List xmlAttachmentList = new(); /// /// /// - protected TempFilesService tempFilesService = null; + protected TempFilesService? tempFilesService = null; protected ReportBaseService(OptUserInfo optUser) : base(optUser) { @@ -66,6 +68,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected abstract DataFlagsEnum BusiDataType { get; } + protected virtual string CacheKey => $"{BusiDataType}"; + protected abstract SuperviseReportTypeEnum ReportType { get; } /// /// 支持的操作类型 @@ -78,7 +82,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// protected OptFlagsEnum _operationType { get; private set; } - private YLContext _writeDb = null; + private YLContext? _writeDb = null; public YLContext WriteDb { get @@ -102,29 +106,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public ReportRootModel Execute(ReportInfo req, OptFlagsEnum operationType) { - LogFactory.GetLogger("Executeone").Info($"PS.Config.ErpElement.SAC_ReportDataSource111:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); - _reqInfo = req; + + LogFactory.GetLogger("Executeone").Info($"PS.Config.ErpElement.SAC_ReportDataSource:" + _reqInfo.DataSource.ToString()); _operationType = operationType; - ReportRootModel root = new ReportRootModel(); + var root = new ReportRootModel(); try { root.Annex = new List(); - LogFactory.GetLogger("Execute22").Info($"PS.Config.ErpElement.SAC_ReportDataSource111:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); loadExcelDataSource(); - LogFactory.GetLogger("Execute22").Info($"PS.Config.ErpElement.SAC_ReportDataSource111:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); - - LogFactory.GetLogger("Execute111").Info($"PS.Config.ErpElement.SAC_ReportDataSource111:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView) - { - LogFactory.GetLogger("Execute111").Info($"PS.Config.ErpElement.SAC_ReportDataSource222:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); - loadViewDataSource(); - } root.Header = GenerateHeader(); FileTag = root.FileTag; - root.Body = GenerateBody(out bool noData, out List fileList); + root.Body = GenerateBody(out var noData, out var fileList); if (noData) { return null; } root.Annex.AddRange(fileList); @@ -168,13 +163,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private HeaderModel GenerateHeader() { - HeaderModel model = new HeaderModel(); - model.SenderCode = _reqInfo.SenderCode; - model.ReceiverCode = _reqInfo.ReceiverCode; - model.SendDate = _reqInfo.ReportDate.ToString("yyyy-MM-dd"); - model.FileNumber = FileNumber.ToString("0000"); - model.BusiDataType = BusiDataType; - model.OperationType = _operationType.ToString(); + var model = new HeaderModel + { + SenderCode = _reqInfo.SenderCode, + ReceiverCode = _reqInfo.ReceiverCode, + SendDate = _reqInfo.ReportDate.ToString("yyyy-MM-dd"), + FileNumber = FileNumber.ToString("0000"), + BusiDataType = BusiDataType, + OperationType = _operationType.ToString() + }; return model; } @@ -193,7 +190,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service errMsg = "接收方编号不应为空"; return false; } - if (req.ReportDate == default(DateTime)) + if (req.ReportDate == default) { errMsg = "报送日期不应为空"; return false; @@ -206,7 +203,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service SacInfo errMsg = null; if (model != null) { - List listRoot = new List(); + var listRoot = new List(); var headerItem = CheckHeaderValue(model?.Header, out _); if (headerItem != null) { @@ -215,8 +212,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var bodyItem = CheckBodyValue(model?.Body, out _); if (bodyItem.Count > 0) { - var item = new SacInfo("Body"); - item.SubMaps = bodyItem; + var item = new SacInfo("Body") + { + SubMaps = bodyItem + }; listRoot.Add(item); } model.XmlStr = XmlHelper.Serializable(model, true); @@ -234,8 +233,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (listRoot.Count > 0) { - errMsg = new SacInfo("Root"); - errMsg.SubMaps = new List(listRoot); + errMsg = new SacInfo("Root") + { + SubMaps = new List(listRoot) + }; errMsg.formatFieldDescription(); } } @@ -246,16 +247,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private SacInfo CheckHeaderValue(HeaderModel model, out bool checkStatus) { SacInfo errMsg = null; - List listRoot = new List(); - CheckHelper helper = new CheckHelper(); + var listRoot = new List(); + var helper = new CheckHelper(); helper.ExecuteCheck(model, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (listRoot.Count > 0) { - errMsg = new SacInfo("Header"); - errMsg.SubMaps = new List(listRoot); + errMsg = new SacInfo("Header") + { + SubMaps = new List(listRoot) + }; } checkStatus = errMsg == null; return errMsg; @@ -263,29 +266,48 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected void SaveReportNotes(SACReportNotes sacReportNotes) { - sacReportNotes.DataId = sacReportNotes.DataId ?? ""; + sacReportNotes.DataId ??= ""; WriteDb.sac_report_notes.Add(sacReportNotes); } + /// + /// 初始化报告记录 + /// + /// + /// + protected IEnumerable InitReportNotes(SuperviseReportTypeEnum reportType) + { + return DbContext.sac_report_notes.AsNoTracking().Where(O => O.ReportType == reportType).ToList(); + } + /// /// 获取报送记录 /// /// 报告标识 - /// 是否忽略无效的交易 + /// 是否需要无效的记录 /// - protected List GetReportNotes(string infoTag, bool ignoreInValid = false) + protected List GetReportNotes(string infoTag, bool needInValid = false, IEnumerable dataSource = null) { - var query = DbContext.sac_report_notes.AsNoTracking().Where(O => O.InfoTag.Contains(infoTag) && O.ReportResponse); - if (!ignoreInValid) + IQueryable query; + if (dataSource == null) + { + query = DbContext.sac_report_notes.AsNoTracking(); + } + else + { + query = dataSource.AsQueryable(); + } + query = query.Where(O => O.InfoTag.Contains(infoTag) && O.ReportResponse); + if (!needInValid) { query = query.Where(O => O.IsValid); } return query.OrderByDescending(O => O.OptTime).ToList(); } - protected List GetReportNotes(SuperviseReportTypeEnum reportType, string infoTag, bool ignoreInValid = false) + protected List GetReportNotes(SuperviseReportTypeEnum reportType, string infoTag, bool needInValid = false, IEnumerable dataSource = null) { - return GetReportNotes(infoTag, ignoreInValid).Where(O => O.ReportType == reportType).ToList(); + return GetReportNotes(infoTag, needInValid, dataSource).Where(O => O.ReportType == reportType).ToList(); } /// @@ -304,8 +326,45 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return transactionConfirmationNumber; } + /// + /// 检查生成内容是否合规 + /// + /// + /// + /// protected abstract List CheckBodyValue(BodyModel model, out bool checkStatus); + /// + /// 修改InfoTag中的编号 + /// + /// 原始InfoTag + /// 要修改的编号 + /// + /// 修改后的InfoTag + /// + protected abstract string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode); + + /// + /// 修改InfoTag中的编号 + /// + /// 原始InfoTag + /// 要修改的编号 + /// + /// 修改后的InfoTag + public string ChangeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + if (string.IsNullOrEmpty(infoTag)) + { + throw new ArgumentException($"“{nameof(infoTag)}”不能为 null 或空。", nameof(infoTag)); + } + + if (string.IsNullOrEmpty(newCode)) + { + throw new ArgumentException($"“{nameof(newCode)}”不能为 null 或空。", nameof(newCode)); + } + return _changeCodeOfInfoTag(infoTag, newCode, out originalCode); + } + /// /// 全部报表生成成功后执行 /// @@ -372,6 +431,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service case SuperviseReportTypeEnum.SAC_ConfirmationAtt: service = new ReportSwapConfirmationAttService(optUser); break; + case SuperviseReportTypeEnum.SAC_OptionConfirmationAtt: + service = new ReportOptionConfirmationAttService(optUser); + break; + case SuperviseReportTypeEnum.SAC_ValuationInformation: + service = new ReportValuationInformationService(optUser); + break; default: throw new ServiceException("报表未实现"); } @@ -384,31 +449,48 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { return ""; } - string directory = $"/App_Docs/Download/Report/"; - string absDirectory = OtcAppContext.MapPath(directory); + var directory = $"/App_Docs/Download/Report/"; + var absDirectory = OtcAppContext.MapPath(directory); checkDirectory(absDirectory); - string tempFile = Path.Combine(absDirectory, "Temp", res.FileTag); + var tempFile = Path.Combine(absDirectory, "Temp", res.FileTag); checkDirectory(tempFile, true); - string attachmentPath = Path.Combine(tempFile, "ATTACHMENT"); + var attachmentPath = Path.Combine(tempFile, "ATTACHMENT"); checkDirectory(attachmentPath); foreach (var item in res.Infos) { File.WriteAllText(Path.Combine(tempFile, item.FileTag + ".xml"), item.XmlStr); - for (int i = 0; i < item.Annex.Count; i++) + for (var i = 0; i < item.Annex.Count; i++) { if (string.IsNullOrWhiteSpace(item.Annex[i])) { continue; } - string annexPath = item.Annex[i]; + var annexPath = item.Annex[i]; + LogFactory.GetLogger().Info($"附件路径:{annexPath}"); if (annexPath.StartsWith("\\") || annexPath.StartsWith("/") || !Path.IsPathRooted(annexPath)) { annexPath = OtcAppContext.MapPath(item.Annex[i]); + if (!OperatingSystem.IsWindows()) + { + //修复linux环境下绝对路径MapPath处理结果会增加系统根目录的问题; + if (!File.Exists(annexPath)) + { + annexPath = item.Annex[i]; + } + } + LogFactory.GetLogger().Info($"附件物理路径:{annexPath}"); } - string annexFileName = Path.GetFileName(annexPath); + var annexFileName = Path.GetFileName(annexPath); try { - File.Copy(annexPath, Path.Combine(attachmentPath, annexFileName)); + var destFileName = Path.Combine(attachmentPath, annexFileName); + //国元固收从金仕达获取的交易确认书附件会有多笔交易指向同一附件的情况,做特殊处理. + if (PS.Config.Company == Configuration.CompanyEnum.国元固收 && File.Exists(destFileName)) + { + continue; + } + LogFactory.GetLogger().Info($"附件目标路径:{destFileName}"); + File.Copy(annexPath, destFileName); } catch (Exception ex) { @@ -418,7 +500,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } var zipFile = res.FileTag + ".zip"; - string outFile = Path.Combine(OtcAppContext.MapPath(directory), zipFile); + var outFile = Path.Combine(OtcAppContext.MapPath(directory), zipFile); ZipHelper.ZipDirectory(tempFile, outFile); return Path.Combine(directory, zipFile); } @@ -431,14 +513,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private static SacInfo ValidationXSD(string xmlStr, string xsdPath) { SacInfo result = null; - List listRoot = new List(); - XmlSchemaSet schema = new XmlSchemaSet(); + var listRoot = new List(); + var schema = new XmlSchemaSet(); schema.Add("", xsdPath); - XmlReader reader = XmlReader.Create(new StringReader(xmlStr)); - XDocument doc = XDocument.Load(reader); + var reader = XmlReader.Create(new StringReader(xmlStr)); + var doc = XDocument.Load(reader); doc.Validate(schema, (obj, e) => { - string msg = Regex.Replace(e.Message, @"元素[^,]+,", ""); + var msg = Regex.Replace(e.Message, @"元素[^,]+,", ""); msg = Regex.Replace(msg, @"\s-\s[\D]+约束失败。", "").Replace("“", "").Replace("”", ""); var name = ""; try @@ -451,8 +533,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listRoot.Count > 0) { - result = new SacInfo("Body"); - result.SubMaps = new List(listRoot); + result = new SacInfo("Body") + { + SubMaps = new List(listRoot) + }; } return result; } @@ -478,10 +562,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// protected string GetSACUndrlygAssetDtldTypeMap(ExpandoDictionary undrlygAssetDtldTypeMap, string underlyingInstrumentType, string commodityCode) { - string result; var desc = ConsGlobal.InstrumentType.GetDesc(underlyingInstrumentType); - if (!undrlygAssetDtldTypeMap.TryGetValue(desc, out result)) + if (!undrlygAssetDtldTypeMap.TryGetValue(desc, out var result)) { switch (desc) { @@ -523,7 +606,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// protected string GetDataSetValue(DataTable dt, int rowIndex, int colIndex) { - string result = ""; + var result = ""; if (dt != null) { if (dt.Rows.Count <= rowIndex @@ -543,18 +626,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// /// /// - protected string GetDataSetValue(DataTable dt, int rowIndex, string colName) + protected string GetDataSetValue(DataRow row, string colName) { - string result = ""; - if (dt != null) + var result = ""; + try { - if (!dt.Columns.Contains(colName)) - { - LogFactory.GetLogger("GetDataSetValue").Info($"{dt.TableName} 不存在[{colName}]列数据"); - //throw new ServiceException($"{dt.TableName} 不存在[{colName}]列数据"); - return ""; - } - result = dt.Rows[rowIndex][colName].ToString().Trim(); + result = row[colName].ToString().Trim(); + } + catch (Exception) + { + LogFactory.GetLogger("GetDataSetValue").Info($"{row.Table.TableName} 不存在[{colName}]列数据"); + result = ""; } return result; } @@ -566,17 +648,34 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// /// /// - protected double GetDataSetValueToDouble(DataTable dt, int rowIndex, string colName) + protected double GetDataSetValueToDouble(DataRow row, string colName) { - double result = 0; - var str = GetDataSetValue(dt, rowIndex, colName); - if (str == null || !double.TryParse(str, out result)) + var str = GetDataSetValue(row, colName); + if (str == null || !double.TryParse(str, out var result)) { result = 0; } return result; } + + /// + /// 从_excelDataSource中获取汇总信息 + /// + /// + /// + /// + /// + protected double? GetDataSetValueToDoubleOrNull(DataTable dt, int rowIndex, int colIndex) + { + var str = GetDataSetValue(dt, rowIndex, colIndex); + if (str == null || !double.TryParse(str, out var result)) + { + return null; + } + return result; + } + /// /// 从_excelDataSource中获取指定信息 /// @@ -586,9 +685,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// protected double GetDataSetValueToDouble(DataTable dt, int rowIndex, int colIndex) { - double result = 0; var str = GetDataSetValue(dt, rowIndex, colIndex); - if (str == null || !double.TryParse(str, out result)) + if (str == null || !double.TryParse(str, out var result)) { result = 0; } @@ -597,8 +695,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected void loadExcelDataSource() { - if (((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template || - BusiDataType == DataFlagsEnum.A1011 || + if ((_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template) || + //BusiDataType == DataFlagsEnum.A1011 || BusiDataType == DataFlagsEnum.A1012 || BusiDataType == DataFlagsEnum.A1013) && !string.IsNullOrWhiteSpace(_excelDataSourcePath)) @@ -609,12 +707,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return; } _excelDataSourceRootPath = $"{Path.GetDirectoryName(rootPath)}\\{Path.GetFileNameWithoutExtension(rootPath)}\\"; - string path = $"{_excelDataSourceRootPath}{_excelDataSourcePath}"; + var path = $"{_excelDataSourceRootPath}{_excelDataSourcePath}"; LogFactory.GetLogger("loadExcelDataSource").Info($"查找数据源目录:{path}"); path = OtcAppContext.MapPath(path); if (System.IO.Directory.Exists(path)) { - string filePath = System.IO.Directory.GetFiles(path, _excelDataSourceFileName).FirstOrDefault(); + var filePath = System.IO.Directory.GetFiles(path, _excelDataSourceFileName).FirstOrDefault(); LogFactory.GetLogger("loadExcelDataSource").Info($"查找数据源文件:{filePath}"); if (!string.IsNullOrWhiteSpace(filePath)) { @@ -702,23 +800,34 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string GetDataReaderValue(OracleDataReader dr, string fieldName) { - string result = ""; - if (dr == null) return result; + var result = ""; + if (dr == null) + { + return result; + } + result = dr[fieldName] == DBNull.Value ? "" : dr[fieldName].ToString(); return result; } - private void SetOneColumnData(OracleDataReader dr, DataRow row, string fieldName) + private string SetOneColumnData(OracleDataReader dr, DataRow row, string fieldName) { - SetOneColumnData(dr, row, fieldName, ""); + return SetOneColumnData(dr, row, fieldName, ""); } - private void SetOneColumnData(OracleDataReader dr, DataRow row, string fieldName, string toFileName = "") + private string SetOneColumnData(OracleDataReader dr, DataRow row, string fieldName, string toFileName = "") + { + var value = GetDataReaderValue(dr, fieldName); + return SetOneColumnData(value, row, fieldName, toFileName); + } + + private string SetOneColumnData(string value, DataRow row, string fieldName, string toFileName = "") { if (string.IsNullOrEmpty(toFileName)) - row[fieldName] = GetDataReaderValue(dr, fieldName); + row[fieldName] = value; else - row[toFileName] = GetDataReaderValue(dr, fieldName); + row[toFileName] = value; + return value; } #region 交易确认书视图数据读取 @@ -733,10 +842,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service try { LogFactory.GetLogger("GetSwapConfirm").Info("进入GetSwapConfirm"); - string schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; + var schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; var dtSwapConfirm = CreateSwapConfirmDataTable(); - var dtSwapCollateral = CreateSwapCollateralDataTable(); - var dtPaymentMethod = CreatePaymentMethodDataTable(); LogFactory.GetLogger("GetSwapConfirm").Info("创建完3个DataTable结构"); var sqlStr = new StringBuilder(); @@ -756,13 +863,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } CreateSwapConfirmNewRow(dtSwapConfirm, dr); }); + if (dtSwapConfirm.Rows.Count > 0) + { + sqlStr.Clear(); + sqlStr.Append("SELECT collateral.*"); + sqlStr.Append($"FROM {schema}v_swap_collateral_A1005 collateral "); + sqlStr.Append($"WHERE collateral.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); - sqlStr.Clear(); - sqlStr.Append("SELECT collateral.*"); - sqlStr.Append($"FROM {schema}v_swap_collateral_A1005 collateral "); - sqlStr.Append($"WHERE collateral.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); + var dtSwapCollateral = CreateSwapCollateralDataTable(); + var dict = new Dictionary>(); - db.ExecuteSql(sqlStr.ToString(), dr => + db.ExecuteSql(sqlStr.ToString(), dr => { try { @@ -772,15 +883,19 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { LogFactory.GetLogger("GetSwapConfirm ExecuteSql CreateSwapPerformanceGuaranteeAttNewRow").Error(ex); } - CreateSwapCollateralNewRow(dtSwapCollateral, dr); + CreateSwapCollateralNewRow(dtSwapCollateral, dr, dict, setIndexDict); }); + dtSwapCollateral.ExtendedProperties["Index"] = dict; - sqlStr.Clear(); - sqlStr.Append("SELECT feepayment.*"); - sqlStr.Append($"FROM {schema}v_swap_fee_payment_A1005 feepayment "); - sqlStr.Append($"WHERE feepayment.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); + dict = new Dictionary>(); + sqlStr.Clear(); + sqlStr.Append("SELECT feepayment.*"); + sqlStr.Append($"FROM {schema}v_swap_fee_payment_A1005 feepayment "); + sqlStr.Append($"WHERE feepayment.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); - db.ExecuteSql(sqlStr.ToString(), dr => + var dtPaymentMethod = CreatePaymentMethodDataTable(); + + db.ExecuteSql(sqlStr.ToString(), dr => { try { @@ -790,14 +905,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { LogFactory.GetLogger("GetSwapConfirm ExecuteSql CreatePaymentMethodNewRow").Error(ex); } - CreatePaymentMethodNewRow(dtPaymentMethod, dr); + CreatePaymentMethodNewRow(dtPaymentMethod, dr, dict, setIndexDict); }); - LogFactory.GetLogger("GetSwapConfirm").Info("dtSwapConfirm Data:" + dtSwapConfirm.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapConfirm); - LogFactory.GetLogger("GetSwapConfirm").Info("CreateSwapCollateralNewRow Data:" + dtSwapCollateral.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapCollateral); - LogFactory.GetLogger("GetSwapConfirm").Info("dtPaymentMethod Data:" + dtPaymentMethod.ToStringContent()); - _viewDataSource.Tables.Add(dtPaymentMethod); + dtPaymentMethod.ExtendedProperties["Index"] = dict; + + _viewDataSource.Tables.Add(dtSwapConfirm); + _viewDataSource.Tables.Add(dtSwapCollateral); + _viewDataSource.Tables.Add(dtPaymentMethod); + LogFactory.GetLogger("GetSwapConfirm ExecuteSql dtSwapConfirm").Info($"dtSwapConfirm:{dtSwapConfirm.Rows.Count}"); + LogFactory.GetLogger("GetSwapConfirm ExecuteSql dtSwapCollateral").Info($"dtSwapCollateral:{dtSwapCollateral.Rows.Count}"); + LogFactory.GetLogger("GetSwapConfirm ExecuteSql dtPaymentMethod").Info($"dtPaymentMethod:{dtPaymentMethod.Rows.Count}"); + } LogFactory.GetLogger("GetSwapConfirm").Info("成功执行完离开GetSwapConfirm"); } catch (Exception ex) @@ -806,10 +924,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } - private void CreatePaymentMethodNewRow(DataTable dtPaymentMethod, OracleDataReader dr) + /// + /// 增加确认书-费用端支付记录 + /// + /// + /// + /// + /// + private void CreatePaymentMethodNewRow( + DataTable dtPaymentMethod, + OracleDataReader dr, + Dictionary> indexDict, + Action>, DataRow, string> action) { var newRow = dtPaymentMethod.NewRow(); - SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); + var no = SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); SetOneColumnData(dr, newRow, "PAYMENTMETHOD"); SetOneColumnData(dr, newRow, "PAYER"); SetOneColumnData(dr, newRow, "PAYMENTFREQ"); @@ -820,25 +949,51 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service SetOneColumnData(dr, newRow, "BLANK1", "BLANK1"); SetOneColumnData(dr, newRow, "BLANK2", "BLANK2"); dtPaymentMethod.Rows.Add(newRow); + action(indexDict, newRow, no); } - private void CreateSwapCollateralNewRow(DataTable dtSwapPerformanceGuaranteeAtt, OracleDataReader dr) + /// + /// 增加确认书-履约担保品记录 + /// + /// + /// + /// + /// + private void CreateSwapCollateralNewRow( + DataTable dtSwapPerformanceGuaranteeAtt, + OracleDataReader dr, + Dictionary> indexDict, + Action>, DataRow, string> action) { var newRow = dtSwapPerformanceGuaranteeAtt.NewRow(); - SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); + var no = SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); SetOneColumnData(dr, newRow, "PERFORMANCECOLLTYPE"); SetOneColumnData(dr, newRow, "PERFORMANCECOLLRANGE"); SetOneColumnData(dr, newRow, "MULTICONFIRMATIONID"); SetOneColumnData(dr, newRow, "REMARKS", "REMARKS"); dtSwapPerformanceGuaranteeAtt.Rows.Add(newRow); + action(indexDict, newRow, no); } + private static void setIndexDict(Dictionary> indexDict, DataRow row, string no) + { + if (!indexDict.ContainsKey(no)) + { + indexDict[no] = new List(); + } + indexDict[no].Add(row); + } + + /// + /// 增加确认书记录 + /// + /// + /// private void CreateSwapConfirmNewRow(DataTable dtSwapConfirm, OracleDataReader dr) { - LogFactory.GetLogger("CreateSwapConfirmNewRow").Info("进入CreateSwapConfirmNewRow"); var confirmationNo = GetDataReaderValue(dr, "CONFIRMATIONNO"); - var rows = dtSwapConfirm.Select("CONFIRMATIONNO='" + confirmationNo + "'"); - if (rows != null && rows.Count() > 0) return;//存在了就不用再加了 + var row = dtSwapConfirm.Rows.Find(confirmationNo); + if (row != null) return;//存在了就不用再加了 var newRow = dtSwapConfirm.NewRow(); @@ -889,12 +1044,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapConfirm.Rows.Add(newRow); LogFactory.GetLogger("CreateSwapConfirmNewRow").Info("退出CreateSwapConfirmNewRow"); } + + /// + /// 创建确认书表格 + /// + /// private DataTable CreateSwapConfirmDataTable() { var dtSwapConfirm = new DataTable("交易确认书"); dtSwapConfirm.Columns.Add("MASTERAGRMTNO"); dtSwapConfirm.Columns.Add("SUPAGRMNO"); - dtSwapConfirm.Columns.Add("CONFIRMATIONNO"); + var primaryKey = dtSwapConfirm.Columns.Add("CONFIRMATIONNO"); dtSwapConfirm.Columns.Add("FILLPARTY"); dtSwapConfirm.Columns.Add("SWAPTYPE"); dtSwapConfirm.Columns.Add("STARTDATE"); @@ -931,9 +1091,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapConfirm.Columns.Add("BLANK2"); dtSwapConfirm.Columns.Add("SUBMIT_STATUS"); dtSwapConfirm.Columns.Add("OPERATIONTYPE"); + + dtSwapConfirm.PrimaryKey = new DataColumn[] { primaryKey }; return dtSwapConfirm; } + /// + /// 创建确认书-履约担保品表格 + /// + /// private DataTable CreateSwapCollateralDataTable() { var dtSwapPerformanceGuaranteeAtt = new DataTable("履约担保品"); @@ -942,9 +1108,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapPerformanceGuaranteeAtt.Columns.Add("PERFORMANCECOLLRANGE"); dtSwapPerformanceGuaranteeAtt.Columns.Add("MULTICONFIRMATIONID"); dtSwapPerformanceGuaranteeAtt.Columns.Add("REMARKS"); + return dtSwapPerformanceGuaranteeAtt; } + /// + /// 创建确认书-费用端支付表格 + /// + /// private DataTable CreatePaymentMethodDataTable() { var dtPaymentMethod = new DataTable("费用端支付"); @@ -958,6 +1129,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtPaymentMethod.Columns.Add("BASEPOINT"); dtPaymentMethod.Columns.Add("BLANK1"); dtPaymentMethod.Columns.Add("BLANK2"); + return dtPaymentMethod; } @@ -975,11 +1147,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { try { - string schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; + var schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; LogFactory.GetLogger("GetSwapLifeCycle").Info("进入GetSwapLifeCycle"); var dtSwapLifeCycle = CreateSwapLifeCycleDataTable(); - var dtSwapLifeCyclePosDt = CreateSwapLifeCyclePosDtDataTable(); - LogFactory.GetLogger("GetSwapLifeCycle").Info("创建完2个DataTable结构"); var sqlStr = new StringBuilder(); sqlStr.Append("SELECT lifecycle.* "); sqlStr.Append($" FROM {schema}v_swap_lifecycle_A1006 lifecycle "); @@ -1001,29 +1171,38 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service CreateSwapLifeCycleNewRow(dtSwapLifeCycle, dr); }); - sqlStr.Clear(); - sqlStr.Append("SELECT posdt.* "); - sqlStr.Append($" FROM {schema}v_swap_lifecycle_pos_dt_A1006 posdt "); - sqlStr.Append($"WHERE posdt.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); - - LogFactory.GetLogger("GetSwapLifeCycle").Info($"sqlStr:{sqlStr}"); - - db.ExecuteSql(sqlStr.ToString(), dr => + if (dtSwapLifeCycle.Rows.Count > 0) { - try + sqlStr.Clear(); + sqlStr.Append("SELECT posdt.* "); + sqlStr.Append($" FROM {schema}v_swap_lifecycle_pos_dt_A1006 posdt "); + sqlStr.Append($"WHERE posdt.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'"); + + LogFactory.GetLogger("dtSwapLifeCyclePosDt").Info($"sqlStr:{sqlStr}"); + + var dtSwapLifeCyclePosDt = CreateSwapLifeCyclePosDtDataTable(); + var dict = new Dictionary>(); + + db.ExecuteSql(sqlStr.ToString(), dr => { - LogFactory.GetLogger("GetSwapLifeCycle ExecuteSql").Info("RowData:" + dr.ToStringContent()); - } - catch (Exception ex) - { - LogFactory.GetLogger("GetSwapLifeCycle ExecuteSql").Error(ex); - } - CreateSwapLifeCyclePosDtNewRow(dtSwapLifeCyclePosDt, dr); - }); - LogFactory.GetLogger("GetSwapLifeCycle").Info("dtSwapLifeCycle Data:" + dtSwapLifeCycle.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapLifeCycle); - LogFactory.GetLogger("GetSwapLifeCycle").Info("dtSwapLifeCyclePosDt Data:" + dtSwapLifeCyclePosDt.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapLifeCyclePosDt); + try + { + LogFactory.GetLogger("dtSwapLifeCyclePosDt ExecuteSql").Info("RowData:" + dr.ToStringContent()); + } + catch (Exception ex) + { + LogFactory.GetLogger("dtSwapLifeCyclePosDt ExecuteSql").Error(ex); + } + CreateSwapLifeCyclePosDtNewRow(dtSwapLifeCyclePosDt, dr, dict, setIndexDict); + }); + dtSwapLifeCyclePosDt.ExtendedProperties["Index"] = dict; + + _viewDataSource.Tables.Add(dtSwapLifeCycle); + _viewDataSource.Tables.Add(dtSwapLifeCyclePosDt); + LogFactory.GetLogger("dtSwapLifeCycle ExecuteSql dtSwapLifeCycle").Info($"dtSwapLifeCycle:{dtSwapLifeCycle.Rows.Count}"); + LogFactory.GetLogger("dtSwapLifeCycle ExecuteSql dtSwapLifeCyclePosDt").Info($"dtSwapLifeCyclePosDt:{dtSwapLifeCyclePosDt.Rows.Count}"); + LogFactory.GetLogger("dtSwapLifeCycle Index dtSwapLifeCyclePosDt").Info($"Index:{dict.Count}"); + } } catch (Exception ex) { @@ -1031,17 +1210,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } + /// + /// 增加存续期管理记录 + /// + /// + /// private void CreateSwapLifeCycleNewRow(DataTable dtSwapLifeCycle, OracleDataReader dr) { var confirmationNo = GetDataReaderValue(dr, "CONFIRMATIONNO"); - var rows = dtSwapLifeCycle.Select("CONFIRMATIONNO='" + confirmationNo + "'"); - if (rows != null && rows.Count() > 0) return;//存在了就不用再加了 + var row = dtSwapLifeCycle.Rows.Find(confirmationNo); + if (row != null) return;//存在了就不用再加了 var newRow = dtSwapLifeCycle.NewRow(); SetOneColumnData(dr, newRow, "BIZID"); SetOneColumnData(dr, newRow, "GUID"); SetOneColumnData(dr, newRow, "DURATIONEVENTNO"); - SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); + SetOneColumnData(confirmationNo, newRow, "CONFIRMATIONNO"); SetOneColumnData(dr, newRow, "DURATIONOPERATIONTYPE"); SetOneColumnData(dr, newRow, "DURATIONOPERATIONDATE"); SetOneColumnData(dr, newRow, "RENEWALDATE"); @@ -1061,11 +1245,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapLifeCycle.Rows.Add(newRow); } - private void CreateSwapLifeCyclePosDtNewRow(DataTable dtSwapLifeCyclePosDt, OracleDataReader dr) + /// + /// 增加持仓明细记录 + /// + /// + /// + /// + /// + private void CreateSwapLifeCyclePosDtNewRow( + DataTable dtSwapLifeCyclePosDt, + OracleDataReader dr, + Dictionary> indexDict, + Action>, DataRow, string> action) { var newRow = dtSwapLifeCyclePosDt.NewRow(); SetOneColumnData(dr, newRow, "GUID", "GUID"); - SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); + var no = SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); SetOneColumnData(dr, newRow, "BUSIDATE"); //SetOneColumnData(dr, newRow, "DURATIONOPERATIONTYPE"); SetOneColumnData(dr, newRow, "UNDRLYGASSETCODE"); @@ -1080,17 +1275,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service SetOneColumnData(dr, newRow, "BLANK1", "BLANK1"); SetOneColumnData(dr, newRow, "BLANK2", "BLANK2"); SetOneColumnData(dr, newRow, "DURATIONEVENTNO", "DURATIONEVENTNO"); + action(indexDict, newRow, no); dtSwapLifeCyclePosDt.Rows.Add(newRow); } + /// + /// 创建存续期管理表格 + /// + /// private DataTable CreateSwapLifeCycleDataTable() { var dtSwapLifeCycle = new DataTable("互换交易存续期管理"); dtSwapLifeCycle.Columns.Add("BIZID"); dtSwapLifeCycle.Columns.Add("GUID"); dtSwapLifeCycle.Columns.Add("DURATIONEVENTNO"); - dtSwapLifeCycle.Columns.Add("CONFIRMATIONNO"); + var primaryKey = dtSwapLifeCycle.Columns.Add("CONFIRMATIONNO"); dtSwapLifeCycle.Columns.Add("DURATIONOPERATIONTYPE"); dtSwapLifeCycle.Columns.Add("DURATIONOPERATIONDATE"); dtSwapLifeCycle.Columns.Add("RENEWALDATE"); @@ -1107,9 +1307,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapLifeCycle.Columns.Add("SUBMIT_STATUS"); dtSwapLifeCycle.Columns.Add("OPERATIONTYPE"); dtSwapLifeCycle.Columns.Add("BUSIDATE"); + + dtSwapLifeCycle.PrimaryKey = new DataColumn[] { primaryKey }; + return dtSwapLifeCycle; } + /// + /// 创建存续期管理-合约持仓明细表格 + /// + /// private DataTable CreateSwapLifeCyclePosDtDataTable() { var dtSwapLifeCyclePosDt = new DataTable("合约持仓明细"); @@ -1146,11 +1353,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { try { - string schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; + var schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; LogFactory.GetLogger("GetSwapequityPayment").Info("进入GetSwapequityPayment"); var dtSwapEquityPayment = CreateSwapEquityPaymentDataTable(); - var dtSwapEquityPaymentTP = CreateSwapEquityPaymentTPDataTable(); - LogFactory.GetLogger("GetSwapequityPayment").Info("创建完2个DataTable结构"); var sqlStr = new StringBuilder(); sqlStr.Append("SELECT quitypayment.* "); sqlStr.Append($"FROM {schema}v_swap_equity_payment_A1016 quitypayment "); @@ -1173,30 +1378,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service CreateSwapEquityPaymentNewRow(dtSwapEquityPayment, dr); }); - sqlStr.Clear(); - sqlStr.Append("SELECT equityaymenttp.* "); - sqlStr.Append($"FROM {schema}v_swap_equity_payment_tp_A1016 equityaymenttp "); - sqlStr.Append($"WHERE equityaymenttp.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'");//一对多分组 - - LogFactory.GetLogger("GetSwapequityPayment").Info($"sqlStr:{sqlStr}"); - - db.ExecuteSql(sqlStr.ToString(), dr => + if (dtSwapEquityPayment.Rows.Count > 0) { - try - { - LogFactory.GetLogger("GetSwapequityPayment ExecuteSql").Info("RowData:" + dr.ToStringContent()); - } - catch (Exception ex) - { - LogFactory.GetLogger("GetSwapequityPayment ExecuteSql").Error(ex); - } + sqlStr.Clear(); + sqlStr.Append("SELECT equityaymenttp.* "); + sqlStr.Append($"FROM {schema}v_swap_equity_payment_tp_A1016 equityaymenttp "); + sqlStr.Append($"WHERE equityaymenttp.BUSIDATE='{reportDate.ToString("yyyy-MM-dd")}'");//一对多分组 - CreateSwapEquityPaymentPtNewRow(dtSwapEquityPaymentTP, dr); - }); - LogFactory.GetLogger("GetSwapequityPayment").Info("dtSwapEquityPayment Data:" + dtSwapEquityPayment.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapEquityPayment); - LogFactory.GetLogger("GetSwapequityPayment").Info("dtSwapEquityPaymentTP Data:" + dtSwapEquityPaymentTP.ToStringContent()); - _viewDataSource.Tables.Add(dtSwapEquityPaymentTP); + LogFactory.GetLogger("dtSwapEquityPaymentTP").Info($"sqlStr:{sqlStr}"); + + var dtSwapEquityPaymentTP = CreateSwapEquityPaymentTPDataTable(); + var dict = new Dictionary>(); + + db.ExecuteSql(sqlStr.ToString(), dr => + { + try + { + LogFactory.GetLogger("dtSwapEquityPaymentTP ExecuteSql").Info("RowData:" + dr.ToStringContent()); + } + catch (Exception ex) + { + LogFactory.GetLogger("dtSwapEquityPaymentTP ExecuteSql").Error(ex); + } + + CreateSwapEquityPaymentPtNewRow(dtSwapEquityPaymentTP, dr, dict, setIndexDict); + }); + dtSwapEquityPaymentTP.ExtendedProperties["Index"] = dict; + + _viewDataSource.Tables.Add(dtSwapEquityPayment); + _viewDataSource.Tables.Add(dtSwapEquityPaymentTP); + LogFactory.GetLogger("dtSwapEquityPayment ExecuteSql dtSwapEquityPayment").Info($"dtSwapLifeCycle:{dtSwapEquityPayment.Rows.Count}"); + LogFactory.GetLogger("dtSwapEquityPayment ExecuteSql dtSwapEquityPaymentTP").Info($"dtSwapLifeCyclePosDt:{dtSwapEquityPaymentTP.Rows.Count}"); + LogFactory.GetLogger("dtSwapEquityPayment Index dtSwapEquityPayment").Info($"Index:{dict.Count}"); + } } catch (Exception ex) { @@ -1204,10 +1418,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } - private void CreateSwapEquityPaymentPtNewRow(DataTable dtSwapEquityPaymentPt, OracleDataReader dr) + /// + /// 增加权益端支付明细记录 + /// + /// + /// + /// + /// + private void CreateSwapEquityPaymentPtNewRow( + DataTable dtSwapEquityPaymentPt, + OracleDataReader dr, + Dictionary> indexDict, + Action>, DataRow, string> action) { var newRow = dtSwapEquityPaymentPt.NewRow(); - SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); + var no = SetOneColumnData(dr, newRow, "CONFIRMATIONNO"); SetOneColumnData(dr, newRow, "BUSIDATE"); SetOneColumnData(dr, newRow, "PAYMENTMETHOD"); SetOneColumnData(dr, newRow, "PAYER"); @@ -1228,16 +1453,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service SetOneColumnData(dr, newRow, "BLANK1"); SetOneColumnData(dr, newRow, "BLANK2"); SetOneColumnData(dr, newRow, "DURATIONEVENTNO"); + action(indexDict, newRow, no); dtSwapEquityPaymentPt.Rows.Add(newRow); } + /// + /// 增加权益端支付记录 + /// + /// + /// private void CreateSwapEquityPaymentNewRow(DataTable dtSwapEquityPayment, OracleDataReader dr) { var confirmationNo = GetDataReaderValue(dr, "CONFIRMATIONNO"); - var rows = dtSwapEquityPayment.Select("CONFIRMATIONNO='" + confirmationNo + "'"); - if (rows != null && rows.Count() > 0) return;//存在了就不用再加了 + var row = dtSwapEquityPayment.Rows.Find(confirmationNo); + if (row != null) return;//存在了就不用再加了 var newRow = dtSwapEquityPayment.NewRow(); @@ -1253,6 +1484,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service dtSwapEquityPayment.Rows.Add(newRow); } + /// + /// 创建权益端支付明细表格 + /// + /// private DataTable CreateSwapEquityPaymentTPDataTable() { var dtSwapEquityPaymentPt = new DataTable("权益端支付"); @@ -1280,18 +1515,24 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return dtSwapEquityPaymentPt; } + /// + /// 创建权益端支付表格 + /// + /// private DataTable CreateSwapEquityPaymentDataTable() { var dtSwapEquityPayment = new DataTable("互换交易权益端支付"); dtSwapEquityPayment.Columns.Add("BIZID"); dtSwapEquityPayment.Columns.Add("BUSIDATE"); - dtSwapEquityPayment.Columns.Add("CONFIRMATIONNO"); + var primaryKey = dtSwapEquityPayment.Columns.Add("CONFIRMATIONNO"); dtSwapEquityPayment.Columns.Add("DURATIONEVENTNO"); dtSwapEquityPayment.Columns.Add("SUBMIT_STATUS"); dtSwapEquityPayment.Columns.Add("OPERATIONTYPE"); dtSwapEquityPayment.Columns.Add("BLANK1"); dtSwapEquityPayment.Columns.Add("BLANK2"); + dtSwapEquityPayment.PrimaryKey = new DataColumn[] { primaryKey }; + return dtSwapEquityPayment; } @@ -1307,7 +1548,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { try { - string schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; + var schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; LogFactory.GetLogger("GetSwapConfirmationAtt").Info("进入GetSwapConfirmationAtt"); var dtSwapConfirmationAtt = CreateSwapConfirmationAttDataTable(); LogFactory.GetLogger("GetSwapConfirmationAtt").Info("创建完1个DataTable结构"); @@ -1329,7 +1570,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } CreatConfirmationAttNewRow(dtSwapConfirmationAtt, dr); }); - LogFactory.GetLogger("GetSwapConfirmationAtt").Info("dtSwapConfirmationAtt Data:" + dtSwapConfirmationAtt.ToStringContent()); _viewDataSource.Tables.Add(dtSwapConfirmationAtt); } catch (Exception ex) @@ -1372,9 +1612,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var subSystemOutboxPath = PS.Config.ErpElement.SAC_SubSystemOutboxPath; LogFactory.GetLogger("loadSubsystemDataSource").Info($"subSystemOutboxPath:" + subSystemOutboxPath); - if (string.IsNullOrEmpty(subSystemOutboxPath) || !Directory.Exists(subSystemOutboxPath)) return list; + if (string.IsNullOrEmpty(subSystemOutboxPath) || !Directory.Exists(subSystemOutboxPath)) + { + return list; + } - LogFactory.GetLogger("loadSubsystemDataSource").Info($"开始执行1"); + LogFactory.GetLogger("loadSubsystemDataSource").Info($"目录存在:{subSystemOutboxPath}"); var dateDir = _reqInfo.ReportDate.ToString("yyyyMMdd"); @@ -1382,13 +1625,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var folder = new DirectoryInfo(subSystemOutboxPath); var files = folder.GetFiles("*.zip"); LogFactory.GetLogger("loadSubsystemDataSource").Info($"zip文件个数:" + files.Count()); - if (files == null || files.Count() == 0) return list; + if (files == null || files.Count() == 0) + { + return list; + } + foreach (var file in files) { - LogFactory.GetLogger("loadSubsystemDataSource").Info($"2:"); + LogFactory.GetLogger("loadSubsystemDataSource").Info($"准备读取{file.Name}"); //zip压缩文件名包含报送日期才需要读取解析 - if (!file.Name.Contains("_" + dateDir + "_")) continue; - LogFactory.GetLogger("loadSubsystemDataSource").Info($"3:"); + if (!file.Name.Contains("_" + dateDir + "_")) + { + continue; + } + + LogFactory.GetLogger("loadSubsystemDataSource").Info($"文件名中包含{dateDir}"); //获取文件不包含扩展名的文件名 var tag = Path.GetFileNameWithoutExtension(file.FullName); //待解压的包含路径的完整文件名 @@ -1407,7 +1658,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("loadSubsystemDataSource").Info($"解压成功:targetName:" + targetName + ",tDir:" + tDir); } - LogFactory.GetLogger("loadSubsystemDataSource").Info($"4"); //存在说明已经解压过了 //解压后文件的附件根目录 var fileAttachmentDir = Path.Combine(subSystemOutboxPath, tag, "ATTACHMENT"); @@ -1422,11 +1672,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("loadSubsystemDataSource").Info($"reportFilesCount:" + reportFiles.Count()); foreach (var reportFile in reportFiles) { - LogFactory.GetLogger("loadSubsystemDataSource").Info($"6:"); + LogFactory.GetLogger("loadSubsystemDataSource").Info($"准备解析:{reportFile.FullName}"); //读取xml文件,并反序列化成对象 var xml = File.ReadAllText(reportFile.FullName); var model = XmlHelper.Deserialize(xml); - if (model.Body == null) continue; + if (model.Body == null) + { + continue; + } //记录xml报告文件,等读取完后,需要删掉 xmlAttachmentList.Add(reportFile.FullName); @@ -1443,7 +1696,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1468,7 +1724,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1493,7 +1752,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1519,7 +1781,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1544,7 +1809,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1569,7 +1837,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1595,7 +1866,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1621,7 +1895,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1647,7 +1924,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var flist = new List(); //调用委托构造notes数据 var ret = callback(x as T, flist, tag); - if (!ret) continue; + if (!ret) + { + continue; + } //把返回的附件文件名加上完整路径添加到附件集合待后边删除 flist.ForEach(attchment => { @@ -1665,6 +1945,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service case DataFlagsEnum.A1017: foreach (var x in model.Body.ConfirmationAtt) { + if (string.IsNullOrWhiteSpace(x.ConfirmationFilesTuple.FirstOrDefault()?.ConfirmationFiles)) + { + continue; + } x.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType, true); //子系统的数据忽略字段检查 x.IgnoreCheck = true; @@ -1687,6 +1971,63 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service list.Add(x as T); }; break; + case DataFlagsEnum.A1018: + foreach (var x in model.Body.ValuationInformation) + { + x.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType, true); + //子系统的数据忽略字段检查 + x.IgnoreCheck = true; + //通过调用委托返回业务的附件文件名数据 + var flist = new List(); + //调用委托构造notes数据 + var ret = callback(x as T, flist, tag); + if (!ret) continue; + //把返回的附件文件名加上完整路径添加到附件集合待后边删除 + flist.ForEach(attchment => + { + var path = Path.Combine(fileAttachmentDir, attchment); + //把附件添加到报告附件列表,为了生成报告 + fileList.Add(path); + //把附件添加到附件列表中,以便后边删除 + xmlAttachmentList.Add(path); + }); + + //添加数据到数据集合当中 + list.Add(x as T); + }; + break; + case DataFlagsEnum.A1019: + foreach (var x in model.Body.ConfirmationAtt) + { + if (string.IsNullOrWhiteSpace(x.ConfirmationFilesTuple.FirstOrDefault()?.ConfirmationAtt)) + { + continue; + } + x.OperationType = (OptFlagsEnum)Enum.Parse(typeof(OptFlagsEnum), model.Header.OperationType, true); + //子系统的数据忽略字段检查 + x.IgnoreCheck = true; + //通过调用委托返回业务的附件文件名数据 + var flist = new List(); + //调用委托构造notes数据 + var ret = callback(x as T, flist, tag); + if (!ret) + { + continue; + } + //把返回的附件文件名加上完整路径添加到附件集合待后边删除 + flist.ForEach(attchment => + { + var path = Path.Combine(fileAttachmentDir, attchment); + //把附件添加到报告附件列表,为了生成报告 + fileList.Add(path); + //把附件添加到附件列表中,以便后边删除 + xmlAttachmentList.Add(path); + }); + + //添加数据到数据集合当中 + list.Add(x as T); + }; + break; default: break; } @@ -1700,14 +2041,23 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// /// /// - protected string formatExceID() + protected string formatExceID(IEnumerable dataSource = null) { var exceId = ""; + IQueryable query; + if (dataSource != null) + { + query = dataSource.AsQueryable(); + } + else + { + query = DbContext.sac_report_notes; + } do { exceId = $"{_reqInfo.SenderCode}{_reqInfo.ReceiverCode}{_reqInfo.ReportDate.ToString("yyyyMMdd")}{MaxExceIndex.ToString("00000000")}"; MaxExceIndex = MaxExceIndex + 1; - } while (DbContext.sac_report_notes.Any(O => O.ExceId == exceId)); + } while (query.Any(O => O.ExceId == exceId)); return exceId; } @@ -1778,5 +2128,67 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var path = $"{configPath}/data/{viewAttFileName}"; return path; } + + /// + /// 从DataTable中获取索引字典 + /// + /// + /// + protected Dictionary> readIndexDict(string tableName) + { + Dictionary> result = null; + if (_viewDataSource != null && _viewDataSource.Tables.Contains(tableName)) + { + DataTable dt = _viewDataSource.Tables[tableName]; + if (dt.ExtendedProperties["Index"] is Dictionary> dict) + { + result = dict; + LogFactory.GetLogger("Index").Info($"取出索引:{dict.Count}"); + } + } + + return result; + } + + protected string formatUnderlyingCode(string underlyingCode, List dictItemMap, string name, string defaultValue = "") + { + if (underlyingCode == null || underlyingCode.Contains(".")) + { + return underlyingCode; + } + if (name == null || dictItemMap == null) { return defaultValue; } + var obj = dictItemMap.FirstOrDefault(O => O.Name == name); + var suffix = (obj == null ? defaultValue : obj.ShortName); + if (suffix.IsNullOrWhiteSpace()) + { + return underlyingCode; + } + return $"{underlyingCode}.{suffix}"; + } + + /// + /// 获取普通互换客户方向多空 山证金衍 逻辑 + /// + /// + /// + /// + /// + public string GetClientSideLongShort(bool isPayFloat, string getLongShort, string payLongShort) + { + string getPayStr = isPayFloat ? ("支付" + payLongShort) : ("收取" + getLongShort); + switch (getPayStr) + { + case "收取多头": + return "空头"; + case "收取空头": + return "多头"; + case "支付多头": + return "多头"; + case "支付空头": + return "空头"; + default: + return ""; + } + } } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportEventReportService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportEventReportService.cs index d48f7010..d5982fd2 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportEventReportService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportEventReportService.cs @@ -15,25 +15,23 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1009; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_EventReport; - List noteList = new List(); + + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -63,7 +61,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service errMsg = "重大事件报告非新增报送时,对应的业务编码不应为空"; return false; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(req.EventReportDate?.ToString("yyyy-MM-dd"))).Where(O => O.ReportDate == req.EventReportDate).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(req.EventReportDate?.ToString("yyyy-MM-dd"))).Where(O => O.ReportDate == req.EventReportDate).FirstOrDefault(); if (note == null) { errMsg = $"{req.EventReportDate?.ToString("yyyy-MM-dd")}不存在报送成功的重大事项报告记录,请重新选择"; @@ -72,7 +70,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (req.EventReportStatus == OptFlagsEnum.U) { var fileIds = tempFilesService.QueryTempFile(req.ReportDate, "重大事项报告").Select(O => O.id.ToString()).ToArray(); - string[] fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + var fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (!fileIds.Except(fileIdArr).Any()) { errMsg = $"{req.ReportDate.ToString("yyyy-MM-dd")}已上传重大事项报告附件都已报送成功,不需要再次报送"; @@ -103,9 +101,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList = new List(); noData = false; var noteKey = formatInfoTag(_reqInfo.ReportDate.ToString("yyyy-MM-dd")); - BodyModel model = new BodyModel(); - model.EventReport = new EventReportModel(); - SACReportNotes note = base.GetReportNotes(ReportType, noteKey).FirstOrDefault(); + var model = new BodyModel + { + EventReport = new EventReportModel() + }; + var note = base.GetReportNotes(ReportType, noteKey).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -161,8 +161,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { ReportStatus.AddCacheInfo(noteKey, item.fileName); } - var info = new EventReportDetailModel(); - info.EventReport = item.fileName; + var info = new EventReportDetailModel + { + EventReport = item.fileName + }; if (model.EventReport.EventReportTuple == null) { model.EventReport.EventReportTuple = new List(); @@ -173,7 +175,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } model.EventReport.DetailedDescription = _reqInfo.EventReportDesc; } - noData = (!(model.EventReport.EventReportTuple?.Count > 0)); + noData = !(model.EventReport.EventReportTuple?.Count > 0); if (!noData) { note.id = 0; @@ -197,19 +199,19 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model.EventReport != null) { - List listRoot = new List(); - CheckHelper helper = new CheckHelper(); - CheckHelper attHelper = new CheckHelper(); + var listRoot = new List(); + var helper = new CheckHelper(); + var attHelper = new CheckHelper(); helper.ExecuteCheck(model.EventReport, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.EventReport.EventReportTuple != null) { - for (int i = 0; i < model.EventReport.EventReportTuple.Count; i++) + for (var i = 0; i < model.EventReport.EventReportTuple.Count; i++) { var listItem = new List(); var item = model.EventReport.EventReportTuple[i]; @@ -219,16 +221,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("EventReportTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("EventReportTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("EventReport"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("EventReport") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -238,7 +244,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(string tag, bool suffixType = false) { - string result = $"{BusiDataType}_{tag}_"; + var result = $"{BusiDataType}_{tag}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -246,10 +252,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtProductService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtProductService.cs index 76192987..70dd9bac 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtProductService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtProductService.cs @@ -23,168 +23,38 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1002; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_MasterAgrmtProduct; - List noteList = new List(); + + readonly List noteList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { - dataList = GetMasterAgrmtProductModel(ref fileList); - } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - using (var baseDb = DbContextFactory.GetClientDbContext(null)) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var fileObjList = (from c in baseDb.client - join cf in baseDb.client_file - on c.id equals cf.ClientId - where c.ProcessStatus == "已开户" && cf.HasSent == false && cf.IsValid && - cf.FileTypeName == ConsGlobal.ClientFileType.AllographProduct && cf.OptState == _operationType && - ((c.ProcessOptDate >= _reqInfo.ReportDate && c.ProcessOptDate < nextDate && cf.OptDate < nextDate) ||//如果这一天开户,则把这一天之前(含这一天)的所有文件都报送了 - (cf.OptDate >= _reqInfo.ReportDate && cf.OptDate < nextDate && c.ProcessOptDate < _reqInfo.ReportDate))//如果这一天不是开户日期,则只在报送日期大于开户日期时,报送当日修改的文件 - && cf.ApprovalOrder < 1 - select new - { - cf.id, - cf.ClientId, - cf.OptState, - cf.ProtocolNumber, - cf.MainProtocolNumber, - cf.SignDate, - cf.FilePath, - cf.FileName, - c.Name, - c.ClientType, - c.Number, - c.ParentId, - }).ToArray(); - var clientIds = fileObjList.Select(O => O.ClientId); - var ct = baseDb.contactype.Where(O => O.ContactType == "产品投资经理").FirstOrDefault(); - ExpandoDictionary clientdutyDict = null; - if (ct != null) - { - clientdutyDict = new ExpandoDictionary( - (from cd in baseDb.clientduty.Where(t => t.ApprovalOrder < 1) - where clientIds.Contains(cd.ClientId ?? 0) && (cd.DeadLine == null || cd.DeadLine >= _reqInfo.ReportDate) - select cd) - .ToList() - .Where(O => O.ContactTypeIdsInt.Contains(ct.id)).GroupBy(O => O.ClientId ?? 0) - .ToDictionary(K => K.Key, V => V.FirstOrDefault())); - } - var cacheKey = $"{BusiDataType}"; - var service = new ClientQueryService(UserInfo); - foreach (var item in fileObjList) - { - if (item.ClientType != "产品") { continue; } - var info = new MasterAgrmtProductModel(); - info.ClientType = item.ClientType; - info.MasterAgrmtNo = item.MainProtocolNumber; - info.OperationType = item.OptState; - info.ProductName = service.GetProductName(item.ClientId); - if (string.IsNullOrWhiteSpace(info.ProductName)) - { - info.ProductName = item.Name; - } - info.CounterpartyCodeProducts = item.Number; - info.ManagerName = clientdutyDict == null ? null : clientdutyDict[item.ClientId]?.ContactName; - info.InvestmentManagerContactNumber = clientdutyDict == null ? null : clientdutyDict[item.ClientId]?.PhoneNumber; - info.TrusteeAgency = service.GetTrusteeAgency(item.ClientId);// ?? DataCacheProvider.GetClientDataSource().GetData(item.ParentId)?.Name; - info.TheDateTable = item.SignDate?.ToString("yyyy-MM-dd"); - info.SuchProducts = item.FileName; - var cacheValue = info.MasterAgrmtNo + "_" + info.ProductName; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{info.ProductName}\",\"Source\":\"System\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.ProductNo = note.BizId; - } - note.id = 0; - info.ExceID = base.formatExceID(); - note.DataId = item.id.ToString(); - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.changeStatus = false; - if (!ReportStatus.CheckFileLength(item.FilePath)) - { - break; - } - else - { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - } - dataList.Add(info); - fileList.Add(item.FilePath); - note.ExceId = info.ExceID; - noteList.Add(note); - } - } + dataList.AddRange(GetMasterAgrmtProductModelFromExcel(ref fileList)); } var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.MasterAgrmtProduct = dataList; @@ -193,7 +63,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(MasterAgrmtProductModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -244,16 +114,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - - private List GetMasterAgrmtProductModel(ref List fileList) + private List GetMasterAgrmtProductModelFromExcel(ref List fileList) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("主协议关联产品列表")) { - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["主协议关联产品列表"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["主协议关联产品列表"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -263,12 +131,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][1]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -278,25 +152,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - MasterAgrmtProductModel model = new MasterAgrmtProductModel(); - - model.ClientType = "产品"; - model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); - model.OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U; - model.ProductName = GetDataSetValue(dt, i, 2); - model.CounterpartyCodeProducts = GetDataSetValue(dt, i, 3); - model.ManagerName = GetDataSetValue(dt, i, 4); - model.InvestmentManagerContactNumber = GetDataSetValue(dt, i, 5); - model.TrusteeAgency = GetDataSetValue(dt, i, 6); - model.TheDateTable = GetDataSetValue(dt, i, 7); - model.SuchProducts = GetDataSetValue(dt, i, 8); + var model = new MasterAgrmtProductModel + { + ClientType = "产品", + MasterAgrmtNo = GetDataSetValue(dt, i, 0), + OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U, + ProductName = GetDataSetValue(dt, i, 2), + CounterpartyCodeProducts = GetDataSetValue(dt, i, 3), + ManagerName = GetDataSetValue(dt, i, 4), + InvestmentManagerContactNumber = GetDataSetValue(dt, i, 5), + TrusteeAgency = GetDataSetValue(dt, i, 6), + TheDateTable = GetDataSetValue(dt, i, 7), + SuchProducts = GetDataSetValue(dt, i, 8) + }; var cacheValue = model.MasterAgrmtNo + "_" + model.ProductName; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -332,14 +207,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (!string.IsNullOrWhiteSpace(model.SuchProducts)) { - string path = Path.Combine(sourcePath, model.SuchProducts); + var path = Path.Combine(sourcePath, model.SuchProducts); if (!ReportStatus.CheckFileLength(path)) { break; } else { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); } note.id = 0; model.ExceID = base.formatExceID(); @@ -366,23 +241,30 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.MasterAgrmtProduct != null) { - List listRoot = new List(); - CheckHelper helper = new Common.CheckHelper(); - for (int i = 0; i < model.MasterAgrmtProduct.Count; i++) + var helper = new Common.CheckHelper(); + for (var i = 0; i < model.MasterAgrmtProduct.Count; i++) { + var listRoot = new List(); var item = model.MasterAgrmtProduct[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (listRoot.Count > 0) { - var errMsg = new SacInfo("MasterAgrmtProduct", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("MasterAgrmtProduct", i) + { + FieldValue = item.ProductName, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -408,7 +290,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } @@ -423,12 +305,24 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } private string formatInfoTag(MasterAgrmtProductModel model, bool suffixType = false) { - string result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.ProductName.Replace("_", "-")}_"; + var result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.ProductName.Replace("_", "-")}_"; if (suffixType) { result = $"{result}{_operationType}"; } return result; } + + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 4) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[2]; + arr[2] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtService.cs index 6d0e7c18..91d4b54c 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportMasterAgrmtService.cs @@ -1,7 +1,9 @@ -using System.Data; +using BaseOUDAL; +using System.Data; using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; using static YLErp.DBModels.Consts.ConsReport; @@ -23,60 +25,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1001; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_MasterAgrmt; - List noteList = new List(); + + readonly List noteList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetMasterAgrmtModelFromExcel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - try - { - LogFactory.GetLogger("GenerateBody").Info($"System:1111x"); - var resultList = GetMasterAgrmtModelFromDb(ref fileList); - if (resultList != null && resultList.Count() > 0) - { - LogFactory.GetLogger("GenerateBody").Info($"ok"); - dataList.AddRange(resultList); - } - - LogFactory.GetLogger("GenerateBody").Info($"System:2222x"); - } - catch (Exception ex) - { - LogFactory.GetLogger("GenerateBody").Info($"System:1111x系统异常:" + ex.ToString()); - } - } - - - LogFactory.GetLogger("GenerateBody").Info($"System:11112"); var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } + noData = dataList.Count == 0; model.MasterAgrmt = dataList; return model; @@ -84,7 +65,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(MasterAgrmtModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -136,186 +117,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - private IEnumerable GetMasterAgrmtModelFromDb(ref List fileList) - { - var dataList = new List(); - using (var baseDb = DbContextFactory.GetClientDbContext(null)) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var fileObjList = (from c in baseDb.client - join cf in baseDb.client_file - on c.id equals cf.ClientId - where c.ProcessStatus == "已开户" && cf.HasSent == false && cf.IsValid && - cf.FileTypeName == ConsGlobal.ClientFileType.MainProtocol && cf.OptState == _operationType && - ((c.ProcessOptDate >= _reqInfo.ReportDate && c.ProcessOptDate < nextDate && cf.OptDate < nextDate) ||//如果这一天开户,则把这一天之前(含这一天)的所有文件都报送了 - (cf.OptDate >= _reqInfo.ReportDate && cf.OptDate < nextDate && c.ProcessOptDate < _reqInfo.ReportDate))//如果这一天不是开户日期,则只在报送日期大于开户日期时,报送当日修改的文件 - && cf.ApprovalOrder < 1 - select new - { - cf.id, - cf.ClientId, - cf.OptState, - cf.ProtocolNumber, - cf.SignDate, - cf.SignType, - cf.ReportorRole, - cf.FilePath, - cf.FileName, - cf.FileDesc, - c.Name, - c.CounterpartyCode, - c.Number, - c.ProperClientClass, - c.CustomerNature1, - c.NFICode, - c.RegisteredCapital, - c.ClientType - }).ToArray(); - var clientIds = fileObjList.Select(O => O.ClientId); - var ct = baseDb.contactype.Where(O => O.ContactType == "联系人").FirstOrDefault(); - ExpandoDictionary clientdutyDict = null; - if (ct != null) - { - clientdutyDict = new ExpandoDictionary( - (from cd in baseDb.clientduty.Where(t => t.ApprovalOrder < 1) - where clientIds.Contains(cd.ClientId ?? 0) && (cd.DeadLine == null || cd.DeadLine >= _reqInfo.ReportDate) - select cd) - .ToList() - .Where(O => O.ContactTypeIdsInt.Contains(ct.id)).GroupBy(O => O.ClientId ?? 0) - .ToDictionary(K => K.Key, V => V.FirstOrDefault())); - } - LogFactory.GetLogger("ReportMasterAgrmtService").Error("查询到: " + fileObjList.Length.ToString()); - var cacheKey = $"{BusiDataType}"; - foreach (var item in fileObjList) - { - var cacheValue = item.ProtocolNumber; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - LogFactory.GetLogger("ReportMasterAgrmtService").Error("有重复编号跳过 " + item.ProtocolNumber); - continue; - } - try - { - var info = new MasterAgrmtModel(); - info.OperationType = item.OptState; - info.MasterAgrmtNo = item.ProtocolNumber; - info.SigningDate = item.SignDate?.ToString("yyyy-MM-dd"); - info.MasterAgrmtVer = ConsReport.MasterAgrmtVerMap[item.SignType ?? ""]; - info.FillParty = ConsReport.FillPartyMap[item.ReportorRole ?? ""]; - info.NameOfCounterparty = item.Name; - info.CounterpartyCode = item.Number; - info.ProCounterparty = item.ProperClientClass != null && item.ProperClientClass.Contains("专业") ? ProCounterpartyMap["专业"] : ProCounterpartyMap["非专业"]; - info.CounterpartyType = CounterpartyTypeMap[item.CustomerNature1 ?? ""]; - if ((info.CounterpartyType == CounterpartyTypeMap["境外金融机构"] || info.CounterpartyType == CounterpartyTypeMap["境外非金融机构"])) - { - info.LEI = item.CounterpartyCode; - } - else - { - info.CODS = item.CounterpartyCode; - } - if (item.CustomerNature1 != null && item.CustomerNature1.Contains("非金融机构")) - { - info.NFICode = item.NFICode; - } - info.CounterpartyRegdCptl = item.RegisteredCapital; - info.MasterAgrmtAtt = item.FileName; - info.MasterAgrmtRemark = item.FileDesc; - if (clientdutyDict != null && clientdutyDict.ContainsKey(item.ClientId)) - { - info.CounterpartyInformationTuple = new List(); - CounterpartyInfomationModel userInfo = new CounterpartyInfomationModel(); - userInfo.Name = clientdutyDict[item.ClientId]?.ContactName; - userInfo.Title = clientdutyDict[item.ClientId] == null ? null : "联系人"; - userInfo.Email = clientdutyDict[item.ClientId]?.Email; - userInfo.Telephone = clientdutyDict[item.ClientId]?.PhoneNumber; - //userInfo.Mobile = clientdutyDict[item.ClientId]?.PhoneNumber; - info.CounterpartyInformationTuple.Add(userInfo); - } - info.CounterpartyIdentity = item.ClientType == "机构" ? CounterpartyIdentityMap["自营"] : CounterpartyIdentityMap["产品管理人"]; - - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{info.MasterAgrmtNo}\",\"Source\":\"System\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - LogFactory.GetLogger("ReportMasterAgrmtService").Error("未找到历史报送信息跳过 " + formatInfoTag(info)); - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.MasterAgrmtID = note.BizId; - } - if (!ReportStatus.CheckFileLength(item.FilePath)) - { - break; - } - else - { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - } - info.ExceID = base.formatExceID(); - dataList.Add(info); - fileList.Add(item.FilePath); - note.id = 0; - note.DataId = item.id.ToString(); - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - catch (Exception ex) - { - LogFactory.GetLogger("ReportMasterAgrmtService").Error(ex); - LogFactory.GetLogger("ReportMasterAgrmtService").Error(item.ToJson()); - throw; - } - } - } - return dataList; - } - private List GetMasterAgrmtModelFromExcel(ref List fileList) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("主协议")) { - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["主协议"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["主协议"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -325,12 +134,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][3]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -340,14 +155,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - MasterAgrmtModel model = generiterInfoFromExcel(dt, i, optType); + var model = generiterInfoFromExcel(dt, i, optType); model.CounterpartyInformationTuple = GetCounterpartyInfomationModelFromExcel(model.MasterAgrmtNo); - string cacheValue = model.MasterAgrmtNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + var cacheValue = model.MasterAgrmtNo; + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -385,14 +200,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (!string.IsNullOrWhiteSpace(model.MasterAgrmtAtt)) { model.ExceID = base.formatExceID(); - string path = Path.Combine(sourcePath, model.MasterAgrmtAtt); + var path = Path.Combine(sourcePath, model.MasterAgrmtAtt); if (!ReportStatus.CheckFileLength(path)) { break; } else { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); } result.Add(model); fileList.Add(path); @@ -418,29 +233,31 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private MasterAgrmtModel generiterInfoFromExcel(DataTable dt, int i, OptFlagsEnum optType) { - var model = new MasterAgrmtModel(); - model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); - model.SigningDate = GetDataSetValue(dt, i, 1); - model.MasterAgrmtVer = ConsReport.MasterAgrmtVerMap[GetDataSetValue(dt, i, 2)]; - model.OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U; - model.FillParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 4)]; - model.NameOfCounterparty = GetDataSetValue(dt, i, 5); - model.CODS = GetDataSetValue(dt, i, 6); - model.CounterpartyCode = GetDataSetValue(dt, i, 7); - model.LEI = GetDataSetValue(dt, i, 8); - model.ProCounterparty = ConsReport.ProCounterpartyMap[GetDataSetValue(dt, i, 9)]; - model.CounterpartyType = ConsReport.CounterpartyTypeMap[GetDataSetValue(dt, i, 10)]; - model.NFICode = GetDataSetValue(dt, i, 11); - model.CounterpartyRegdCptl = GetDataSetValue(dt, i, 12); - model.MasterAgrmtRemark = GetDataSetValue(dt, i, 13); - model.MasterAgrmtAtt = GetDataSetValue(dt, i, 14); - model.CounterpartyIdentity = ConsReport.CounterpartyIdentityMap[GetDataSetValue(dt, i, 15)]; + var model = new MasterAgrmtModel + { + MasterAgrmtNo = GetDataSetValue(dt, i, 0), + SigningDate = GetDataSetValue(dt, i, 1), + MasterAgrmtVer = ConsReport.MasterAgrmtVerMap[GetDataSetValue(dt, i, 2)], + OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U, + FillParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 4)], + NameOfCounterparty = GetDataSetValue(dt, i, 5), + CODS = GetDataSetValue(dt, i, 6), + CounterpartyCode = GetDataSetValue(dt, i, 7), + LEI = GetDataSetValue(dt, i, 8), + ProCounterparty = ConsReport.ProCounterpartyMap[GetDataSetValue(dt, i, 9)], + CounterpartyType = ConsReport.CounterpartyTypeMap[GetDataSetValue(dt, i, 10)], + NFICode = GetDataSetValue(dt, i, 11), + CounterpartyRegdCptl = GetDataSetValue(dt, i, 12), + MasterAgrmtRemark = GetDataSetValue(dt, i, 13), + MasterAgrmtAtt = GetDataSetValue(dt, i, 14), + CounterpartyIdentity = ConsReport.CounterpartyIdentityMap[GetDataSetValue(dt, i, 15)] + }; return model; } private string formatInfoTag(MasterAgrmtModel model, bool suffixType = false) { - string result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_"; + var result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -448,31 +265,44 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 3) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + private List GetCounterpartyInfomationModelFromExcel(string masterAgrmtNo) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("填报方业务代表明细")) { - DataTable dt = _excelDataSource.Tables["填报方业务代表明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["填报方业务代表明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != masterAgrmtNo) + if (dt.Rows[i][0]?.ToString().Trim() != masterAgrmtNo) { continue; } - CounterpartyInfomationModel model = new CounterpartyInfomationModel(); - - model.Name = GetDataSetValue(dt, i, 1); - model.Title = GetDataSetValue(dt, i, 2); - model.Telephone = GetDataSetValue(dt, i, 3); - model.Mobile = GetDataSetValue(dt, i, 4); - model.Email = GetDataSetValue(dt, i, 5); + var model = new CounterpartyInfomationModel + { + Name = GetDataSetValue(dt, i, 1), + Title = GetDataSetValue(dt, i, 2), + Telephone = GetDataSetValue(dt, i, 3), + Mobile = GetDataSetValue(dt, i, 4), + Email = GetDataSetValue(dt, i, 5) + }; result.Add(model); } @@ -482,23 +312,27 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.MasterAgrmt != null) { - CheckHelper helper = new Common.CheckHelper(); - CheckHelper infoHelper = new Common.CheckHelper(); - for (int i = 0; i < model.MasterAgrmt.Count; i++) + var helper = new Common.CheckHelper(); + var infoHelper = new Common.CheckHelper(); + for (var i = 0; i < model.MasterAgrmt.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.MasterAgrmt[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (item.CounterpartyInformationTuple != null) { - for (int j = 0; j < item.CounterpartyInformationTuple.Count; j++) + for (var j = 0; j < item.CounterpartyInformationTuple.Count; j++) { var listItem = new List(); var tuple = item.CounterpartyInformationTuple[j]; @@ -508,16 +342,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("CounterpartyInformationTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("CounterpartyInformationTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("MasterAgrmt", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("MasterAgrmt", i) + { + FieldValue = item.MasterAgrmtNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -542,7 +381,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger().Error(e); }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationAttService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationAttService.cs new file mode 100644 index 00000000..e29762b7 --- /dev/null +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationAttService.cs @@ -0,0 +1,320 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static YLErp.DBModels.Consts.ConsReport; +using YLErp.BLL; +using YLErp.DBModels.Consts; +using YLErp.DBModels.Enums; +using YLErp.DBModels; +using YLErp.Modules.SuperviseReportModule.SAC.Common; +using YLErp.Modules.SuperviseReportModule.SAC.Model; +using System.Data; +using System.IO; +using NPOI.SS.Formula.Functions; +using YLErp.Helpers; + +namespace YLErp.Modules.SuperviseReportModule.SAC.Service +{ + class ReportOptionConfirmationAttService : ReportBaseService + { + public ReportOptionConfirmationAttService(OptUserInfo optUser) : base(optUser) + { + } + + protected override string _excelDataSourcePath => "交易相关\\"; + + protected override string _excelDataSourceFileName => "import_OptionConfirmationAtt_template.xlsx"; + + protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1019; + + private List _validOperationType = null; + public override List ValidOperationType + { + get + { + if (_validOperationType == null) + { + _validOperationType = new List() { + OptFlagsEnum.A, + OptFlagsEnum.U, + OptFlagsEnum.D, + }; + } + return _validOperationType; + } + } + + protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_OptionConfirmationAtt; + List noteList = new List(); + + protected override BodyModel GenerateBody(out bool noData, out List fileList) + { + fileList = new List(); + BodyModel model = new BodyModel(); + List dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) + { + dataList = GetOptionConfirmationAttModel(out fileList); + } + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); + if (subsystemDataList != null && subsystemDataList.Count > 0) + dataList.AddRange(subsystemDataList); + + noData = dataList.Count == 0; + model.ConfirmationAtt = dataList; + return model; + } + + public bool AddSubsystemNote(ConfirmationAttModel model, List fileList, string tag) + { + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + if (note == null) + { + note = new SACReportNotes() + { + InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", + IsValid = true, + }; + } + else + { + switch (model.OperationType) + { + case OptFlagsEnum.A: + return false;//新增数据已报送,跳过 + case OptFlagsEnum.U: + //多次U的时候,每次用最新的tag来赋值SubFileTag + note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; + note.IsValid = true; + break; + case OptFlagsEnum.D: + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + if (model.ConfirmationFilesTuple != null && model.ConfirmationFilesTuple.Count > 0) + { + fileList.AddRange(model.ConfirmationFilesTuple.Select(x => x.ConfirmationAtt)); + } + model.ExceID = base.formatExceID(); + note.ExceId = model.ExceID; + note.id = 0; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(model, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); + return true; + } + + private List GetOptionConfirmationAttModel(out List fileList) + { + fileList = new List(); + List result = new List(); + if (_excelDataSource != null && _excelDataSource.Tables.Contains("场外期权确认书附件明细")) + { + DataTable dt = _excelDataSource.Tables["场外期权确认书附件明细"]; + string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + for (int i = 1; i < dt.Rows.Count; i++) + { + if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) + { + //第一列空白说明数据结束了; + break; + } + var optType = OptFlagsEnum.NONE; + switch (dt.Rows[i][1]?.ToString()) + { + case "0": + case "A": + case "首次": + optType = OptFlagsEnum.A; + break; + case "1": + case "U": + case "变更": + optType = OptFlagsEnum.U; + break; + case "2": + case "D": + case "废止": + optType = OptFlagsEnum.D; + break; + } + if (optType != _operationType) + { + continue; + } + + ConfirmationAttModel model = new ConfirmationAttModel(); + + model.ConfirmationNo = GetDataSetValue(dt, i, 0); + model.OperationType = optType; + var cacheValue = (model.ConfirmationNo ?? "").ToString(); + if (cacheValue.IsNullOrWhiteSpace()) + { + continue; + } + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) + { + continue; + } + model.ConfirmationFilesTuple = new List(); + var files = GetDataSetValue(dt, i, 2).Split(','); + foreach (var f in files) + { + if (!string.IsNullOrWhiteSpace(f)) + { + var path = Path.Combine(sourcePath, f); + if (!ReportStatus.CheckFileLength(path)) + { + break; + } + fileList.Add(path); + model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { IsSwap = "false", ConfirmationAtt = f }); + } + } + List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); + var note = notes.LastOrDefault(O => O.InfoCache.Contains(cacheValue)); + if (note == null && _operationType == OptFlagsEnum.A) + { + note = new SACReportNotes() + { + IsValid = true, + }; + } + else + { + if (note == null) + { + continue; + } + switch (_operationType) + { + case OptFlagsEnum.A: + continue;//新增数据已报送,跳过 + case OptFlagsEnum.U: + note.IsValid = true; + break; + case OptFlagsEnum.D: + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + if (_operationType != OptFlagsEnum.A) + { + model.BizID = note.BizId; + } + model.ExceID = base.formatExceID(); + result.Add(model); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); + note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}"; + note.id = 0; + note.ExceId = model.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(model, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.DataId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + return result; + } + + private string formatInfoTag(ConfirmationAttModel model, bool suffixType = false) + { + string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_确认书_"; + if (suffixType) + { + result = $"{result}{_operationType}"; + } + return result; + } + + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 5) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) + { + List result = new List(); + if (model?.ConfirmationAtt != null) + { + CheckHelper helper = new CheckHelper(); + CheckHelper attHelper = new CheckHelper(); + for (int i = 0; i < model.ConfirmationAtt.Count; i++) + { + List listRoot = new List(); + var item = model.ConfirmationAtt[i]; + helper.ExecuteCheck(item, (name, value, msg) => + { + listRoot.Add(new SacInfo(name, value, msg)); + }); + if (item.ConfirmationFilesTuple != null) + { + for (int j = 0; j < item.ConfirmationFilesTuple.Count; j++) + { + var att = item.ConfirmationFilesTuple[j]; + attHelper.ExecuteCheck(att, (name, value, msg) => + { + listRoot.Add(new SacInfo(name, value, msg)); + }); + } + } + if (listRoot.Count > 0) + { + var errMsg = new SacInfo("OptionConfirmationAtt", i); + errMsg.FieldValue = item.ConfirmationNo; + errMsg.SubMaps = new List(listRoot); + result.Add(errMsg); + } + } + } + checkStatus = result.Count > 0; + return result; + } + + public override bool BeforeOfGenerated(out string errMsg) + { + errMsg = ""; + for (int i = 0; i < noteList.Count; i++) + { + base.SaveReportNotes(noteList[i]); + } + return true; + } + } +} diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationService.cs index 171224a1..a1a8e686 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionConfirmationService.cs @@ -1,16 +1,27 @@ -using BaseOUDAL; +using BaseOUDAL; +using NPOI.SS.Formula.Functions; +using Qdp.Foundation.Implementations; +using Qdp.Pricing.Base.Utilities; +using Qdp.Pricing.Library.Base.Utilities; using System.Data; +using System.Net; using System.Text.RegularExpressions; using YLErp.BLL; +using YLErp.Commons; +using YLErp.Configuration; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Modules.EodModule; +using YLErp.Modules.StructureModule; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; +using YLErp.QdpModule; using static YLErp.DBModels.Consts.ConsReport; namespace YLErp.Modules.SuperviseReportModule.SAC.Service { + //交易确认书-期权交易确认书 class ReportOptionConfirmationService : ReportBaseService { public ReportOptionConfirmationService(OptUserInfo optUser) : base(optUser) @@ -23,514 +34,40 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1004; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_OptionConfirmation; - List noteList = new List(); + + readonly List noteList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); noData = true; - BodyModel model = new BodyModel(); - LogFactory.GetLogger("loadSubsystemDataSource").Error($"x1:"); - var cacheKey = $"{BusiDataType}"; - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetOptionConfirmationModelFromExcel(ref fileList); } - LogFactory.GetLogger("loadSubsystemDataSource").Error($"x2:"); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var nextDataDate = _reqInfo.DataDate.AddDays(1); - using (var db = new YLContext()) - { - var codeList = ReportStatus.GetCacheInfo(cacheKey); - var query = (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r - on tc.id equals tr.TradeCashId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - where - ((_operationType == OptFlagsEnum.A && t.TradeDate >= _reqInfo.DataDate && t.TradeDate < nextDataDate)//新增时使用交易日期判断 - || (_operationType != OptFlagsEnum.A && tc.OptDate >= _reqInfo.ReportDate && tc.OptDate < nextDate))//补正和废止时使用操作日期判断 - && (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid)) - && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType != "收益互换" - && tc.Action == "系统操作-期权费" && t.ParentTradeId == 0 - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.OriginalNotional, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - tr.ContractCode, - td.Paths, - td.StampDocumentFileName, - t.TradePrice, - t.PremiumRate, - t.QuoteCurrency, - t.SettlementCurrency - }).OrderBy(O => O.OptDate).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray(); - - List ids = query.Select(O => O.id).ToList(); - List delIds = new List(); - if (_operationType == OptFlagsEnum.D) - { - delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList(); - } - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - Dictionary reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescOption).ToDictionary(K => K.PName, V => V.PValue); - foreach (var item in query.ToArray()) - { - var cacheValue = item.id.ToString(); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - //如果存在重复数据,则始终用较新的数据 - OptionConfirmationModel info = new OptionConfirmationModel(); - - info.TradeId = item.id.ToString(); - info.ConfirmationNo = item.ContractCode; - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - info.OperationType = OptFlagsEnum.A; - note = new SACReportNotes() - { - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - if (!note.changeStatus) - { - continue;//交易没有被修改过,跳过 - } - info.OperationType = OptFlagsEnum.U; - note.IsValid = true; - break; - case OptFlagsEnum.D: - if (!delIds.Contains(item.id)) - { - continue;//交易没有被删除,跳过 - } - info.OperationType = OptFlagsEnum.D; - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != _operationType) - { - continue; - } - if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradecashValid || !item.tradeContractRValid)) - {//非废止报送中,应跳过所有存在无效数据的数据 - continue; - } - if (metaDic.ContainsKey(item.id)) - { - var metaInfo = metaDic[item.id]; - info.MasterAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.MainProtocolCode) ? metaInfo[ConsTradeMetaKey.MainProtocolCode] : ""; - info.SupAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.SupProtocolCode) ? metaInfo[ConsTradeMetaKey.SupProtocolCode] : ""; - info.ClearingAgency = metaInfo.ContainsKey(ConsTradeMetaKey.ClearingAgency) ? ClearingAgencyMap[metaInfo[ConsTradeMetaKey.ClearingAgency]] : ""; - info.TradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : ""; - if (info.TradingPlace == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - var rate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(item.QuoteCurrency, "CNY", _reqInfo.DataDate); - if (info.OperationType != OptFlagsEnum.A) - { - info.ConfirmationID = note.BizId;//确认书编号; - } - info.ConfirmationType = ReportTypeMap[info.OperationType == OptFlagsEnum.A ? "首次" : "变更"]; - info.FillParty = FillPartyMap["甲方"]; - info.OptionSeller = item.BuySell == "卖出" ? OptionTraderMap["填报方"] : OptionTraderMap["对手方"]; - info.OptionDirection = OptionDirectionMap[item.OptionType]; - string defaultDesc = reportDescDic.ContainsKey("默认") ? reportDescDic["默认"] : ""; - info.ProfitCalculationInfo = reportDescDic.ContainsKey(item.TradeType) && !string.IsNullOrWhiteSpace(reportDescDic[item.TradeType]) ? reportDescDic[item.TradeType] : defaultDesc; - info.ExercisePriceOne = ((item.IsMoneynessOption == "是" ? item.Strike : item.Strike / item.SpotPrice) * 100)?.ToString("0.00"); - string tradeType = item.TradeType; - if (tradeType.Contains("价差")) - { - tradeType = "价差期权"; - } - double? strike = null; - switch (tradeType) - { - case "香草期权": - info.OptionStructureType = OptionStructureTypeMap["香草"]; - break; - case "二元期权": - info.OptionStructureType = OptionStructureTypeMap["二元"]; - break; - case "价差期权": - info.OptionStructureType = OptionStructureTypeMap["价差"]; - break; - case "障碍期权": - info.OptionStructureType = OptionStructureTypeMap["障碍"]; - break; - case "双鲨期权": - info.OptionStructureType = OptionStructureTypeMap["鲨鱼鳍"]; - var sharkfin = DbContext.trade_double_sharkfin_option.Where(O => O.TradeId == item.id).Select(O => new { O.StrikeHigh, O.StrikeLow }).FirstOrDefault(); - info.ExercisePriceOne = ((item.IsMoneynessOption == "是" ? sharkfin.StrikeLow : sharkfin.StrikeLow / item.SpotPrice) * 100)?.ToString("0.00"); - info.ExercisePriceTwo = ((item.IsMoneynessOption == "是" ? sharkfin.StrikeHigh : sharkfin.StrikeHigh / item.SpotPrice) * 100)?.ToString("0.00"); - break; - case "区间累积期权": - info.OptionStructureType = OptionStructureTypeMap["区间累计"]; - break; - case "凤凰期权": - info.OptionStructureType = OptionStructureTypeMap["AutoCallable"]; - var autocall = DbContext.trade_autocall.Where(O => O.TradeId == item.id).FirstOrDefault(); - if (autocall.KIPayoffType != KIPayoffTypeEnum.None) - { - strike = autocall.SpreadStrike ?? autocall.SpreadStrike1; - } - if (strike != null) - { - info.ExercisePriceTwo = ((item.IsMoneynessOption == "是" ? strike : strike / item.SpotPrice) * 100)?.ToString("0.00"); - } - break; - case "雪球期权": - info.OptionStructureType = OptionStructureTypeMap["AutoCallable"]; - var snowball = DbContext.trade_snowball.Where(O => O.TradeId == item.id).FirstOrDefault(); - if (snowball.KIPayoffType != KIPayoffTypeEnum.None) - { - strike = snowball.SpreadStrikeAtMaturity ?? snowball.SpreadStrikeAtMaturity1; - } - else if (snowball.KOPayoffType != KOPayoffTypeEnum.Rebate) - { - strike = snowball.SpreadStrikeAtKO ?? snowball.SpreadStrikeAtKO1; - } - if (strike != null) - { - info.ExercisePriceTwo = ((item.IsMoneynessOption == "是" ? strike : strike / item.SpotPrice) * 100)?.ToString("0.00"); - } - break; - default: - info.OptionStructureType = OptionStructureTypeMap["其他"]; - info.OptionStructure = item.TradeType; - break; - } - if (string.IsNullOrWhiteSpace(info.ExercisePriceOne) && !string.IsNullOrWhiteSpace(info.ExercisePriceTwo)) - { - info.ExercisePriceOne = info.ExercisePriceTwo; - info.ExercisePriceTwo = null; - } - if (string.IsNullOrWhiteSpace(info.ExercisePriceTwo)) - { - info.ExercisePriceTwo = null; - } - info.ExerciseApproach = ExerciseApproachMap[item.ExerciseMode == "American" ? "美式" : "欧式"]; - info.StartDate = item.TradeDate?.ToString("yyyy-MM-dd"); - info.DueDate = item.ExerciseDate?.ToString("yyyy-MM-dd"); - info.SettlementDate = item.SettlementDate?.ToString("yyyy-MM-dd"); - info.OptionPremium = (item.PremiumRate * 100)?.ToString("0.00"); - var currency = item.SettlementCurrency == "CNH" ? "CNY" : item.SettlementCurrency ?? "CNY"; - info.Currency = ((int)(CurrencyEnum)Enum.Parse(typeof(CurrencyEnum), currency)).ToString();// ((int)CurrencyEnum.CNY).ToString(); - info.NotinalPrincipleAmt = (item.OriginalStockEqvNotional * rate)?.ToString("0.00"); - info.BusinessModelType = BusinessModelTypeMap["传统型期权"]; - //系统中的交易修改时必须回退,所以报送不存在修改时还存在有效的存续期记录的情况; - //Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); - //if (info.OperationType == OptFlagsEnum.U) - //{ - // if (reportCacheDic.ContainsKey("DueDate") && !reportCacheDic["DueDate"].StartsWith(info.DueDate) && !info.DueDate.StartsWith(reportCacheDic["DueDate"])) - // { - // throw new ServiceException("补正时,如果该交易还存在有效的存续期记录,到期日字段不能修改"); - // } - // if (reportCacheDic.ContainsKey("NotinalPrincipleAmt") && reportCacheDic["NotinalPrincipleAmt"] != info.NotinalPrincipleAmt && reportCacheDic["NotinalPrincipleAmt"] != item.OriginalStockEqvNotional?.ToString("0")) - // { - // throw new ServiceException("补正时,如果该交易还存在有效的存续期记录,名义本金额(人民币)字段不能修改"); - // } - //} - - info.ConfirmationAttTuple = new List(); - ConfirmationAttModel confirmationInfo = new ConfirmationAttModel(); - string path = item.StampDocumentFileName ?? item.Paths; - if (!(path.StartsWith("\\") || path.StartsWith("/"))) - { - path = "\\" + path; - } - var absolutePath = OtcAppContext.MapPath(path); - absolutePath = Path.ChangeExtension(absolutePath, "pdf"); - confirmationInfo.ConfirmationAtt = Path.GetFileName(absolutePath); - info.ConfirmationAttTuple.Add(confirmationInfo); - - var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode); - switch (um.UnderlyingInstrumentType) - { - case ConsGlobal.InstrumentType.Stock: - case ConsGlobal.InstrumentType.StockIndex: - case ConsGlobal.InstrumentType.NewOtcStock: - case ConsGlobal.InstrumentType.HKStock: - case ConsGlobal.InstrumentType.HKStockIndex: - case ConsGlobal.InstrumentType.AbroadStock: - case ConsGlobal.InstrumentType.AbroadStockIndex: - info.UndrlygAssetType = UndrlygAssetTypeMap["权益类"]; - break; - case ConsGlobal.InstrumentType.StockIF: - case ConsGlobal.InstrumentType.CommodityFutures: - case ConsGlobal.InstrumentType.GoldFutures: - case ConsGlobal.InstrumentType.TBFutures: - case ConsGlobal.InstrumentType.OtherFutures: - case ConsGlobal.InstrumentType.AbroadFutures: - case ConsGlobal.InstrumentType.CommoditySpot: - case ConsGlobal.InstrumentType.GoldSpot: - case ConsGlobal.InstrumentType.OtherSpot: - case ConsGlobal.InstrumentType.AbroadSpot: - info.UndrlygAssetType = UndrlygAssetTypeMap["大宗商品"]; - break; - case ConsGlobal.InstrumentType.ExRate: - info.UndrlygAssetType = UndrlygAssetTypeMap["汇率"]; - break; - case ConsGlobal.InstrumentType.Shibor: - case ConsGlobal.InstrumentType.OtherRate: - break; - default: - info.UndrlygAssetType = UndrlygAssetTypeMap["其他"]; - break; - } - - info.UndrlygAssetNo = um.CommodityCode == "组合标的" ? UndrlygAssetNoMap["组合标的"] : UndrlygAssetNoMap["单一标的"]; - #region 标的信息 - - info.UndrlygAssetTuple = new List(); - List sCodeList = null; - if (um.CommodityCode == "组合标的") - { - sCodeList = DataCacheProvider.GetUnderlyingDataSource().GetSyntheticUnderlying(item.UnderlyingCode).GetUnderlyingCodes().ToList(); - } - else - { - sCodeList = new List() { um.UnderlyingCode }; - } - for (int i = 0; i < sCodeList.Count; i++) - { - var codeInfo = DataCacheProvider.GetUnderlyingDataSource().GetData(sCodeList[i]); - UndrlygAssetModel undrlygAsset = new UndrlygAssetModel(); - undrlygAsset.UndrlygAssetCode = Regex.Replace(codeInfo.UnderlyingCode, @"\..+", ""); - undrlygAsset.UndrlygAssetName = codeInfo.UnderlyingName; - undrlygAsset.UndrlygAssetAmt = item.OriginalNotional?.ToString(); - switch (codeInfo.MarketCode) - { - case "SHFE": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["上海期货交易所"]; - break; - case "DCE": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["大连商品交易所"]; - break; - case "CZC": - case "CZCE": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["郑州商品期货交易所"]; - break; - case "CFFEX": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["中国金融期货交易所"]; - break; - case "INE": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["上海国际能源交易中心"]; - break; - case "SGE": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["上海黄金交易所"]; - break; - case "SH": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["上海证券交易所"]; - break; - case "SZ": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["深圳证券交易所"]; - break; - case "CFETS": - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["外汇交易中心"]; - break; - default: - undrlygAsset.UndrlygAssetTradgPlc = UndrlygAssetTradgPlceMap["其他"]; - break; - } - - if (UndrlygAssetDtldTypeMap.TryGetValue(ConsGlobal.InstrumentType.GetDesc(codeInfo.UnderlyingInstrumentType), out var AssetDtldType)) - { - undrlygAsset.UndrlygAssetDtldType = AssetDtldType; - } - else - { - undrlygAsset.UndrlygAssetDtldType = UndrlygAssetDtldTypeMap["其他标的"]; - } - - info.UndrlygAssetTuple.Add(undrlygAsset); - } - - #endregion - #region 履约担保 - - var files = db.trade_file.Where(O => O.TradeId == item.id).ToArray(); - info.PerformanceGuaranteeType = item.MarginType == MarginTypeEnum.NONE ? PerformanceGuaranteeMap["无履约担保"] : PerformanceGuaranteeMap["部分担保"]; - if (item.MarginType != MarginTypeEnum.NONE) - { - info.PerformanceCollProvider = PerformanceCollProviderMap["乙方"]; - info.PartyUseColl = ConsReport.BoolMap[valuedateBLL.SystemDate.PartyUseColl || PS.Config.Company == Configuration.CompanyEnum.东莞 ? "是" : "否"];//todo:读取用户输入 - info.CollInstruction = valuedateBLL.SystemDate.CollInstruction;//todo:读取用户输入 - info.CalculateCollInterest = BoolMap["否"]; - info.PerformanceCollInitialRatio = "0";//((item.InitialMargin / item.OriginalStockEqvNotional * 100) ?? 0).ToString("0.00"); - info.PerformanceCollAddtlRatio = "0"; - info.PerformanceCollOffsetRatio = "0"; - var file_PerformanceGuarante = files.FirstOrDefault(O => O.Path.ToLower().EndsWith("履约保证书.pdf")); - if (!string.IsNullOrWhiteSpace(file_PerformanceGuarante?.Path)) - { - string fileName = Path.GetFileName(file_PerformanceGuarante?.Path); - path = file_PerformanceGuarante?.Path; - info.PerformanceGuaranteeAtt = fileName; - info.PerformanceGuaranteeRemark = file_PerformanceGuarante?.Description; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - } - info.PerformanceCollTuple = new List(); - info.PerformanceCollTuple.Add(new PerformanceGuaranteeAttModel() - { - PerformanceCollType = PerformanceCollTypeMap["现金"], - PerformanceCollRange = /*item.MarginType == MarginTypeEnum.DEFAULT ? PerformanceCollRangeMap["本笔交易对应主协议框架下的所有交易"] :*/ PerformanceCollRangeMap["仅本笔交易"] - }); - } - - #endregion - - var file_ComplianceOpinion = files.FirstOrDefault(O => O.Path.ToLower().EndsWith("合规意见书.pdf")); - if (!string.IsNullOrWhiteSpace(file_ComplianceOpinion?.Path)) - { - string fileName = Path.GetFileName(file_ComplianceOpinion?.Path); - path = file_ComplianceOpinion?.Path; - info.ComplianceOpinion = fileName; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - } - info.ValidNotinalPrincipleAmt = (item.StockEqvNotionalReal * rate).ToString("0.00"); - var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); - if (client.ClientType == "产品") - { - using (var baseDb = new ClientDBContext()) - { - if (PS.Config.Company == Configuration.CompanyEnum.中金) - { - info.FillParty = FillPartyMap["甲方"]; - info.PtyBPdctName = client.Abbreviation ?? ""; - info.PytBPdctCode = client.ProductNumber ?? ""; - } - else - { - //var clientFile = baseDb.client_file.Where(O => ((O.FileTypeName == ConsGlobal.ClientFileType.MainProtocol && O.ProtocolNumber == info.MasterAgrmtNo) || (O.FileTypeName == ConsGlobal.ClientFileType.AllographProduct && O.MainProtocolNumber == info.MasterAgrmtNo)) && O.ClientId == client.id && O.IsValid).AsEnumerable().GroupBy(O => O.FileTypeName).ToDictionary(K => K.Key, V => V.FirstOrDefault()); - //if (!clientFile.ContainsKey(ConsGlobal.ClientFileType.MainProtocol)) - //{ - // throw new ServiceException($"{client.Name} 主协议文件不存在,生成失败!"); - //} - ////下面这行注释掉是因为目前系统报送互换时只处理了报送方是甲方的情况,假如报送方为乙方,则所有涉及支付方向的参数都应该对调,期权为了逻辑保持一直,所以暂时一起注释掉; - ////info.FillParty = FillPartyMap[clientFile[ConsGlobal.ClientFileType.MainProtocol].ReportorRole]; - //var productFile = clientFile.ContainsKey(ConsGlobal.ClientFileType.AllographProduct) ? clientFile[ConsGlobal.ClientFileType.AllographProduct] : null; - if (info.FillParty == FillPartyMap["甲方"]) - { - info.PtyBPdctName = client.Name ?? ""; - info.PytBPdctCode = client.Number ?? ""; - } - else - { - info.PtyAPdctName = client.Name ?? ""; - info.PytAPdctCode = client.Number ?? ""; - } - } - } - } - info.ExceID = base.formatExceID(); - if (!ReportStatus.CheckFileLength(absolutePath)) - { - break; - } - fileList.Add(absolutePath); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{info.NotinalPrincipleAmt}\",\"DueDate\":\"{info.DueDate}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}"; - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.ReportResponse = false; - note.RetCode = ""; - note.RetMsg = ""; - note.DataId = item.tcId.ToString(); - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - LogFactory.GetLogger("loadSubsystemDataSource").Error($"x3:"); - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); - LogFactory.GetLogger("loadSubsystemDataSource").Error($"x4:"); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); - + } fileList = fileList.Distinct().ToList(); noData = dataList.Count == 0; @@ -540,7 +77,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(OptionConfirmationModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -579,10 +116,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList.Add(model.PerformanceGuaranteeAtt); } - if (model.ConfirmationAttTuple != null && model.ConfirmationAttTuple.Count > 0) - { - fileList.AddRange(model.ConfirmationAttTuple.Select(x => x.ConfirmationAtt)); - } + //if (model.ConfirmationAttTuple != null && model.ConfirmationAttTuple.Count > 0) + //{ + // fileList.AddRange(model.ConfirmationAttTuple.Select(x => x.ConfirmationAtt)); + //} model.ExceID = base.formatExceID(); note.id = 0; @@ -604,42 +141,41 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private List GetOptionConfirmationModelFromExcel(ref List fileList) { - List result = new List(); - string path = ""; - if (_excelDataSource != null) - { - LogFactory.GetLogger("loadSubsystemDataSource").Info($"xrrrr:"); - if (_excelDataSource.Tables != null) - LogFactory.GetLogger("loadSubsystemDataSource").Info($"ggg:"); - if (_excelDataSource.Tables == null) - LogFactory.GetLogger("loadSubsystemDataSource").Info($"ghh:"); - } - - + var result = new List(); + var path = ""; if (_excelDataSource != null && _excelDataSource.Tables.Contains("期权交易确认书明细")) { - LogFactory.GetLogger("loadSubsystemDataSource").Info($"x111:"); - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["期权交易确认书明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["期权交易确认书明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } + + OptionConfirmationModel model = new OptionConfirmationModel(); + + model.ConfirmationNo = GetDataSetValue(dt, i, 2); var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][3]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; + ReportStatus.AddCacheInfo($"{DataFlagsEnum.A1018}_D", model.ConfirmationNo); break; } if (optType != _operationType) @@ -647,12 +183,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - OptionConfirmationModel model = new OptionConfirmationModel(); - model.OperationType = optType; model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); model.SupAgrmtNo = GetDataSetValue(dt, i, 1); - model.ConfirmationNo = GetDataSetValue(dt, i, 2); model.ConfirmationType = ConsReport.ReportTypeMap[optType == OptFlagsEnum.A ? "首次" : "变更"]; model.FillParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 4)]; model.OptionSeller = ConsReport.OptionTraderMap[GetDataSetValue(dt, i, 5)]; @@ -664,49 +197,66 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.DueDate = GetDataSetValue(dt, i, 11); model.SettlementDate = GetDataSetValue(dt, i, 12); model.OptionPremium = GetDataSetValue(dt, i, 13); - if (!Enum.TryParse(GetDataSetValue(dt, i, 14), out CurrencyEnum currency)) + model.AnnualizedDays = GetDataSetValue(dt, i, 14); + model.PricingVolatility = GetDataSetValueToDoubleOrNull(dt, i, 15)?.ToString("0.00"); + model.RiskFreeInterestRates = GetDataSetValueToDoubleOrNull(dt, i, 16)?.ToString("0.00"); + var currencyStr = GetDataSetValue(dt, i, 17); + currencyStr = currencyStr == "其他" ? "Other" : currencyStr; + if (!Enum.TryParse(currencyStr, out CurrencyEnum currency)) { - currency = CurrencyEnum.CNY; + model.Currency = null; } - model.Currency = ((int)currency).ToString(); - model.NotinalPrincipleAmt = GetDataSetValue(dt, i, 15); - model.ClearingAgency = ConsReport.ClearingAgencyMap[GetDataSetValue(dt, i, 16)]; - model.TradingPlace = ConsReport.TradingPlaceMap[GetDataSetValue(dt, i, 17)]; - model.BusinessModelType = ConsReport.BusinessModelTypeMap[GetDataSetValue(dt, i, 18)]; - model.ConfirmationRemark = GetDataSetValue(dt, i, 20); - model.UndrlygAssetType = ConsReport.UndrlygAssetTypeMap[GetDataSetValue(dt, i, 21)]; - model.UndrlygAssetNo = ConsReport.UndrlygAssetNoMap[GetDataSetValue(dt, i, 22)]; - model.ProfitCalculationInfo = GetDataSetValue(dt, i, 23); - model.ProfitRemark = GetDataSetValue(dt, i, 24); - model.PerformanceGuaranteeType = ConsReport.PerformanceGuaranteeMap[GetDataSetValue(dt, i, 25)]; - model.PerformanceCollProvider = ConsReport.PerformanceCollProviderMap[GetDataSetValue(dt, i, 26)]; - model.PartyUseColl = ConsReport.BoolMap[GetDataSetValue(dt, i, 27)]; - model.CollInstruction = GetDataSetValue(dt, i, 28); - model.CalculateCollInterest = ConsReport.BoolMap[GetDataSetValue(dt, i, 29)]; - model.PerformanceCollInitialRatio = GetDataSetValue(dt, i, 30); - model.PerformanceCollAddtlRatio = GetDataSetValue(dt, i, 31); - model.PerformanceCollOffsetRatio = GetDataSetValue(dt, i, 32); - model.PerformanceGuaranteeRemark = GetDataSetValue(dt, i, 33); - model.PerformanceGuaranteeAtt = GetDataSetValue(dt, i, 34); - model.Remark = GetDataSetValue(dt, i, 35); - model.ValidNotinalPrincipleAmt = GetDataSetValue(dt, i, 36); - model.ComplianceOpinion = GetDataSetValue(dt, i, 37); - model.ExercisePriceOne = GetDataSetValue(dt, i, 38); - model.ExercisePriceTwo = GetDataSetValue(dt, i, 39); - model.PtyAPdctName = GetDataSetValue(dt, i, 40); - model.PytAPdctCode = GetDataSetValue(dt, i, 41); - model.PtyBPdctName = GetDataSetValue(dt, i, 42); - model.PytBPdctCode = GetDataSetValue(dt, i, 43); + else + { + model.Currency = ((int)currency).ToString(); - var notinalPrincipleAmt = GetDataSetValueToDouble(dt, i, 15); + } + model.NotinalPrincipleAmt = GetDataSetValueToDoubleOrNull(dt, i, 18)?.ToString("0.00"); + model.ClearingAgency = ConsReport.ClearingAgencyMap[GetDataSetValue(dt, i, 19)]; + model.TradingPlace = ConsReport.TradingPlaceMap[GetDataSetValue(dt, i, 20)]; + model.TradingPlaceOther = GetDataSetValue(dt, i, 21); + //model.BusinessModelType = ConsReport.BusinessModelTypeMap[GetDataSetValue(dt, i, 18)]; + model.ConfirmationRemark = GetDataSetValue(dt, i, 22); + model.UndrlygAssetType = ConsReport.UndrlygAssetTypeMap[GetDataSetValue(dt, i, 23)]; + model.UndrlygAssetNo = ConsReport.UndrlygAssetNoMap[GetDataSetValue(dt, i, 24)]; + model.ProfitCalculationInfo = GetDataSetValue(dt, i, 25); + model.ProfitRemark = GetDataSetValue(dt, i, 26); + model.PerformanceGuaranteeType = ConsReport.PerformanceGuaranteeMap[GetDataSetValue(dt, i, 27)]; + model.PerformanceCollProvider = ConsReport.PerformanceCollProviderMap[GetDataSetValue(dt, i, 28)]; + model.PartyUseColl = ConsReport.BoolMap[GetDataSetValue(dt, i, 29)]; + model.CollInstruction = GetDataSetValue(dt, i, 30); + model.CalculateCollInterest = ConsReport.BoolMap[GetDataSetValue(dt, i, 31)]; + model.PerformanceCollInitialRatio = GetDataSetValue(dt, i, 32); + model.PerformanceCollInitialRatioCash = GetDataSetValue(dt, i, 33); + model.PerformanceCollAddtlRatio = GetDataSetValue(dt, i, 34); + model.PerformanceCollOffsetRatio = GetDataSetValue(dt, i, 35); + model.MaintainGuaranteeRatio = GetDataSetValue(dt, i, 36); + model.PerformanceGuaranteeRemark = GetDataSetValue(dt, i, 37); + model.PerformanceGuaranteeAtt = GetDataSetValue(dt, i, 38); + model.Remark = GetDataSetValue(dt, i, 39); + model.ValidNotinalPrincipleAmt = GetDataSetValueToDoubleOrNull(dt, i, 40)?.ToString("0.00"); + model.ComplianceOpinion = GetDataSetValue(dt, i, 41); + model.PtyAPdctName = GetDataSetValue(dt, i, 42); + model.PytAPdctCode = GetDataSetValue(dt, i, 43); + model.PtyBPdctName = GetDataSetValue(dt, i, 44); + model.PytBPdctCode = GetDataSetValue(dt, i, 45); + model.CrossBorderTransactions = BoolMap[GetDataSetValue(dt, i, 46)]; + model.Blank1 = GetDataSetValue(dt, i, 47); + model.Blank2 = GetDataSetValue(dt, i, 48); - var cacheValue = model.ConfirmationNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + var notinalPrincipleAmt = GetDataSetValueToDouble(dt, i, 18); + + var cacheValue = (model.ConfirmationNo ?? "").ToString(); + if (cacheValue.IsNullOrWhiteSpace()) + { + continue; + } + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -736,7 +286,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (_operationType == OptFlagsEnum.U) { - Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); + var reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); var settleList = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionTermination, formatInfoTag(model, false, true)); if (settleList.Count > 0) { @@ -756,27 +306,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.ConfirmationID = note.BizId;//确认书编号; } - string[] confirmationAttTuple = GetDataSetValue(dt, i, 19).Split(','); - foreach (var item in confirmationAttTuple) - { - if (string.IsNullOrWhiteSpace(item)) - { - continue; - } - if (model.ConfirmationAttTuple == null) - { - model.ConfirmationAttTuple = new List(); - } - model.ConfirmationAttTuple.Add(new ConfirmationAttModel() { ConfirmationAtt = item }); - path = Path.Combine(sourcePath, item); - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - } - model.UndrlygAssetTuple = GetUndrlygAssetModel(model.ConfirmationNo); - model.PerformanceCollTuple = GetPerformanceGuaranteeAttModel(model.ConfirmationNo); + //var confirmationAttTuple = GetDataSetValue(dt, i, 19).Split(','); + //foreach (var item in confirmationAttTuple) + //{ + // if (string.IsNullOrWhiteSpace(item)) + // { + // continue; + // } + // model.ConfirmationAttTuple ??= new List(); + // model.ConfirmationAttTuple.Add(new ConfirmationAttModel() { ConfirmationAtt = item }); + // path = Path.Combine(sourcePath, item); + // if (!ReportStatus.CheckFileLength(path)) + // { + // break; + // } + // fileList.Add(path); + //} + model.UndrlygAssetTuple = GetUndrlygAssetModel(model.ConfirmationNo, model.UndrlygAssetNo, model.UndrlygAssetType); + model.PerformanceCollTuple = GetPerformanceGuaranteeAttModel(model.ConfirmationNo, model.PerformanceGuaranteeType); + + SetOptionStructureModelFromExcel(model); path = Path.Combine(sourcePath, model.PerformanceGuaranteeAtt); if (!string.IsNullOrWhiteSpace(model.PerformanceGuaranteeAtt)) { @@ -797,7 +346,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } model.ExceID = base.formatExceID(); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}"; note.ExceId = model.ExceID; @@ -818,29 +367,33 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - private List GetPerformanceGuaranteeAttModel(string masterAgrmtNo) + private List GetPerformanceGuaranteeAttModel(string masterAgrmtNo, string performanceGuaranteeType) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("履约担保品详情明细")) { - DataTable dt = _excelDataSource.Tables["履约担保品详情明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["履约担保品详情明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != masterAgrmtNo) + if (dt.Rows[i][0]?.ToString().Trim() != masterAgrmtNo) { continue; } - PerformanceGuaranteeAttModel model = new PerformanceGuaranteeAttModel(); - - model.PerformanceCollType = ConsReport.PerformanceCollTypeMap[GetDataSetValue(dt, i, 1)]; - model.PerformanceCollRange = ConsReport.PerformanceCollRangeMap[GetDataSetValue(dt, i, 2)]; - model.MultiConfirmationID = GetDataSetValue(dt, i, 3); + var model = new PerformanceGuaranteeAttModel + { + PerformanceGuaranteeType = performanceGuaranteeType, + ConfirmationNo = GetDataSetValue(dt, i, 0), + PerformanceCollType = ConsReport.PerformanceCollTypeMap[GetDataSetValue(dt, i, 1)], + PerformanceCollRange = ConsReport.PerformanceCollRangeMap[GetDataSetValue(dt, i, 2)], + MultiConfirmationID = GetDataSetValue(dt, i, 3), + Remarks = GetDataSetValue(dt, i, 4) + }; result.Add(model); } @@ -848,12 +401,95 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - private List GetUndrlygAssetModel(string masterAgrmtNo) + private List GetUndrlygAssetModel(string masterAgrmtNo, string undrlygAssetNo, string undrlygAssetType) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("标的详情明细")) { - DataTable dt = _excelDataSource.Tables["标的详情明细"]; + var dt = _excelDataSource.Tables["标的详情明细"]; + for (var i = 1; i < dt.Rows.Count; i++) + { + if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) + { + //第一列空白说明数据结束了; + break; + } + if (dt.Rows[i][0]?.ToString().Trim() != masterAgrmtNo) + { + continue; + } + + var model = new UndrlygAssetModel + { + ConfirmationNo = GetDataSetValue(dt, i, 0), + UndrlygAssetDtldType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 1)], + UndrlygAssetName = GetDataSetValue(dt, i, 2), + UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 3), + UndrlygAssetCode = GetDataSetValue(dt, i, 4), + UndrlygAssetAmt = GetDataSetValue(dt, i, 5) + }; + model.ContractMultiplier = GetDataSetValueToDoubleOrNull(dt, i, 6)?.ToString() ?? ""; + + model.UndrlygAssetNo = undrlygAssetNo; + model.MultiOrderOptionType = MultiOrderOptionTypeMap[GetDataSetValue(dt, i, 7)]; + + model.UndrlygAssetNotinalPrincipleAmtRMB = GetDataSetValueToDoubleOrNull(dt, i, 8)?.ToString(); + model.OpeningPrice = GetDataSetValueToDoubleOrNull(dt, i, 9)?.ToString(); + + model.UndrlygAssetType = undrlygAssetType; + + var currencyStr = GetDataSetValue(dt, i, 10); + currencyStr = currencyStr == "其他" ? "Other" : currencyStr; + if (!Enum.TryParse(currencyStr, out CurrencyEnum currency)) + { + model.OpeningPriceCurrency = ""; + } + else + { + model.OpeningPriceCurrency = ((int)currency).ToString(); + } + + model.Blank1 = GetDataSetValue(dt, i, 11); + model.Blank2 = GetDataSetValue(dt, i, 12); + + result.Add(model); + } + } + return result; + } + + private void SetOptionStructureModelFromExcel(OptionConfirmationModel model) + { + var tbName = ""; + + switch (model.OptionStructureType) + { + case "0": + tbName = "期权结构类型详情(香草及其组合)"; + break; + case "1": + tbName = "期权结构类型详情(二元及其组合)"; + break; + case "2": + tbName = "期权结构类型详情(障碍及其组合)"; + break; + case "3": + tbName = "期权结构类型详情(自动赎回)"; + break; + case "4": + tbName = "期权结构类型详情(区间累计)"; + break; + case "5": + tbName = "期权结构类型详情(安全气囊)"; + break; + case "99": + tbName = "期权结构类型详情(其他)"; + break; + } + + if (_excelDataSource != null && _excelDataSource.Tables.Contains(tbName)) + { + DataTable dt = _excelDataSource.Tables[tbName]; for (int i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) @@ -861,28 +497,147 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != masterAgrmtNo) + if (dt.Rows[i][0]?.ToString().Trim() != model.ConfirmationNo) { continue; } - UndrlygAssetModel model = new UndrlygAssetModel(); - - model.UndrlygAssetDtldType = ConsReport.UndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 1)]; - model.UndrlygAssetName = GetDataSetValue(dt, i, 2); - model.UndrlygAssetTradgPlc = ConsReport.UndrlygAssetTradgPlceMap[GetDataSetValue(dt, i, 3)]; - model.UndrlygAssetCode = GetDataSetValue(dt, i, 4); - model.UndrlygAssetAmt = GetDataSetValue(dt, i, 5); - - result.Add(model); + switch (model.OptionStructureType) + { + case "0": + model.VanillaOptionStructureSubclass = VanillaOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.VanillaStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.VanillaStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.VanillaStrikePriceCoefficientThree = GetDataSetValue(dt, i, 4); + model.VanillaStrikePriceCoefficientFour = GetDataSetValue(dt, i, 5); + model.VanillaEngagementRateOne = GetDataSetValue(dt, i, 6); + model.VanillaEngagementRateTwo = GetDataSetValue(dt, i, 7); + model.VanillaEngagementRateThree = GetDataSetValue(dt, i, 8); + model.VanillaEngagementRateFour = GetDataSetValue(dt, i, 9); + model.VanillaBackCoverYield = GetDataSetValue(dt, i, 10); + model.VanillaCappingYield = GetDataSetValue(dt, i, 11); + model.VanillaBlank1 = GetDataSetValue(dt, i, 12); + model.VanillaBlank2 = GetDataSetValue(dt, i, 13); + break; + case "1": + model.DigitalOptionStructureSubclass = DigitalOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.DigitalStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.DigitalStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.DigitalStrikePriceCoefficientThree = GetDataSetValue(dt, i, 4); + model.DigitalEngagementRateOne = GetDataSetValue(dt, i, 5); + model.DigitalEngagementRateTwo = GetDataSetValue(dt, i, 6); + model.DigitalEngagementRateThree = GetDataSetValue(dt, i, 7); + model.DigitalYieldOneNonAnnualized = GetDataSetValue(dt, i, 8); + model.DigitalYieldTwoNonAnnualized = GetDataSetValue(dt, i, 9); + model.DigitalYieldThreeNonAnnualized = GetDataSetValue(dt, i, 10); + model.DigitalYieldFourNonAnnualized = GetDataSetValue(dt, i, 11); + model.DigitalBlank1 = GetDataSetValue(dt, i, 12); + model.DigitalBlank2 = GetDataSetValue(dt, i, 13); + break; + case "2": + model.BarrierOptionStructureSubclass = BarrierOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.BarrierStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.BarrierStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.BarrierEngagementRateOne = GetDataSetValue(dt, i, 4); + model.BarrierEngagementRateTwo = GetDataSetValue(dt, i, 5); + model.BarrierKnockInPriceCoefficient = GetDataSetValue(dt, i, 6); + model.BarrierKnockOutPriceCoefficientOne = GetDataSetValue(dt, i, 7); + model.BarrierKnockOutYieldOneNonAnnualized = GetDataSetValue(dt, i, 8); + model.BarrierKnockOutPriceCoefficientTwo = GetDataSetValue(dt, i, 9); + model.BarrierKnockOutYieldTwoNonAnnualized = GetDataSetValue(dt, i, 10); + model.BarrierObservationType = BarrierObservationTypeMap[GetDataSetValue(dt, i, 11)]; + model.BarrierBackCoverYield = GetDataSetValue(dt, i, 12); + model.BarrierUnknockedYield = GetDataSetValue(dt, i, 13); + model.BarrierBlank1 = GetDataSetValue(dt, i, 14); + model.BarrierBlank2 = GetDataSetValue(dt, i, 15); + break; + case "3": + model.AutoCallableOptionStructureSubclass = AutoCallableOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.AutoCallableEngagementRate = GetDataSetValueToDouble(dt, i, 2).ToString(); + model.AutoCallableStrikePriceCoefficient = GetDataSetValue(dt, i, 3); + model.AutoCallableKnockOutPriceCoefficient = AddBrackets(GetDataSetValue(dt, i, 4)); + model.AutoCallableKnockOutYieldAnnualized = AddBrackets(GetDataSetValue(dt, i, 5)); + model.AutoCallableKnockOutObservationDay = AddBrackets(GetDataSetValue(dt, i, 6)); + model.AutoCallableKnockOutSettlementDay = AddBrackets(GetDataSetValue(dt, i, 7)); + model.AutoCallableKnockInPriceCoefficient = AddBrackets(GetDataSetValue(dt, i, 8)); + model.AutoCallableKnockInObservationDay = AddBrackets(GetDataSetValue(dt, i, 9)); + model.AutoCallableDividendYieldAnnualized = GetDataSetValue(dt, i, 10); + model.AutoCallableMinimumYieldAnnualized = GetDataSetValue(dt, i, 11); + model.AutoCallableMinimumPrincipalProtectionRatio = GetDataSetValueToDouble(dt, i, 12).ToString(); + model.AutoCallableWhetherDiscountedWarehouseType = + AutoCallableWhetherDiscountedWarehouseTypeMap[GetDataSetValue(dt, i, 13)]; + model.AutoCallableWhetherRevenueEnhancedType = + AutoCallableWhetherRevenueEnhancedTypeMap[GetDataSetValue(dt, i, 14)]; + model.AutoCallableWhetherFixedCouponNote = + AutoCallableWhetherRevenueEnhancedTypeMap[GetDataSetValue(dt, i, 15)]; + model.AutoCallableWhetherKnockInPriceCoefficientIsVariable = + AutoCallableWhetherKnockInPriceCoefficientIsVariableMap[GetDataSetValue(dt, i, 16)]; + model.AutoCallableWhetherKnockOutPriceCoefficientIsVariable = + AutoCallableWhetherKnockOutPriceCoefficientIsVariableMap[GetDataSetValue(dt, i, 17)]; + model.AutoCallableWhetherKnockOutYieldIsVariable = + AutoCallableWhetherKnockOutYieldIsVariableMap[GetDataSetValue(dt, i, 18)]; + model.AutoCallableWhetherDividendYieldIsVariable = + AutoCallableWhetherDividendYieldIsVariableMap[GetDataSetValue(dt, i, 19)]; + model.AutoCallableBlank1 = GetDataSetValue(dt, i, 20); + model.AutoCallableBlank2 = GetDataSetValue(dt, i, 21); + break; + case "4": + model.RangeAccrualOptionStructureSubclass = + RangeAccrualOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.RangeAccrualStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.RangeAccrualStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.RangeAccrualStrikePriceCoefficientThree = GetDataSetValue(dt, i, 4); + model.RangeAccrualStrikePriceCoefficientFour = GetDataSetValue(dt, i, 5); + model.RangeAccrualEngagementRate = GetDataSetValue(dt, i, 6); + model.RangeAccrualOneNonAnnualized = GetDataSetValue(dt, i, 7); + model.RangeAccrualTwoNonAnnualized = GetDataSetValue(dt, i, 8); + model.RangeAccrualThreeNonAnnualized = GetDataSetValue(dt, i, 9); + model.RangeAccrualFourNonAnnualized = GetDataSetValue(dt, i, 10); + //model.RangeAccrualMinimumYieldAnnualized = GetDataSetValue(dt, i, 11); + model.RangeAccrualBlank1 = GetDataSetValue(dt, i, 11); + model.RangeAccrualBlank2 = GetDataSetValue(dt, i, 12); + break; + case "5": + model.AirbagOptionStructureSubclass = + AirbagOptionStructureSubclassMap[GetDataSetValue(dt, i, 1)]; + model.AirbagStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.AirbagStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.AirbagStrikePriceCoefficientThree = GetDataSetValue(dt, i, 4); + model.AirbagStrikePriceCoefficientFour = GetDataSetValue(dt, i, 5); + model.AirbagEngagementRateOne = GetDataSetValue(dt, i, 6); + model.AirbagEngagementRateTwo = GetDataSetValue(dt, i, 7); + model.AirbagEngagementRateThree = GetDataSetValue(dt, i, 8); + model.AirbagKnockInPriceCoefficient = GetDataSetValue(dt, i, 9); + model.AirbagBackCoverYield = GetDataSetValue(dt, i, 10); + model.AirbagCappingYield = GetDataSetValue(dt, i, 11); + model.AirbagBlank1 = GetDataSetValue(dt, i, 12); + model.AirbagBlank2 = GetDataSetValue(dt, i, 13); + break; + case "99": + model.OthersOptionStructureSubclass = GetDataSetValue(dt, i, 1); + model.OthersStrikePriceCoefficientOne = GetDataSetValue(dt, i, 2); + model.OthersStrikePriceCoefficientTwo = GetDataSetValue(dt, i, 3); + model.OthersStrikePriceCoefficientThree = GetDataSetValue(dt, i, 4); + model.OthersStrikePriceCoefficientFour = GetDataSetValue(dt, i, 5); + model.OthersEngagementRateOne = GetDataSetValue(dt, i, 6); + model.OthersEngagementRateTwo = GetDataSetValue(dt, i, 7); + model.OthersEngagementRateThree = GetDataSetValue(dt, i, 8); + model.OthersEngagementRateFour = GetDataSetValue(dt, i, 9); + model.OthersBarrierPricesCoefficientOne = GetDataSetValue(dt, i, 10); + model.OthersBarrierPricesCoefficientTwo = GetDataSetValue(dt, i, 11); + model.OthersBackCoverYield = GetDataSetValue(dt, i, 12); + model.OthersCappingYield = GetDataSetValue(dt, i, 13); + model.OthersBlank1 = GetDataSetValue(dt, i, 14); + model.OthersBlank2 = GetDataSetValue(dt, i, 15); + break; + } } } - return result; } private string formatInfoTag(OptionConfirmationModel model, bool suffixType = false, bool isSettlement = false) { - string result = $"{(isSettlement ? "" : BusiDataType.ToString())}_{model.ConfirmationNo.Replace("_", "-")}_{(isSettlement ? "" : "成交_")}"; + var result = $"{(isSettlement ? "" : BusiDataType.ToString())}_{model.ConfirmationNo.Replace("_", "-")}_{(isSettlement ? "" : "成交_")}"; if (suffixType) { result = $"{result}{_operationType}"; @@ -890,45 +645,43 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 4) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.OptionConfirmation != null) { - CheckHelper helper = new Common.CheckHelper(); - CheckHelper cAttHelper = new Common.CheckHelper(); - CheckHelper undrlygHelper = new Common.CheckHelper(); - CheckHelper pAttHelper = new Common.CheckHelper(); - for (int i = 0; i < model.OptionConfirmation.Count; i++) + var helper = new Common.CheckHelper(); + //var cAttHelper = new Common.CheckHelper(); + var undrlygHelper = new Common.CheckHelper(); + var pAttHelper = new Common.CheckHelper(); + for (var i = 0; i < model.OptionConfirmation.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.OptionConfirmation[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); - if (item.ConfirmationAttTuple != null) - { - for (int j = 0; j < item.ConfirmationAttTuple.Count; j++) - { - var listItem = new List(); - var attItem = item.ConfirmationAttTuple[j]; - cAttHelper.ExecuteCheck(attItem, (name, value, msg) => - { - listItem.Add(new SacInfo(name, value, msg)); - }); - if (listItem.Count > 0) - { - var temp = new SacInfo("ConfirmationAttTuple", j); - temp.SubMaps = new List(listItem); - listRoot.Add(temp); - } - } - } if (item.UndrlygAssetTuple != null) { - for (int j = 0; j < item.UndrlygAssetTuple.Count; j++) + for (var j = 0; j < item.UndrlygAssetTuple.Count; j++) { var listItem = new List(); var undrlygItem = item.UndrlygAssetTuple[j]; @@ -938,15 +691,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("UndrlygAssetTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("UndrlygAssetTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (item.PerformanceCollTuple != null) { - for (int j = 0; j < item.PerformanceCollTuple.Count; j++) + for (var j = 0; j < item.PerformanceCollTuple.Count; j++) { var listItem = new List(); var pItem = item.PerformanceCollTuple[j]; @@ -956,16 +711,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("PerformanceCollTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("PerformanceCollTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("OptionConfirmation", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("OptionConfirmation", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -988,11 +748,30 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger().Error(e); }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } return true; } + + //写一个方法,判断字符串前面是否存在括号,如果不存在,就在前面加上括号,后面同理 + private string AddBrackets(string str) + { + if (str.IsNullOrWhiteSpace()) + { + return str; + } + string result = str; + if (!str.StartsWith("(")) + { + result = "(" + result; + } + if (!str.EndsWith(")")) + { + result += ")"; + } + return result; + } } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionTerminationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionTerminationService.cs index edc0c7cc..c2f56ed3 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionTerminationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOptionTerminationService.cs @@ -1,8 +1,14 @@ -using System.Data; +using FluentFTP.Helpers; +using MoreLinq; +using NPOI.SS.Formula.Functions; +using System.Data; +using System.Linq; using System.Text.RegularExpressions; using YLErp.BLL; +using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Modules.EodModule; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; @@ -10,6 +16,7 @@ using static YLErp.DBModels.Consts.ConsReport; namespace YLErp.Modules.SuperviseReportModule.SAC.Service { + //交易存续期管理 class ReportOptionTerminationService : ReportBaseService { public ReportOptionTerminationService(OptUserInfo optUser) : base(optUser) @@ -22,53 +29,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1007; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, - OptFlagsEnum.U, OptFlagsEnum.D, + OptFlagsEnum.U, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_OptionTermination; - List noteList = new List(); - private List _cacheCodeList = new List(); + + readonly List noteList = new(); + private readonly List _cacheCodeList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { - dataList = GetOptionTerminationFromExcel(); + dataList = GetOptionTerminationModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var cacheKey = $"{BusiDataType}"; - var nextDate = _reqInfo.ReportDate.AddDays(1); - var actions = new List() { "系统操作-平仓费", "系统操作-行权费" }; - using (var db = new YLContext()) - { - dataList.AddRange(GetOptionTerminationExtensionTimeFromDb(db, cacheKey, nextDate)); - - dataList.AddRange(GetOptionTerminationSettlementFromDb(db, cacheKey, nextDate)); - } - } - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); - + } noData = dataList.Count == 0; model.OptionTermination = dataList; @@ -78,7 +71,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(OptionTerminationModel model, List fileList, string tag) { var isExtensionTime = model.DurationOperationType == ConsReport.OperationTypeMap["展期"]; - DateTime date = DateTime.MinValue; + var date = DateTime.MinValue; if (isExtensionTime) { DateTime.TryParse(model.RenewalDate, out date); @@ -88,14 +81,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime.TryParse(model.ExpirationDate, out date); } var extensionTimeInfo = model.DurationOperationType == ConsReport.OperationTypeMap["展期"] ? "-" : ""; - List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_{_operationType}", true);//添加了operationType,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_{_operationType}", true);//添加了operationType,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 //永远查找现有成功报送了结的新增记录,而不是修改; var note = notes.LastOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); if (note == null) { if (isExtensionTime) { - string oldDateStr = ""; + var oldDateStr = ""; var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1004_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) @@ -127,7 +120,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //多次U的时候,每次用最新的tag来赋值SubFileTag if (isExtensionTime) { - string oldDateStr = ""; + var oldDateStr = ""; var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1004_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) @@ -169,374 +162,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - /// - /// 从数据库获取展期记录 - /// - /// - /// - /// - /// - private List GetOptionTerminationExtensionTimeFromDb(YLContext db, string cacheKey, DateTime nextDate) - { - List dataList = new List(); - var extensionTimeList = (from et in db.ExtensionTime - join t in db.trade - on et.TradeId equals t.id - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - where - et.OptDate >= _reqInfo.ReportDate && - et.OptDate < nextDate && - t.TradeType != "收益互换" && - tr.IsValid - select new - { - et.id, - et.TradeId, - et.OldMaturityDate, - et.NewMaturityDate, - et.IsValid, - et.OptDate, - tr.ContractCode, - t.StockEqvNotional - }).ToArray(); - - List ids = extensionTimeList.Select(O => O.TradeId).ToList(); - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - foreach (var item in extensionTimeList) - { - var cacheValue = item.id.ToString(); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - if (metaDic.ContainsKey(item.TradeId)) - { - var metaInfo = metaDic[item.TradeId]; - if (metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) && TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - var info = new OptionTerminationModel(); - - info.TradeId = item.TradeId.ToString(); - info.ConfirmationNo = item.ContractCode; - List notes = base.GetReportNotes(ReportType, $"_{info.ConfirmationNo.Replace("_", "-")}_", true); - var note = notes.FirstOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(info, extensionTimeInfo: item.id.ToString()))); - if (!item.IsValid) - {//当前信息是无效的,报送过就是废止,否则就不需要报 - if (note != null) - { - info.OperationType = OptFlagsEnum.D; - } - else - { - continue; - } - } - else - {//当前信息是有效的,报送过,就是修改,否则就是新增 - if (note == null) - { - info.OperationType = OptFlagsEnum.A; - } - else - { - if (!note.changeStatus) - { - continue; - } - info.OperationType = OptFlagsEnum.U; - } - } - if (info.OperationType != _operationType) - { - continue; - } - switch (info.OperationType) - { - case OptFlagsEnum.A: - note = new SACReportNotes() - { - IsValid = true, - }; - break; - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId; - } - var infoCache = JsonHelper.Deserialize>(note?.InfoCache) ?? new Dictionary(); - var oldMaturityDate = infoCache.TryGetValue("NewMaturityDate", out var date) ? DateTime.Parse(date) : item.OldMaturityDate; - var newMaturityDate = item.NewMaturityDate; - if (info.OperationType == OptFlagsEnum.D) - { - oldMaturityDate = infoCache.TryGetValue("OldMaturityDate", out date) ? DateTime.Parse(date) : item.OldMaturityDate; - newMaturityDate = infoCache.TryGetValue("NewMaturityDate", out date) ? DateTime.Parse(date) : item.NewMaturityDate; - } - else - { - if (newMaturityDate <= oldMaturityDate) - { - throw new ServiceException($"确认书编号:{item.ContractCode}\r\n新展期日:{newMaturityDate.ToString("yyyy-MM-dd")}\r\n原到期日:{oldMaturityDate.ToString("yyyy-MM-dd")}\r\n新展期日应大于原到期日"); - } - } - //info.ExpirationDate = item.OldMaturityDate.ToString("yyyy-MM-dd"); - info.DurationOperationType = OperationTypeMap["展期"]; - info.RenewalDate = newMaturityDate.ToString("yyyy-MM-dd"); - info.Balance = Math.Max(item.StockEqvNotional, 0).ToString("0.00"); - info.ExceID = base.formatExceID(); - - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.ExceId = info.ExceID; - note.InfoCache = $"{{\"Tag\":\"{info.ConfirmationNo}\",\"OldMaturityDate\":\"{oldMaturityDate.ToString("yyyy-MM-dd")}\",\"NewMaturityDate\":\"{newMaturityDate.ToString("yyyy-MM-dd")}\",\"Source\":\"System\"}}"; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true, item.id.ToString()); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - return dataList; - } - /// - /// 从数据库获取结算信息 - /// - /// - /// - /// - /// - private IEnumerable GetOptionTerminationSettlementFromDb(YLContext db, string cacheKey, DateTime nextDate) - { - List dataList = new List(); - var actions = new List() { "系统操作-平仓费", "系统操作-行权费" }; - //当天有回退记录的资金记录 - var query = (from t in db.trade - join log in db.TradeAuditLog on t.id equals log.TradeId - join tc in db.trade_cash on t.id equals tc.TradeId - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - where log.OptDate >= _reqInfo.ReportDate && log.OptDate < nextDate && log.OptType == "交易回退" && t.ParentTradeId == 0 && - actions.Contains(tc.Action) && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType != "收益互换" && tr.IsValid - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - tc.ValueDate, - tc.Notional, - tc.UnwindNotional, - tc.Amount, - t.OriginalNotional, - tr.ContractCode, - t.QuoteCurrency, - t.SettlementCurrency - }).Union//当天有了结的资金记录 - (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - where tc.ValueDate == _reqInfo.DataDate && - t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid && - /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType != "收益互换" && - actions.Contains(tc.Action) - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - tc.ValueDate, - tc.Notional, - tc.UnwindNotional, - tc.Amount, - t.OriginalNotional, - tr.ContractCode, - t.QuoteCurrency, - t.SettlementCurrency - }).ToArray().GroupBy(O => new { O.id, O.ValueDate }).ToDictionary(K => K.Key, V => V.ToList()); - List ids = query.Keys.Select(O => O.id).ToList(); - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - foreach (var item in query) - { - string cacheValue = item.Key.id.ToString() + item.Key.ValueDate.ToString("yyyy-MM-dd"); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - if (metaDic.ContainsKey(item.Key.id)) - { - var metaInfo = metaDic[item.Key.id]; - if (metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) && TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - var info = new OptionTerminationModel(); - - info.TradeId = item.Key.id.ToString(); - var validItem = item.Value.FirstOrDefault(O => O.tradecashValid); - var invalidItem = item.Value.FirstOrDefault(O => !O.tradecashValid); - var obj = invalidItem ?? validItem; - info.ExpirationDate = obj.ValueDate.ToString("yyyy-MM-dd"); - info.ConfirmationNo = obj.ContractCode; - List notes = base.GetReportNotes(ReportType, $"_{info.ConfirmationNo.Replace("_", "-")}_", true); - var note = notes.FirstOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(info)) && O.InfoCache.Contains(info.ExpirationDate)); - if (validItem == null && invalidItem != null) - {//有效资金记录不存在,无效资金记录存在时,当天报送过就是废止,否则就不需要报 - obj = invalidItem; - if (note != null) - { - info.OperationType = OptFlagsEnum.D; - } - else - { - continue; - } - } - else - {//有效资金记录存在时,当天报送过,就是修改,否则就是新增 - obj = validItem; - if (note == null) - { - info.OperationType = OptFlagsEnum.A; - } - else - { - if (!note.changeStatus) - { - continue; - } - info.OperationType = OptFlagsEnum.U; - } - } - - if (info.OperationType != _operationType) - { - continue; - } - switch (info.OperationType) - { - case OptFlagsEnum.A: - note = new SACReportNotes() - { - IsValid = true, - }; - break; - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId; - } - info.ExpirationDate = obj.ValueDate.ToString("yyyy-MM-dd"); - info.DurationOperationType = OperationTypeMap["终止"]; - var quoteRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(obj.QuoteCurrency, "CNY", obj.ValueDate); - var settlementRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(obj.SettlementCurrency, "CNY", obj.ValueDate); - var currentStockEqvNotional = Math.Round(Math.Min((obj.UnwindNotional / obj.OriginalNotional * obj.OriginalStockEqvNotional) ?? 0, obj.OriginalStockEqvNotional ?? 0) * quoteRate, 2); - var latestStockEqvNotional = Math.Round(Math.Min((obj.Notional / obj.OriginalNotional * obj.OriginalStockEqvNotional) ?? 0, obj.OriginalStockEqvNotional ?? 0) * quoteRate, 2); - //是否全部了结 - var isComplete = Math.Abs(obj.Notional - (obj.UnwindNotional ?? 0)) < 1e-4; - if (isComplete) - { - var tcArr = DbContext.trade_cash.Where(O => O.TradeId == obj.id && O.ValueDate < obj.ValueDate && actions.Contains(O.Action)).ToArray(); - var originalStockEqvNotional = obj.OriginalStockEqvNotional ?? 0; - currentStockEqvNotional = originalStockEqvNotional - tcArr.Sum(O => Math.Round(Math.Min((O.UnwindNotional / obj.OriginalNotional * originalStockEqvNotional) ?? 0, originalStockEqvNotional) * quoteRate, 2)); - latestStockEqvNotional = currentStockEqvNotional; - } - info.TerminationAmount = currentStockEqvNotional.ToString("0.00"); - info.Balance = Math.Max((latestStockEqvNotional - currentStockEqvNotional), 0).ToString("0.00"); - info.AmountPaidThisTime = (obj.Amount * settlementRate).ToString(); - info.ExceID = base.formatExceID(); - - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.InfoCache = $"{{\"Tag\":\"{info.ConfirmationNo}\",\"ValueDate\":\"{info.ExpirationDate}\",\"Source\":\"System\"}}"; - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - return dataList; - } /// /// 格式化报送标签,用于关联报表和业务信息 /// @@ -546,25 +171,50 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private string formatInfoTag(OptionTerminationModel model, bool suffixType = false, string extensionTimeInfo = "") { - string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : ($"_{extensionTimeInfo}_展期"))}_"; + var operationTag = ""; + if (model.DurationOperationType == ConsReport.OperationTypeMap["敲入"] || model.DurationOperationType == ConsReport.OperationTypeMap["敲出"]) + { + operationTag = $"_{model.DurationOperationType}"; + } + string result = $"{formatInfoTagStr(model)}{operationTag}_{model.DurationEventNO}_"; if (suffixType) { result = $"{result}{_operationType}"; } return result; } + + private string formatInfoTagStr(OptionTerminationModel model, string extensionTimeInfo = "") + { + string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : ($"_{extensionTimeInfo}_展期"))}"; + return result; + } + + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 5 && arr.Length != 6) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + /// /// 从Excel获取结算信息 /// /// - private List GetOptionTerminationFromExcel() + private List GetOptionTerminationModel(ref List fileList) { - List result = new List(); + var result = new List(); + string path = ""; if (_excelDataSource != null && _excelDataSource.Tables.Contains("期权交易存续期明细")) { - var cacheKey = $"{BusiDataType}"; - DataTable dt = _excelDataSource.Tables["期权交易存续期明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["期权交易存续期明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -572,14 +222,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } var optType = OptFlagsEnum.NONE; - switch (dt.Rows[i][1]?.ToString()) + switch (dt.Rows[i][2]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -589,63 +245,55 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - OptionTerminationModel model = new OptionTerminationModel(); - - model.ConfirmationNo = GetDataSetValue(dt, i, 0); - model.OperationType = optType; - model.ExpirationDate = GetDataSetValue(dt, i, 2); - model.DefaultingParty = ConsReport.OptionTraderMap[GetDataSetValue(dt, i, 3)]; - model.DefaultEvent = GetDataSetValue(dt, i, 4); - model.RenewalDate = GetDataSetValue(dt, i, 5); - model.DurationOperationType = ConsReport.OperationTypeMap[GetDataSetValue(dt, i, 6)]; - model.TerminationAmount = GetDataSetValue(dt, i, 7); - model.Balance = GetDataSetValue(dt, i, 8); - model.AmountPaidThisTime = GetDataSetValue(dt, i, 9); - - var isExtensionTime = model.DurationOperationType == ConsReport.OperationTypeMap["展期"]; - DateTime date = DateTime.MinValue; - if (isExtensionTime) + DateTime.TryParse(GetDataSetValue(dt, i, 4), out DateTime expirationDate); + var model = new OptionTerminationModel { - DateTime.TryParse(model.RenewalDate, out date); - } - else + DurationEventNO = GetDataSetValue(dt, i, 0), + ConfirmationNo = GetDataSetValue(dt, i, 1), + OperationType = optType, + DurationOperationType = ConsReport.OperationTypeMap[GetDataSetValue(dt, i, 3)], + ExpirationDate = expirationDate == DateTime.MinValue ? null : expirationDate.ToString("yyyy-MM-dd"), + RenewalDate = GetDataSetValue(dt, i, 5), + }; + model.DefaultingParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 6)]; + model.DefaultEvent = GetDataSetValue(dt, i, 7); + model.TerminationAmount = GetDataSetValue(dt, i, 8); + model.Balance = GetDataSetValueToDoubleOrNull(dt, i, 9)?.ToString("0.00"); + model.AmountPaidThisTime = GetDataSetValue(dt, i, 10); + model.ClosedTransactionsRealRateReturn = GetDataSetValue(dt, i, 11); + // model.TerminationAmount = GetDataSetValueToDouble(dt, i, 8).ToString("0.00"); + // model.Balance = GetDataSetValueToDouble(dt, i, 9).ToString("0.00"); + // model.AmountPaidThisTime = GetDataSetValueToDouble(dt, i, 10).ToString("0.00"); + // model.ClosedTransactionsRealRateReturn = GetDataSetValueToDouble(dt, i, 11).ToString("0.00"); + model.OptionDurationManagementAtt = GetDataSetValue(dt, i, 12); + var eventStatus = ""; + switch (model.DurationOperationType) { - DateTime.TryParse(model.ExpirationDate, out date); + case "05": + eventStatus = "01"; + break; + case "06": + eventStatus = "02"; + break; } - var cacheValue = model.ConfirmationNo + date.ToString("yyyy-MM-dd"); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + model.BarrierEventStatus = eventStatus; + model.Blank1 = GetDataSetValue(dt, i, 14); + model.Blank2 = GetDataSetValue(dt, i, 15); + + DateTime.TryParse(model.ExpirationDate, out DateTime date); + var cacheValue = $"{model.ConfirmationNo}_{model.DurationEventNO}_"; + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - var extensionTimeInfo = model.DurationOperationType == ConsReport.OperationTypeMap["展期"] ? "-" : ""; - List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_", true); - //永远查找现有成功报送了结的新增记录,而不是修改; - var note = notes.LastOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); + List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); + var note = notes.LastOrDefault(O => O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); if (note == null && _operationType == OptFlagsEnum.A) { - if (isExtensionTime) + note = new SACReportNotes() { - string oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1004_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); - oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; - if (DateTime.TryParse(oldDateStr, out var oldDate)) - { - oldDateStr = $",\"OldMaturityDate\":\"{oldDate.ToString("yyyy-MM-dd")}\""; - } - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"Source\":\"Template\"}}", - IsValid = true, - }; - } - else - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"Source\":\"Template\"}}", - IsValid = true, - }; - } + IsValid = true, + }; } else { @@ -667,22 +315,31 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service default: throw new ServiceException("未知操作类型"); } - note.InfoCache = Regex.Replace(note.InfoCache, "(?<=NewMaturityDate\":\")[^\"]+ (?= \")", date.ToString("yyyy-MM-dd")); } if (model.OperationType != OptFlagsEnum.A) { model.BizID = note.BizId;//确认书编号; } + path = Path.Combine(sourcePath, model.OptionDurationManagementAtt); + if (!string.IsNullOrWhiteSpace(model.OptionDurationManagementAtt)) + { + if (!ReportStatus.CheckFileLength(path)) + { + break; + } + fileList.Add(path); + } model.ExceID = base.formatExceID(); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); + note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\"}}"; note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; note.FileTag = FileTag; note.ReportType = ReportType; note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(model, true, extensionTimeInfo); + note.InfoTag = formatInfoTag(model, true); note.OptTime = note.CreateTime; note.RetCode = ""; note.RetMsg = ""; @@ -698,13 +355,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.OptionTermination != null) { - CheckHelper helper = new Common.CheckHelper(); - for (int i = 0; i < model.OptionTermination.Count; i++) + var helper = new Common.CheckHelper(); + for (var i = 0; i < model.OptionTermination.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.OptionTermination[i]; helper.ExecuteCheck(item, (name, value, msg) => { @@ -712,8 +369,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listRoot.Count > 0) { - var errMsg = new SacInfo("OptionTermination", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("OptionTermination", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -736,7 +396,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger().Error(e); }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOtherReportService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOtherReportService.cs index 76eb8d8e..c0af87f8 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOtherReportService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportOtherReportService.cs @@ -15,25 +15,23 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1010; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_OtherReport; - List noteList = new List(); + + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -63,7 +61,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service errMsg = "其他事项报告非新增报送时,对应的业务编码不应为空"; return false; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(req.OtherReportDate?.ToString("yyyy-MM-dd"))).Where(O => O.ReportDate == req.OtherReportDate).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(req.OtherReportDate?.ToString("yyyy-MM-dd"))).Where(O => O.ReportDate == req.OtherReportDate).FirstOrDefault(); if (note == null) { errMsg = $"{req.OtherReportDate?.ToString("yyyy-MM-dd")}不存在报送成功的其他事项报告记录,请重新选择"; @@ -72,7 +70,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (req.OtherReportStatus == OptFlagsEnum.U) { var fileIds = tempFilesService.QueryTempFile(req.ReportDate, "其他事项报告").Select(O => O.id.ToString()).ToArray(); - string[] fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + var fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (!fileIds.Except(fileIdArr).Any()) { errMsg = $"{req.ReportDate.ToString("yyyy-MM-dd")}已上传其他事项报告附件都已报送成功,不需要再次报送"; @@ -103,9 +101,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList = new List(); noData = false; var noteKey = formatInfoTag(_reqInfo.ReportDate.ToString("yyyy-MM-dd")); - BodyModel model = new BodyModel(); - model.OtherReport = new OtherReportModel(); - SACReportNotes note = base.GetReportNotes(ReportType, noteKey).FirstOrDefault(); + var model = new BodyModel + { + OtherReport = new OtherReportModel() + }; + var note = base.GetReportNotes(ReportType, noteKey).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -161,8 +161,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { ReportStatus.AddCacheInfo(noteKey, item.fileName); } - var info = new OtherReportFileDetailModel(); - info.OtherReportFile = item.fileName; + var info = new OtherReportFileDetailModel + { + OtherReportFile = item.fileName + }; if (model.OtherReport.OtherReportFileTuple == null) { model.OtherReport.OtherReportFileTuple = new List(); @@ -174,8 +176,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.OtherReport.DetailedDescription = _reqInfo.OtherReportDesc; } model.OtherReport.ExceID = base.formatExceID(); - List notes = base.GetReportNotes(ReportType, noteKey); - noData = (!(model.OtherReport.OtherReportFileTuple?.Count > 0)); + var notes = base.GetReportNotes(ReportType, noteKey); + noData = !(model.OtherReport.OtherReportFileTuple?.Count > 0); if (!noData) { note.id = 0; @@ -198,19 +200,19 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.OtherReport != null) { - List listRoot = new List(); - CheckHelper helper = new CheckHelper(); - CheckHelper detailHelper = new CheckHelper(); + var listRoot = new List(); + var helper = new CheckHelper(); + var detailHelper = new CheckHelper(); helper.ExecuteCheck(model.OtherReport, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.OtherReport.OtherReportFileTuple != null) { - for (int i = 0; i < model.OtherReport.OtherReportFileTuple.Count; i++) + for (var i = 0; i < model.OtherReport.OtherReportFileTuple.Count; i++) { var listItem = new List(); var item = model.OtherReport.OtherReportFileTuple[i]; @@ -220,16 +222,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("OtherReportFileTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("OtherReportFileTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("OtherReport"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("OtherReport") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -239,7 +245,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(string tag, bool suffixType = false) { - string result = $"{BusiDataType}_{tag}_"; + var result = $"{BusiDataType}_{tag}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -247,10 +253,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPerformanceGuaranteeAgrmtService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPerformanceGuaranteeAgrmtService.cs index 52ae67fd..773ea660 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPerformanceGuaranteeAgrmtService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPerformanceGuaranteeAgrmtService.cs @@ -19,151 +19,38 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1008; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt; - List noteList = new List(); + + readonly List noteList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetPerformanceGuaranteeAgrmtModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var cacheKey = $"{BusiDataType}"; - using (var baseDb = DbContextFactory.GetClientDbContext(null)) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var fileObjList = (from c in baseDb.client - join cf in baseDb.client_file - on c.id equals cf.ClientId - where c.ProcessStatus == "已开户" && cf.HasSent == false && cf.IsValid && - cf.FileTypeName == ConsGlobal.ClientFileType.DateMargin && cf.OptState == _operationType && - ((c.ProcessOptDate >= _reqInfo.ReportDate && c.ProcessOptDate < nextDate && cf.OptDate < nextDate) ||//如果这一天开户,则把这一天之前(含这一天)的所有文件都报送了 - (cf.OptDate >= _reqInfo.ReportDate && cf.OptDate < nextDate && c.ProcessOptDate < _reqInfo.ReportDate))//如果这一天不是开户日期,则只在报送日期大于开户日期时,报送当日修改的文件 - && cf.ApprovalOrder < 1 - select new - { - cf.id, - cf.ProtocolNumber, - cf.MainProtocolNumber, - cf.FilePath, - cf.FileName, - cf.SignDate, - }).ToArray(); - var codes = fileObjList.Select(O => O.MainProtocolNumber); - ExpandoDictionary protocolFileDict = null; - if (codes.Count() > 0) - { - protocolFileDict = new ExpandoDictionary( - baseDb.client_file - .Where(O => O.ApprovalOrder < 1 && O.FileTypeName == ConsGlobal.ClientFileType.EnhanceProtocol && codes.Contains(O.ProtocolNumber) && O.IsValid) - .AsEnumerable() - .GroupBy(O => O.ProtocolNumber) - .ToDictionary(K => K.Key, V => V.FirstOrDefault()) - ); - } - foreach (var item in fileObjList) - { - var info = new PerformanceGuaranteeAgrmtModel(); - info.OperationType = _operationType; - info.MasterAgrmtNo = protocolFileDict[item.MainProtocolNumber ?? ""]?.MainProtocolNumber; - info.SupAgrmtNo = protocolFileDict[item.MainProtocolNumber ?? ""]?.ProtocolNumber; - info.PerformanceGuaranteeAgrmt = item.FileName; - info.SigningDate = item.SignDate?.ToString("yyyy-MM-dd"); - var cacheValue = info.MasterAgrmtNo + "_" + info.SupAgrmtNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{info.PerformanceGuaranteeAgrmt}\",\"Source\":\"System\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.PerformanceGuaranteeAgrmtID = note.BizId; - } - info.ExceID = base.formatExceID(); - if (!ReportStatus.CheckFileLength(item.FilePath)) - { - break; - } - else - { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - } - dataList.Add(info); - fileList.Add(item.FilePath); - note.id = 0; - note.DataId = item.id.ToString(); - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.PerformanceGuaranteeAgrmt = dataList; @@ -172,7 +59,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(PerformanceGuaranteeAgrmtModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model,true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -200,7 +87,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service throw new ServiceException("未知操作类型"); } } - + if (!string.IsNullOrEmpty(model.PerformanceGuaranteeAgrmt)) { fileList.Add(model.PerformanceGuaranteeAgrmt); @@ -225,7 +112,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(PerformanceGuaranteeAgrmtModel model, bool suffixType = false) { - string result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.SupAgrmtNo.Replace("_", "-")}_"; + var result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.SupAgrmtNo.Replace("_", "-")}_{model.PerformanceGuaranteeAgrmt.Replace("_", "-")}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -233,15 +120,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + originalCode = ""; + return infoTag; + } + private List GetPerformanceGuaranteeAgrmtModel(ref List fileList) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("履约保证书明细")) { - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["履约保证书明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["履约保证书明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -251,12 +143,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][2]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -266,20 +164,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - PerformanceGuaranteeAgrmtModel model = new PerformanceGuaranteeAgrmtModel(); - - model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); - model.SupAgrmtNo = GetDataSetValue(dt, i, 1); - model.OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U; - model.PerformanceGuaranteeAgrmt = GetDataSetValue(dt, i, 3); - model.SigningDate = GetDataSetValue(dt, i, 4); - var cacheValue = model.MasterAgrmtNo + "_" + model.SupAgrmtNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + var model = new PerformanceGuaranteeAgrmtModel + { + MasterAgrmtNo = GetDataSetValue(dt, i, 0), + SupAgrmtNo = GetDataSetValue(dt, i, 1), + OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U, + PerformanceGuaranteeAgrmt = GetDataSetValue(dt, i, 3), + SigningDate = GetDataSetValue(dt, i, 4) + }; + var cacheValue = model.MasterAgrmtNo + "_" + model.SupAgrmtNo + "_" + model.PerformanceGuaranteeAgrmt; + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -316,14 +215,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (!string.IsNullOrWhiteSpace(model.PerformanceGuaranteeAgrmt)) { model.ExceID = base.formatExceID(); - string path = Path.Combine(sourcePath, model.PerformanceGuaranteeAgrmt); + var path = Path.Combine(sourcePath, model.PerformanceGuaranteeAgrmt); if (!ReportStatus.CheckFileLength(path)) { break; } else { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); } result.Add(model); fileList.Add(path); @@ -349,23 +248,30 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model.PerformanceGuaranteeAgrmt != null) { - CheckHelper helper = new Common.CheckHelper(); - for (int i = 0; i < model.PerformanceGuaranteeAgrmt.Count; i++) + var helper = new Common.CheckHelper(); + for (var i = 0; i < model.PerformanceGuaranteeAgrmt.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.PerformanceGuaranteeAgrmt[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (listRoot.Count > 0) { - var errMsg = new SacInfo("PerformanceGuaranteeAgrmt", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("PerformanceGuaranteeAgrmt", i) + { + FieldValue = item.MasterAgrmtNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -391,7 +297,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportISDAService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportISDAService.cs index a9d411bb..83424816 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportISDAService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportISDAService.cs @@ -20,19 +20,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1013; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } @@ -40,7 +37,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime minDate = DateTime.MinValue; DateTime maxDate = DateTime.MinValue; protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_PeriodicReportISDA; - List noteList = new List(); + + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -59,7 +57,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service case OptFlagsEnum.D: minDate = req.ISDAReportDate.Value.Date.AddDays(-req.ISDAReportDate.Value.Day).AddDays(1); maxDate = req.ISDAReportDate.Value.Date.AddMonths(1).AddDays(-req.ISDAReportDate.Value.Day); - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(req.ISDAReportDate.Value.ToString("yyyy-MM"))).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(req.ISDAReportDate.Value.ToString("yyyy-MM"))).FirstOrDefault(); if (note == null) { errMsg = $"{minDate.ToString("yyyy-MM-dd")}~{maxDate.ToString("yyyy-MM-dd")}不存在报送成功的ISDA定期报告记录,请重新选择"; @@ -86,16 +84,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); noData = true; - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; + var model = new BodyModel(); var cacheValue = formatInfoTag(_reqInfo.ISDAReportDate.Value.ToString("yyyy-MM")); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { return model; } - model.PeriodicReportISDA = new PeriodicReportISDAModel(); - model.PeriodicReportISDA.OperationType = _operationType; - SACReportNotes note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); + model.PeriodicReportISDA = new PeriodicReportISDAModel + { + OperationType = _operationType + }; + var note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -128,7 +127,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (_excelDataSource != null) { - DataTable dt = _excelDataSource.Tables["业务统计"]; + var dt = _excelDataSource.Tables["业务统计"]; model.PeriodicReportISDA.Year = _reqInfo.ISDAReportDate.Value.Year.ToString("0000"); model.PeriodicReportISDA.Month = _reqInfo.ISDAReportDate.Value.Month.ToString("0"); model.PeriodicReportISDA.OperationType = _operationType; @@ -151,7 +150,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.PeriodicReportISDA.ExceID = base.formatExceID(); } - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); noData = string.IsNullOrWhiteSpace(model.PeriodicReportISDA?.MainAgreementLastMonthAccumulatedThisYear); if (!noData) { @@ -486,24 +485,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetIncreaseBusinessDetailsThisMonthTuple() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("本月新增业务明细")) { - DataTable dt = _excelDataSource.Tables["本月新增业务明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["本月新增业务明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { - string colHead = dt.Rows[i][0]?.ToString(); + var colHead = dt.Rows[i][0]?.ToString(); if (string.IsNullOrWhiteSpace(colHead) || colHead.Contains("合计")) { //第一列空白说明数据结束了; break; } - ISDAIncreaseBusinessDetailsThisMonthModel model = new ISDAIncreaseBusinessDetailsThisMonthModel(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(); - model.NameOfCounterparty = GetDataSetValue(dt, i, 2).ToString(); - model.NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3).ToString(); - model.TradeConfirmationNumber = GetDataSetValue(dt, i, 4); - model.TransactionConfirmationNumber = GetDataSetValue(dt, i, 5); + var model = new ISDAIncreaseBusinessDetailsThisMonthModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(), + NameOfCounterparty = GetDataSetValue(dt, i, 2).ToString(), + NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3).ToString(), + TradeConfirmationNumber = GetDataSetValue(dt, i, 4), + TransactionConfirmationNumber = GetDataSetValue(dt, i, 5) + }; if (model.TransactionConfirmationNumber.IsNullOrWhiteSpace()) { model.TransactionConfirmationNumber = base.GetBizIdFromInfoTag(model.TradeConfirmationNumber); @@ -516,7 +517,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.InvestmentTargetType = ConsReport.UndrlygAssetTypeMap[GetDataSetValue(dt, i, 11).ToString()]; model.UndrlygAssetName = GetDataSetValue(dt, i, 12).ToString(); model.UndrlygAssetCode = GetDataSetValue(dt, i, 13).ToString(); - model.OptionObjectSecondClass = ConsReport.UndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 14).ToString()]; + model.OptionObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 14).ToString()]; model.SwapObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15).ToString()]; model.NonAnnualOptionFee = GetDataSetValue(dt, i, 16).ToString(); model.OptionType = ConsReport.OptionStructureTypeMap[GetDataSetValue(dt, i, 17).ToString()]; @@ -532,24 +533,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetInventoryBusinessDetailsAtTheEndOfThisMonthTuple() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("本月末存量业务明细")) { - DataTable dt = _excelDataSource.Tables["本月末存量业务明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["本月末存量业务明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { - string colHead = dt.Rows[i][0]?.ToString(); + var colHead = dt.Rows[i][0]?.ToString(); if (string.IsNullOrWhiteSpace(colHead) || colHead.Contains("合计")) { //第一列空白说明数据结束了; break; } - ISDAInventoryBusinessDetailsAtTheEndOfThisMonthModel model = new ISDAInventoryBusinessDetailsAtTheEndOfThisMonthModel(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(); - model.NameOfCounterparty = GetDataSetValue(dt, i, 2).ToString(); - model.NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3).ToString(); - model.TradeConfirmationNumber = GetDataSetValue(dt, i, 4); - model.TransactionConfirmationNumber = GetDataSetValue(dt, i, 5); + var model = new ISDAInventoryBusinessDetailsAtTheEndOfThisMonthModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(), + NameOfCounterparty = GetDataSetValue(dt, i, 2).ToString(), + NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3).ToString(), + TradeConfirmationNumber = GetDataSetValue(dt, i, 4), + TransactionConfirmationNumber = GetDataSetValue(dt, i, 5) + }; if (model.TransactionConfirmationNumber.IsNullOrWhiteSpace()) { model.TransactionConfirmationNumber = base.GetBizIdFromInfoTag(model.TradeConfirmationNumber); @@ -563,7 +566,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.UndrlygAssetName = GetDataSetValue(dt, i, 12).ToString(); model.UndrlygAssetCode = GetDataSetValue(dt, i, 13).ToString(); model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 14).ToString(); - model.OptionObjectSecondClass = ConsReport.UndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15).ToString()]; + model.OptionObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15).ToString()]; model.SwapObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 16).ToString()]; model.NonAnnualOptionFee = GetDataSetValue(dt, i, 17).ToString(); model.OptionType = ConsReport.OptionStructureTypeMap[GetDataSetValue(dt, i, 18).ToString()]; @@ -583,30 +586,32 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetTargetCaseAndHedgeTuple() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("标的情况与对冲")) { - DataTable dt = _excelDataSource.Tables["标的情况与对冲"]; - for (int i = 2; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["标的情况与对冲"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - ISDATargetCaseAndHedgeModel model = new ISDATargetCaseAndHedgeModel(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(); - model.BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 2).ToString()]; - model.InvestmentTargetType = ConsReport.HedgeSACUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 3).ToString()]; - model.InvestmentTarget = GetDataSetValue(dt, i, 4).ToString(); - model.UnderlyingCode = GetDataSetValue(dt, i, 5).ToString(); - model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 6).ToString(); - model.BuyingImpulseVolume = GetDataSetValue(dt, i, 7).ToString(); - model.SellingImpulseVolume = GetDataSetValue(dt, i, 8).ToString(); - model.ImpulseVolume = GetDataSetValue(dt, i, 9).ToString(); - model.PositionAtTheEndOfThisMonth = GetDataSetValue(dt, i, 10).ToString(); - model.TheNumberOfPositionsHeldAtTheEndOfThisMonth = GetDataSetValue(dt, i, 11).ToString(); - model.AveragePriceAtTheEndOfTheMonth = GetDataSetValue(dt, i, 12).ToString(); + var model = new ISDATargetCaseAndHedgeModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1).ToString(), + BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 2).ToString()], + InvestmentTargetType = ConsReport.HedgeSACUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 3).ToString()], + InvestmentTarget = GetDataSetValue(dt, i, 4).ToString(), + UnderlyingCode = GetDataSetValue(dt, i, 5).ToString(), + UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 6).ToString(), + BuyingImpulseVolume = GetDataSetValue(dt, i, 7).ToString(), + SellingImpulseVolume = GetDataSetValue(dt, i, 8).ToString(), + ImpulseVolume = GetDataSetValue(dt, i, 9).ToString(), + PositionAtTheEndOfThisMonth = GetDataSetValue(dt, i, 10).ToString(), + TheNumberOfPositionsHeldAtTheEndOfThisMonth = GetDataSetValue(dt, i, 11).ToString(), + AveragePriceAtTheEndOfTheMonth = GetDataSetValue(dt, i, 12).ToString() + }; result.Add(model); } @@ -616,21 +621,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.PeriodicReportISDA != null) { - List listRoot = new List(); - CheckHelper helper = new Common.CheckHelper(); - CheckHelper detailHelper = new Common.CheckHelper(); - CheckHelper detail2Helper = new Common.CheckHelper(); - CheckHelper hedgeHelper = new Common.CheckHelper(); + var listRoot = new List(); + var helper = new Common.CheckHelper(); + var detailHelper = new Common.CheckHelper(); + var detail2Helper = new Common.CheckHelper(); + var hedgeHelper = new Common.CheckHelper(); helper.ExecuteCheck(model.PeriodicReportISDA, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.PeriodicReportISDA.IncreaseBusinessDetailsThisMonthTuple != null) { - for (int i = 0; i < model.PeriodicReportISDA.IncreaseBusinessDetailsThisMonthTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportISDA.IncreaseBusinessDetailsThisMonthTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportISDA.IncreaseBusinessDetailsThisMonthTuple[i]; @@ -640,15 +645,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("IncreaseBusinessDetailsThisMonthTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("IncreaseBusinessDetailsThisMonthTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportISDA.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) { - for (int i = 0; i < model.PeriodicReportISDA.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportISDA.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportISDA.InventoryBusinessDetailsAtTheEndOfThisMonthTuple[i]; @@ -658,15 +665,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("InventoryBusinessDetailsAtTheEndOfThisMonthTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("InventoryBusinessDetailsAtTheEndOfThisMonthTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportISDA.TargetCaseAndHedgeTuple != null) { - for (int i = 0; i < model.PeriodicReportISDA.TargetCaseAndHedgeTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportISDA.TargetCaseAndHedgeTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportISDA.TargetCaseAndHedgeTuple[i]; @@ -676,16 +685,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("TargetCaseAndHedgeTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("TargetCaseAndHedgeTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("PeriodicReportISDA"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("PeriodicReportISDA") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -695,7 +708,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(string tag, bool suffixType = false) { - string result = $"{BusiDataType}_{tag}_"; + var result = $"{BusiDataType}_{tag}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -703,10 +716,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportNAFMIIService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportNAFMIIService.cs index 11ee25bc..2b8e5cf1 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportNAFMIIService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportNAFMIIService.cs @@ -19,19 +19,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1012; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } @@ -39,7 +36,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime minDate = DateTime.MinValue; DateTime maxDate = DateTime.MinValue; protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII; - List noteList = new List(); + + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -58,7 +56,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service case OptFlagsEnum.D: minDate = req.NAFMIIReportDate.Value.Date.AddDays(-req.NAFMIIReportDate.Value.Day).AddDays(1); maxDate = req.NAFMIIReportDate.Value.Date.AddMonths(1).AddDays(-req.NAFMIIReportDate.Value.Day); - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(req.NAFMIIReportDate.Value.ToString("yyyy-MM"))).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(req.NAFMIIReportDate.Value.ToString("yyyy-MM"))).FirstOrDefault(); if (note == null) { errMsg = $"{minDate.ToString("yyyy-MM-dd")}~{maxDate.ToString("yyyy-MM-dd")}不存在报送成功的NAFMII定期报告记录,请重新选择"; @@ -85,16 +83,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); noData = true; - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; + var model = new BodyModel(); var cacheValue = formatInfoTag(_reqInfo.NAFMIIReportDate.Value.ToString("yyyy-MM")); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { return model; } - model.PeriodicReportNAFMII = new PeriodicReportNAFMIIModel(); - model.PeriodicReportNAFMII.OperationType = _operationType; - SACReportNotes note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); + model.PeriodicReportNAFMII = new PeriodicReportNAFMIIModel + { + OperationType = _operationType + }; + var note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -131,7 +130,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (_excelDataSource != null) { - DataTable dt = _excelDataSource.Tables["业务统计"]; + var dt = _excelDataSource.Tables["业务统计"]; model.PeriodicReportNAFMII.Year = _reqInfo.NAFMIIReportDate.Value.Year.ToString("0000"); model.PeriodicReportNAFMII.Month = _reqInfo.NAFMIIReportDate.Value.Month.ToString("0"); model.PeriodicReportNAFMII.OperationType = _operationType; @@ -145,7 +144,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.PeriodicReportNAFMII.ExceID = base.formatExceID(); } noData = string.IsNullOrWhiteSpace(model.PeriodicReportNAFMII?.MainAgreementLastMonthAccumulatedThisYear); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); if (!noData) { note.id = 0; @@ -276,31 +275,33 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetScheduleOfOtherTransactionModel() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("其他交易明细")) { - DataTable dt = _excelDataSource.Tables["其他交易明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["其他交易明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - ScheduleOfOtherTransactionModel model = new ScheduleOfOtherTransactionModel(); - model.TradingDate = GetDataSetValue(dt, i, 1).ToString(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(); - model.FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(); - model.NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(); - model.CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(); - model.BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 6).ToString()]; - model.CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 7).ToString()]; - model.CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 8).ToString()]; - model.NotionalPrincipalAmount = GetDataSetValue(dt, i, 9).ToString(); - model.InvestmentTargetType = ConsReport.NAFMIIUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 10).ToString()]; - model.InvestmentTarget = GetDataSetValue(dt, i, 11).ToString(); - model.StartDate = GetDataSetValue(dt, i, 12).ToString(); - model.ContractExpirationDate = GetDataSetValue(dt, i, 13).ToString(); + var model = new ScheduleOfOtherTransactionModel + { + TradingDate = GetDataSetValue(dt, i, 1).ToString(), + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(), + FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(), + NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(), + CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(), + BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 6).ToString()], + CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 7).ToString()], + CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 8).ToString()], + NotionalPrincipalAmount = GetDataSetValue(dt, i, 9).ToString(), + InvestmentTargetType = ConsReport.NAFMIIUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 10).ToString()], + InvestmentTarget = GetDataSetValue(dt, i, 11).ToString(), + StartDate = GetDataSetValue(dt, i, 12).ToString(), + ContractExpirationDate = GetDataSetValue(dt, i, 13).ToString() + }; result.Add(model); } @@ -314,40 +315,42 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetInterestRateSwapDetailModel() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("利率互换明细")) { - DataTable dt = _excelDataSource.Tables["利率互换明细"]; - for (int i = 2; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["利率互换明细"]; + for (var i = 2; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - InterestRateSwapDetailModel model = new InterestRateSwapDetailModel(); - model.TransactionDate = GetDataSetValue(dt, i, 1).ToString(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(); - model.FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(); - model.NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(); - model.CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(); - model.CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 6).ToString()]; - model.CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 7).ToString()]; - model.FixedInterestPaymentParty = GetDataSetValue(dt, i, 8).ToString(); - model.FloatingInterestPaymentParty = GetDataSetValue(dt, i, 9).ToString(); - model.NotionalPrincipalAmount = GetDataSetValue(dt, i, 10).ToString(); - model.ContractPeriod = GetDataSetValue(dt, i, 11).ToString(); - model.DalueDate = GetDataSetValue(dt, i, 12).ToString(); - model.DueDate = GetDataSetValue(dt, i, 13).ToString(); - model.FixedRate = GetDataSetValue(dt, i, 14).ToString(); - model.FixedRatePaymentCycle = GetDataSetValue(dt, i, 15).ToString(); - model.FixedInterestRateBasis = GetDataSetValue(dt, i, 16).ToString(); - model.NameOfReferenceRate = GetDataSetValue(dt, i, 17).ToString(); - model.Spreads = GetDataSetValue(dt, i, 18).ToString(); - model.FloatingRatePaymentCycle = GetDataSetValue(dt, i, 19).ToString(); - model.ResetTheFrequency = GetDataSetValue(dt, i, 20).ToString(); - model.FloatingInterestRateBasis = GetDataSetValue(dt, i, 21).ToString(); - model.FirstInterestPaymentDay = GetDataSetValue(dt, i, 22).ToString(); + var model = new InterestRateSwapDetailModel + { + TransactionDate = GetDataSetValue(dt, i, 1).ToString(), + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(), + FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(), + NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(), + CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(), + CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 6).ToString()], + CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 7).ToString()], + FixedInterestPaymentParty = GetDataSetValue(dt, i, 8).ToString(), + FloatingInterestPaymentParty = GetDataSetValue(dt, i, 9).ToString(), + NotionalPrincipalAmount = GetDataSetValue(dt, i, 10).ToString(), + ContractPeriod = GetDataSetValue(dt, i, 11).ToString(), + DalueDate = GetDataSetValue(dt, i, 12).ToString(), + DueDate = GetDataSetValue(dt, i, 13).ToString(), + FixedRate = GetDataSetValue(dt, i, 14).ToString(), + FixedRatePaymentCycle = GetDataSetValue(dt, i, 15).ToString(), + FixedInterestRateBasis = GetDataSetValue(dt, i, 16).ToString(), + NameOfReferenceRate = GetDataSetValue(dt, i, 17).ToString(), + Spreads = GetDataSetValue(dt, i, 18).ToString(), + FloatingRatePaymentCycle = GetDataSetValue(dt, i, 19).ToString(), + ResetTheFrequency = GetDataSetValue(dt, i, 20).ToString(), + FloatingInterestRateBasis = GetDataSetValue(dt, i, 21).ToString(), + FirstInterestPaymentDay = GetDataSetValue(dt, i, 22).ToString() + }; result.Add(model); } @@ -361,34 +364,36 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetInterestRateOptionDetailModel() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("利率期权明细")) { - DataTable dt = _excelDataSource.Tables["利率期权明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["利率期权明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - InterestRateOptionDetailModel model = new InterestRateOptionDetailModel(); - model.TradingDate = GetDataSetValue(dt, i, 1).ToString(); - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(); - model.FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(); - model.NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(); - model.CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(); - model.BusinessType = ConsReport.OptionTraderMap[GetDataSetValue(dt, i, 6).ToString()]; - model.OptionType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 7).ToString()]; - model.OptionPosition = ConsReport.NAFMIIOptionDirectionMap[GetDataSetValue(dt, i, 8).ToString()]; - model.CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 9).ToString()]; - model.CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 10).ToString()]; - model.NotionalPrincipalAmount = GetDataSetValue(dt, i, 11).ToString(); - model.ExcerciseInterestRate = GetDataSetValue(dt, i, 12).ToString(); - model.InvestmentTarget = ConsReport.NAFMIIInvestmentNameMap[GetDataSetValue(dt, i, 13).ToString()]; - model.DeliveryType = ConsReport.NAFMIIDeliveryTypeMap[GetDataSetValue(dt, i, 14).ToString()]; - model.StartDate = GetDataSetValue(dt, i, 15).ToString(); - model.ContractExpirationDate = GetDataSetValue(dt, i, 16).ToString(); + var model = new InterestRateOptionDetailModel + { + TradingDate = GetDataSetValue(dt, i, 1).ToString(), + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 2).ToString(), + FillInTheNameOfTheAgency = GetDataSetValue(dt, i, 3).ToString(), + NameOfCounterparty = GetDataSetValue(dt, i, 4).ToString(), + CounterpartyAllographProduct = GetDataSetValue(dt, i, 5).ToString(), + BusinessType = ConsReport.OptionTraderMap[GetDataSetValue(dt, i, 6).ToString()], + OptionType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 7).ToString()], + OptionPosition = ConsReport.NAFMIIOptionDirectionMap[GetDataSetValue(dt, i, 8).ToString()], + CounterpartyType = ConsReport.NAFMIICounterpartyTypeMap[GetDataSetValue(dt, i, 9).ToString()], + CounterpartyIsProfessionalInstitutionsOrNot = ConsReport.BoolNumberMap[GetDataSetValue(dt, i, 10).ToString()], + NotionalPrincipalAmount = GetDataSetValue(dt, i, 11).ToString(), + ExcerciseInterestRate = GetDataSetValue(dt, i, 12).ToString(), + InvestmentTarget = ConsReport.NAFMIIInvestmentNameMap[GetDataSetValue(dt, i, 13).ToString()], + DeliveryType = ConsReport.NAFMIIDeliveryTypeMap[GetDataSetValue(dt, i, 14).ToString()], + StartDate = GetDataSetValue(dt, i, 15).ToString(), + ContractExpirationDate = GetDataSetValue(dt, i, 16).ToString() + }; result.Add(model); } @@ -398,21 +403,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.PeriodicReportNAFMII != null) { - List listRoot = new List(); - CheckHelper helper = new Common.CheckHelper(); - CheckHelper swapDetailHelper = new Common.CheckHelper(); - CheckHelper optionDetailHelper = new Common.CheckHelper(); - CheckHelper transactionHelper = new Common.CheckHelper(); + var listRoot = new List(); + var helper = new Common.CheckHelper(); + var swapDetailHelper = new Common.CheckHelper(); + var optionDetailHelper = new Common.CheckHelper(); + var transactionHelper = new Common.CheckHelper(); helper.ExecuteCheck(model.PeriodicReportNAFMII, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.PeriodicReportNAFMII.InterestRateSwapDetails != null) { - for (int i = 0; i < model.PeriodicReportNAFMII.InterestRateSwapDetails.Count; i++) + for (var i = 0; i < model.PeriodicReportNAFMII.InterestRateSwapDetails.Count; i++) { var listItem = new List(); var item = model.PeriodicReportNAFMII.InterestRateSwapDetails[i]; @@ -422,15 +427,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("InterestRateSwapDetails", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("InterestRateSwapDetails", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportNAFMII.InterestRateOptionDetails != null) { - for (int i = 0; i < model.PeriodicReportNAFMII.InterestRateOptionDetails.Count; i++) + for (var i = 0; i < model.PeriodicReportNAFMII.InterestRateOptionDetails.Count; i++) { var listItem = new List(); var item = model.PeriodicReportNAFMII.InterestRateOptionDetails[i]; @@ -440,15 +447,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("InterestRateOptionDetails", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("InterestRateOptionDetails", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportNAFMII.ScheduleOfOtherTransactions != null) { - for (int i = 0; i < model.PeriodicReportNAFMII.ScheduleOfOtherTransactions.Count; i++) + for (var i = 0; i < model.PeriodicReportNAFMII.ScheduleOfOtherTransactions.Count; i++) { var listItem = new List(); var item = model.PeriodicReportNAFMII.ScheduleOfOtherTransactions[i]; @@ -458,16 +467,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("ScheduleOfOtherTransactions", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("ScheduleOfOtherTransactions", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("PeriodicReportNAFMII"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("PeriodicReportNAFMII") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -477,7 +490,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(string tag, bool suffixType = false) { - string result = $"{BusiDataType}_{tag}_"; + var result = $"{BusiDataType}_{tag}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -485,10 +498,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportQuarterService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportQuarterService.cs index d2274de7..37b67590 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportQuarterService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportQuarterService.cs @@ -15,19 +15,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override ConsReport.DataFlagsEnum BusiDataType => ConsReport.DataFlagsEnum.A1014; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } @@ -37,7 +34,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime minDate = DateTime.MinValue; DateTime maxDate = DateTime.MinValue; protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_PeriodicReportQuarter; - List noteList = new List(); + + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -52,7 +50,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } SACReportNotes note = null; quarter = GetQuarterRange(req.PeriodicReportQuarterDate.Value, out minDate, out maxDate); - fileType = (quarter == "05" ? "半年报" : "季度报告"); + fileType = quarter == "05" ? "半年报" : "季度报告"; switch (req.PeriodicReportQuarterStatus) { case OptFlagsEnum.A: @@ -80,7 +78,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (req.PeriodicReportQuarterStatus == OptFlagsEnum.U) { var fileIds = tempFilesService.QueryTempFile(minDate, maxDate, fileType).Select(O => O.id.ToString()).ToArray(); - string[] fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + var fileIdArr = note.DataId.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (!fileIds.Except(fileIdArr).Any()) { errMsg = $"{minDate.ToString("yyyy-MM-dd")}~{maxDate.ToString("yyyy-MM-dd")}已上传季度报告附件都已报送,不需要再次报送"; @@ -99,15 +97,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList = new List(); noData = true; - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; + var model = new BodyModel(); var cacheValue = formatInfoTag(_reqInfo.PeriodicReportQuarterDate.Value.Year + quarter); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { return model; } model.PeriodicReportQuarter = new PeriodicReportQuarterModel(); - SACReportNotes note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, cacheValue).FirstOrDefault(); if (note == null) { note = new SACReportNotes() @@ -154,8 +151,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList.Clear(); break; } - var info = new DerivativesQuarterlyReportAnnexModel(); - info.DerivativesQuarterlyReportAnnex = item.fileName; + var info = new DerivativesQuarterlyReportAnnexModel + { + DerivativesQuarterlyReportAnnex = item.fileName + }; if (model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple == null) { model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple = new List(); @@ -165,10 +164,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service note.DataId += item.id + ","; } } - noData = (!(model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple?.Count > 0)); + noData = !(model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple?.Count > 0); if (!noData) { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.ExceId = model.PeriodicReportQuarter.ExceID; note.CreateTime = DateTime.Now; @@ -189,19 +188,19 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.PeriodicReportQuarter != null) { - List listRoot = new List(); - CheckHelper helper = new Common.CheckHelper(); - CheckHelper annexHelper = new Common.CheckHelper(); + var listRoot = new List(); + var helper = new Common.CheckHelper(); + var annexHelper = new Common.CheckHelper(); helper.ExecuteCheck(model.PeriodicReportQuarter, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple != null) { - for (int i = 0; i < model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportQuarter.DerivativesQuarterlyReportAnnexTuple[i]; @@ -211,16 +210,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("DerivativesQuarterlyReportAnnexTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("DerivativesQuarterlyReportAnnexTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("PeriodicReportQuarter"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("PeriodicReportQuarter") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -230,7 +233,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(string tag, bool suffixType = false) { - string result = $"{BusiDataType}_{tag}_"; + var result = $"{BusiDataType}_{tag}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -238,10 +241,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportSACService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportSACService.cs index 16f74afe..29828d0f 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportSACService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportPeriodicReportSACService.cs @@ -1,7 +1,8 @@ -using BaseOUDAL; +using BaseOUDAL; using System.Data; using System.Linq.Expressions; using YLErp.BLL; +using YLErp.DBModels; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.Helpers; @@ -23,19 +24,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1011; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } @@ -44,7 +42,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime maxDate = DateTime.MinValue; protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_PeriodicReportSAC; - readonly List noteList = new List(); + readonly List noteList = new(); public override bool CheckRequestParamer(ReportInfo req, out string errMsg) { @@ -91,9 +89,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList = new List(); noData = true; var model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; var cacheValue = formatInfoTag(_reqInfo.SACReportDate.Value.ToString("yyyy-MM")); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { return model; } @@ -124,23 +121,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service throw new ServiceException("未知操作类型"); } } - //if (((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) && ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System)) - //{ - // model.PeriodicReportSAC = GetPeriodicReportSACFromExcelAndDb(); - //} - //else if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - //{ - // model.PeriodicReportSAC = GetPeriodicReportSACFromDb(); - //} - //else if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) - //{ - // model.PeriodicReportSAC = GetPeriodicReportSACFromExcel(); - //} - model.PeriodicReportSAC = GetPeriodicReportSACFromExcel(); + // To optimize the code we can use the switch statement instead of if-else statements + switch (_reqInfo.DataSource & SAC_ReportDataSourceEnum.Template) + { + case SAC_ReportDataSourceEnum.Template: + model.PeriodicReportSAC = GetPeriodicReportSACFromExcel(); + break; + } model.PeriodicReportSAC.OperationType = _operationType; noData = string.IsNullOrWhiteSpace(model?.PeriodicReportSAC?.MainAgreementAddedThisMonth); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); if (!noData) { if (_operationType != OptFlagsEnum.A) @@ -167,902 +158,6 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return model; } - private PeriodicReportSACModel GetPeriodicReportSACFromDb() - { - var monthStart = QdpCalendarHelper.GetNonHoliday(_reqInfo.SACReportDate.Value.AddDays(-_reqInfo.SACReportDate.Value.Day + 1)); - var lastMonthEnd = QdpCalendarHelper.GetNonHolidayDefore(monthStart.AddDays(-1)); - var monthEnd = QdpCalendarHelper.GetNonHolidayDefore(monthStart.AddMonths(1).AddDays(-monthStart.Day)); - var yearStart = QdpCalendarHelper.GetNonHoliday(new DateTime(_reqInfo.SACReportDate.Value.Year, 01, 01)); - var lastYearEnd = QdpCalendarHelper.GetNonHolidayDefore(yearStart.AddDays(-1)); - var yearEnd = monthEnd; - - var model = new PeriodicReportSACModel(); - using (var baseDb = new ClientDBContext()) - { - using (var db = new YLContext()) - { - model.Year = _reqInfo.SACReportDate.Value.Year.ToString("0000"); - model.Month = _reqInfo.SACReportDate.Value.Month.ToString("0"); - - model.MainAgreementAddedThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate >= monthStart && O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_MasterAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.MainAgreementAccumulatedThisYear = DbContext.sac_report_notes.Where(O => O.ReportDate >= yearStart && O.ReportDate <= yearEnd && O.ReportType == SuperviseReportTypeEnum.SAC_MasterAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.MainAgreementValidedAtEndOfThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_MasterAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A") && O.IsValid).Count().ToString(); - - model.SupplementalAgreementAddedThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate >= monthStart && O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_SupAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.SupplementalAgreementAccumulatedThisYear = DbContext.sac_report_notes.Where(O => O.ReportDate >= yearStart && O.ReportDate <= yearEnd && O.ReportType == SuperviseReportTypeEnum.SAC_SupAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.SupplementalAgreementValidedAtTheEndOfThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_SupAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A") && O.IsValid).Count().ToString(); - - model.PerformanceGuaranteeAgreementAddedThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate >= monthStart && O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.PerformanceGuaranteeAgreementAccumulatedThisYear = DbContext.sac_report_notes.Where(O => O.ReportDate >= yearStart && O.ReportDate <= yearEnd && O.ReportType == SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A")).Count().ToString(); - model.PerformanceGuaranteeAgreementValidedAtEndOfThisMonth = DbContext.sac_report_notes.Where(O => O.ReportDate <= monthEnd && O.ReportType == SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt && O.ReportResponse && O.InfoTag.EndsWith("_A") && O.IsValid).Count().ToString(); - - var contractCount = from tc in db.trade_cash join tr in db.trade_contract_r on tc.id equals tr.TradeCashId where tr.Type == "交易确认书" && !tc.IsDeleted && tr.IsValid select tc.ValueDate; - model.TransactionConfirmationAddedThisMonth = contractCount.Where(O => O >= monthStart && O <= monthEnd).Count().ToString(); - model.TransactionConfirmationBookAccumulatedThisYear = contractCount.Where(O => O >= yearStart && O <= yearEnd).Count().ToString(); - model.TransactionConfirmationValidedAtEndOfThisMonth = contractCount.Where(O => O <= monthEnd).Count().ToString(); - - var endAction = new List() { "系统操作-平仓费", "系统操作-行权费" }; - var selfClientInfos = baseDb.client.Where(O => O.ProcessOptDate <= monthEnd && O.ProcessStatus == "已开户" && O.ClientType == "产品").Select(O => O.id).ToList(); - var dotSelfClientInfos = baseDb.client.Where(O => O.ProcessOptDate <= monthEnd && O.ProcessStatus == "已开户" && O.ClientType != "产品").Select(O => O.id).ToList(); - var latestTradeInfos = - (from et in db.eod_trade - where et.ValueDate == monthEnd && et.TradeStatus == "确认成交" - join ep in db.eod_trade_position on new { et.TradeId, et.ValueDate } equals new { ep.TradeId, ep.ValueDate } - join um in db.underlying_manager on et.UnderlyingCode equals um.UnderlyingCode - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书" && O.IsValid) on et.TradeId equals tr.TradeId into tempTr - from tr in tempTr.DefaultIfEmpty() - select new - { - et = new xodTradeBase() { TradeJson = et.TradeJson }, - um, - tr, - ep.Pv, - }) - .ToArray().Select(O => new - { - O.et.trade.StockEqvNotional, - O.et.trade.TradeType, - O.um.UnderlyingInstrumentType, - O.et.trade.ClientId, - O.et.trade.StockEqvNotionalReal, - O.et.trade.StartDate, - O.et.trade.ExerciseDate, - O.et.trade.TradePrice, - O.et.trade.PremiumRate, - O.et.trade.OriginalStockEqvNotional, - ContractCode = O.tr?.ContractCode, - O.um.CommodityCode, - O.et.trade.ParticipationRate, - O.et.trade.AnnualizeFactor, - O.um.UnderlyingName, - O.um.UnderlyingCode, - O.um.MarketCode, - O.um.MarketName, - O.et.trade.PositionMarginRate, - O.et.trade.trade_swap, - O.Pv, - }).ToArray(); - var lastMonthTradeInfos = (from et in db.eod_trade join um in db.underlying_manager on et.UnderlyingCode equals um.UnderlyingCode join ts in db.trade_span.Where(O => O.ValueDate == lastMonthEnd) on et.TradeId equals ts.TradeId where et.ValueDate == lastMonthEnd && et.TradeStatus == "确认成交" select new { et = new xodTradeBase() { TradeJson = et.TradeJson }, ts.WorstCastClientPayable, um }).ToArray().Select(O => new { O.et.trade.id, O.et.trade.StockEqvNotional, O.et.TradeType, O.um.UnderlyingInstrumentType, O.WorstCastClientPayable }).ToArray(); - var latestMonthNewTradeInfos = (from t in db.trade join tc in db.trade_cash.Where(O => O.ValueDate >= monthStart && O.ValueDate <= monthEnd && O.Action == "系统操作-期权费" && O.ValidState != "InValid" && !O.IsDeleted) on t.id equals tc.TradeId join um in db.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode join tr in db.trade_contract_r on tc.id equals tr.TradeCashId into tempTr from tr in tempTr.DefaultIfEmpty() where tr.IsValid select new { t.id, StockEqvNotional = t.OriginalStockEqvNotional, t.TradeType, um.UnderlyingInstrumentType, t.ClientId, t.StockEqvNotionalReal, t.StartDate, t.ExerciseDate, t.TradePrice, t.PremiumRate, t.OriginalStockEqvNotional, tr.ContractCode, um.CommodityCode, um.UnderlyingName, um.UnderlyingCode, um.MarketName }).ToArray(); - var latestMonthEndTradeInfos = (from t in db.trade join tc in db.trade_cash.Where(O => O.ValueDate >= monthStart && O.ValueDate <= monthEnd && endAction.Contains(O.Action) && O.ValidState != "InValid" && !O.IsDeleted) on t.id equals tc.TradeId join um in db.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode select new { t.id, StockEqvNotional = (tc.UnwindNotional / t.OriginalNotional * t.OriginalStockEqvNotional), t.TradeType, um.UnderlyingInstrumentType }).ToArray(); - var latestMonthTradeInfos = (from et in db.eod_trade join um in db.underlying_manager on et.UnderlyingCode equals um.UnderlyingCode join ts in db.trade_span.Where(O => O.ValueDate == monthEnd) on et.TradeId equals ts.TradeId where et.ValueDate == monthEnd && et.TradeStatus == "确认成交" select new { et = new xodTradeBase() { TradeJson = et.TradeJson }, ts.WorstCastClientPayable, um }).ToArray().Select(O => new { O.et.trade.id, O.et.trade.StockEqvNotional, O.et.TradeType, O.um.UnderlyingInstrumentType, O.WorstCastClientPayable }).ToArray(); - var latestYearNewTradeInfos = (from t in db.trade join tc in db.trade_cash.Where(O => O.ValueDate >= yearStart && O.ValueDate <= yearEnd && O.Action == "系统操作-期权费" && O.ValidState != "InValid" && !O.IsDeleted) on t.id equals tc.TradeId join um in db.underlying_manager on t.UnderlyingCode equals um.UnderlyingCode select new { t.id, StockEqvNotional = t.OriginalStockEqvNotional, t.TradeType, um.UnderlyingInstrumentType }).ToArray(); - var totleStockEqvNotional = (latestTradeInfos.Sum(O => (double?)O.StockEqvNotional) ?? 0); - var latestNetAssets = _reqInfo.LatestNetAssets; - model.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionBusinessCorrespondence = totleStockEqvNotional.ToString(); - model.NetCapitalAtEndOfTheMonth = latestNetAssets.ToString(); - model.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionsBusinessAccountedForTheProportionOfTheCorrespondingNetCapital = latestNetAssets == 0 ? "0" : (totleStockEqvNotional / latestNetAssets * 100).ToString("0.00"); - model.OTCOptionHasSignedByLegalPerson = dotSelfClientInfos.Count.ToString(); - model.OTCOptionsHaveContractedProducts = selfClientInfos.Count.ToString(); - model.OTCOptionsForTheMonthOfTheNewAddLegalPerson = baseDb.client.Where(O => O.ProcessStatus == "已开户" && O.ProcessOptDate >= monthStart && O.ProcessOptDate <= monthEnd && O.ClientType != "产品").Count().ToString(); - model.OTCOptionsForTheMonthOfTheNewAddProduct = baseDb.client.Where(O => O.ProcessStatus == "已开户" && O.ProcessOptDate >= monthStart && O.ProcessOptDate <= monthEnd && O.ClientType == "产品").Count().ToString(); - model.OTCOptionsLegalPersonInDurationForThisMouth = dotSelfClientInfos.Count.ToString(); - model.OTCOptionsProductsInDurationForThisMouth = selfClientInfos.Count.ToString(); - model.IncomeSwapHasSignedLegalPersonNumber = dotSelfClientInfos.Count.ToString(); - model.IncomeSwapHasSignedProductNumber = selfClientInfos.Count.ToString(); - model.IncomeSwapForTheMonthOfTheNewAddLegalPerson = model.OTCOptionsForTheMonthOfTheNewAddLegalPerson; - model.IncomeSwapForTheMonthOfTheNewAddProduct = model.OTCOptionsForTheMonthOfTheNewAddProduct; - model.IncomeSwapLegalPersonInDurationForThisMouth = dotSelfClientInfos.Count.ToString(); - model.IncomeSwapProductsInDurationForThisMouth = selfClientInfos.Count.ToString(); - - var tempList = new List { "StockIF", "Stock", "CommodityFutures" }; - model.OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale = (lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsWithinIndividualStocksLateLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsCommoditiesLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsOtherSubjectLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticStockIndexLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticIndividualStocksLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeCommoditiesLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeOtherSubjectLastMonthDurationScale = (lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.TotalOfLastMonthDurationScale = (lastMonthTradeInfos.Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - - model.OTCOptionsWithinTheIndexThisMonthOfTheNewScale = (latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsToAddScaleDomesticStocksInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsCommoditiesTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsOtherSubjectTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticStockIndexTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticIndividualStocksTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeCommoditiesTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeOtherSubjectTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.TotalOfTheNewSizeOfTheIncreaseInThisMonth = (latestMonthNewTradeInfos.Sum(O => O.StockEqvNotional) ?? 0).ToString(); - - model.OTCOptionsTerminateScaleDomesticStockIndexThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsTerminateScaleDomesticStocksInThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsCommoditiesTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsOtherSubjectTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticStockIndexTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticIndividualStocksTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeCommoditiesTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeOtherSubjectTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.TotalOfTerminationOfTheScaleOfThisMonth = (latestMonthEndTradeInfos.Sum(O => O.StockEqvNotional) ?? 0).ToString(); - - model.OTCStockIndexOptionsWithinThisMonthOfTheExistenceOfScale = (latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsWithinIndividualStocksInThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsCommoditiesInThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsOtherSubjectThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticStockIndexThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeDomesticIndividualStocksThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeCommoditiesThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.RevenueExchangeOtherSubjectThisMonthDurationScale = (latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - model.TotalOfThisMonthDurationScale = (latestMonthTradeInfos.Sum(O => (double?)O.StockEqvNotional) ?? 0).ToString(); - - model.OTCOptionsStockIndexThisYearCumulativeScaleOfNewTerritory = (latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsStockThisYearCumulativeScaleOfNewTerritory = (latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsCommoditiesThisYearCumulativeScaleOfNewTerritory = (latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OTCOptionsOtherSubjectThisYearCumulativeScaleOfNewTerritory = (latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.IncomeSwapDomesticStockIndexHasAddedNewScaleInThisYear = (latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.IncomeSwapDomesticStockHasAddedNewScaleInThisYear = (latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.IncomeSwapCommoditiesIndexHasAddedNewScaleInThisYear = (latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.IncomeSwapOtherSubjectIndexHasAddedNewScaleInThisYear = (latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.TotalNewScaleInThisYear = (latestYearNewTradeInfos.Sum(O => O.StockEqvNotional) ?? 0).ToString(); - - model.OTCOptionsStockIndexAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsStockAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsCommoditiesAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsOtherSubjectAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.TotalNumberOfContractsAtTheEndOfLastMonth = lastMonthTradeInfos.GroupBy(O => O.id).Count().ToString(); - - model.OTCOptionsStockIndexThisMonthNewDomesticContractNumber = latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsStockThisMonthNewDomesticContractNumber = latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsCommoditiesThisMonthNewDomesticContractNumber = latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsOtherSubjectThisMonthNewDomesticContractNumber = latestMonthNewTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockIndexNewContractInThisMonth = latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockNewContractInThisMonth = latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapCommoditiesNewContractInThisMonth = latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapOtherSubjectNewContractInThisMonth = latestMonthNewTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.TotalNumberOfNewContractsInThisMonth = latestMonthNewTradeInfos.GroupBy(O => O.id).Count().ToString(); - - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockIndexNumber = latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockNumber = latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheCommoditiesNumber = latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheOtherSubjectNumber = latestMonthEndTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockIndexTerminatesTheNumberOfContractsThisMonth = latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockTerminatesTheNumberOfContractsThisMonth = latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapCommoditiesTerminatesTheNumberOfContractsThisMonth = latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapOtherSubjectTerminatesTheNumberOfContractsThisMonth = latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.TotalNumberOfContractsTerminatedThisMonth = latestMonthEndTradeInfos.GroupBy(O => O.id).Count().ToString(); - - model.OTCDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.OTCDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.OTCCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.OTCOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.TotalNumberOfContractsAtTheEndOfThisMonth = latestMonthTradeInfos.GroupBy(O => O.id).Count().ToString(); - - model.OTCOptionsStockIndexCumulativeDomesticNewContractNumberInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsStockCumulativeDomesticNewContractNumberInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsCommoditiesCumulativeDomesticNewContractNumberInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.OTCOptionsOtherSubjectCumulativeDomesticNewContractNumberInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType != "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockIndexCumulativeNumberOfNewContractsInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "StockIF").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapDomesticStockCumulativeNumberOfNewContractsInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "Stock").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapCommoditiesCumulativeNumberOfNewContractsInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && O.UnderlyingInstrumentType == "CommodityFutures").GroupBy(O => O.id).Count().ToString(); - model.IncomeSwapOtherSubjectCumulativeNumberOfNewContractsInThisYear = latestYearNewTradeInfos.Where(O => O.TradeType == "收益互换" && !tempList.Contains(O.UnderlyingInstrumentType)).GroupBy(O => O.id).Count().ToString(); - model.TotalNumberOfNewContractsInThisYear = latestYearNewTradeInfos.GroupBy(O => O.id).Count().ToString(); - - var totalNominalPrincipalAmountOfSwapThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换").Sum(O => (double?)O.StockEqvNotional) ?? 0; - var totalNominalPrincipalAmountOfSwapLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换").Sum(O => (double?)O.StockEqvNotional) ?? 0; - model.TotalNominalPrincipalAmountOfSwapThisMonth = totalNominalPrincipalAmountOfSwapThisMonth.ToString(); - model.TotalNominalPrincipalAmountOfSwapLastMonth = totalNominalPrincipalAmountOfSwapLastMonth.ToString(); - - var theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "收益互换").Sum(O => O.WorstCastClientPayable) ?? 0; - var theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "收益互换").Sum(O => O.WorstCastClientPayable) ?? 0; - model.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth = theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth.ToString(); - model.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth = theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth.ToString(); - - model.SwapCashCollateralValueThisMonth = theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth.ToString(); - model.SwapCashCollateralValueLastMonth = theValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth.ToString(); - - model.SwapSecuritiesCollateralValueThisMonth = 0.ToString(); - model.SwapSecuritiesCollateralValueLastMonthThisMonth = 0.ToString(); - - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull = 0.ToString(); - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull = 0.ToString(); - - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet = 0.ToString(); - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet = 0.ToString(); - - model.SwapNumberOfDefaultCustomersAtThisMonthThisMonth = 0.ToString(); - model.SwapNumberOfDefaultCustomersAtThisMonthLastMonth = 0.ToString(); - - model.SwapDefaultTransactionNumberAtThisMonthThisMonth = 0.ToString(); - model.SwapDefaultTransactionNumberAtThisMonthLastMonth = 0.ToString(); - - model.TotalSwapDefaultCustomerNumberInThisYearThisMonth = 0.ToString(); - model.TotalSwapDefaultCustomerNumberInThisYearLastMonth = 0.ToString(); - - model.SwapNumberOfDefaultCustomersInThisYearThisMonth = 0.ToString(); - model.SwapNumberOfDefaultCustomersInThisYearLastMonth = 0.ToString(); - - var totalNominalPrincipalAmountOfOptionThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "远期").Sum(O => (double?)O.StockEqvNotional) ?? 0; - var totalNominalPrincipalAmountOfOptionLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "远期").Sum(O => (double?)O.StockEqvNotional) ?? 0; - model.TotalNominalPrincipalAmountOfOptionThisMonth = totalNominalPrincipalAmountOfOptionThisMonth.ToString(); - model.TotalNominalPrincipalAmountOfOptionLastMonth = totalNominalPrincipalAmountOfOptionLastMonth.ToString(); - - var theValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth = latestMonthTradeInfos.Where(O => O.TradeType == "远期").Sum(O => O.WorstCastClientPayable) ?? 0; - var theValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth = lastMonthTradeInfos.Where(O => O.TradeType == "远期").Sum(O => O.WorstCastClientPayable) ?? 0; - model.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth = theValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth.ToString(); - model.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth = theValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth.ToString(); - - model.OptionCashCollateralValueThisMonth = theValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth.ToString(); - model.OptionCashCollateralValueLastMonth = theValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth.ToString(); - - model.OptionSecuritiesCollateralValueThisMonth = 0.ToString(); - model.OptionSecuritiesCollateralValueLastMonth = 0.ToString(); - - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthFull = 0.ToString(); - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthFull = 0.ToString(); - - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthNet = 0.ToString(); - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthNet = 0.ToString(); - - model.OptionNumberOfDefaultCustomersAtThisMonthThisMonth = 0.ToString(); - model.OptionNumberOfDefaultCustomersAtThisMonthLastMonth = 0.ToString(); - - model.OptionTransactionNumberAtThisMonthThisMonth = 0.ToString(); - model.OptionTransactionNumberAtThisMonthLastMonth = 0.ToString(); - - model.TotalOptionDefaultCustomerNumberInThisYearThisMonth = 0.ToString(); - model.TotalOptionDefaultCustomerNumberInThisYearLastMonth = 0.ToString(); - - model.OptionNumberOfDefaultCustomersInThisYearThisMonth = 0.ToString(); - model.OptionNumberOfDefaultCustomersInThisYearLastMonth = 0.ToString(); - - model.StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth = (latestMonthTradeInfos.Sum(O => O.WorstCastClientPayable) ?? 0).ToString(); - model.StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth = (lastMonthTradeInfos.Sum(O => O.WorstCastClientPayable) ?? 0).ToString(); - - model.CashBalanceAtEndOfThisMonth = _reqInfo.LatestMonthCash.ToString("0.00"); - model.CashBalanceAtEndOfLastMonth = _reqInfo.LastMonthCash.ToString("0.00"); - - var positionTradeTypes = new List() { "股票", "债券", "银行理财", "信托", "保险" }; - var latestMonthPosition = db.eod_trade_position.Where(O => O.ValueDate == monthEnd && O.ClientId == 0).Select(O => new { O.TradeType, O.Pv }); - var lastMonthPosition = db.eod_trade_position.Where(O => O.ValueDate == lastMonthEnd && O.ClientId == 0).Select(O => new { O.TradeType, O.Pv }); - model.HoldStockMarketValueAtEndOfThisMonth = (latestMonthPosition.Where(O => O.TradeType == "股票").Sum(O => (double?)O.Pv) ?? 0).ToString(); - model.HoldStockMarketValueAtEndOfLastMonth = (lastMonthPosition.Where(O => O.TradeType == "股票").Sum(O => (double?)O.Pv) ?? 0).ToString(); - - model.HoldMarketValueOfBondsAtTheEndOfThisMonth = 0.ToString();// latestMonthPosition.Where(O => O.TradeType == "债券").Sum(O => O.Pv).ToString(); - model.HoldMarketValueOfBondsAtTheEndOfLastMonth = 0.ToString();// lastMonthPosition.Where(O => O.TradeType == "债券").Sum(O => O.Pv).ToString(); - - model.OwnedAssetManagementProductsAtTheEndOfThisMonth = 0.ToString();// latestMonthPosition.Where(O => O.TradeType == "债券").Sum(O => O.Pv).ToString(); - model.OwnedAssetManagementProductsAtTheEndOfLastMonth = 0.ToString();// lastMonthPosition.Where(O => O.TradeType == "债券").Sum(O => O.Pv).ToString(); - - model.OwnedBankFinanceAtTheEndOfThisMonth = 0.ToString();// latestMonthPosition.Where(O => O.TradeType == "银行理财").Sum(O => O.Pv).ToString(); - model.OwnedBankFinanceAtTheEndOfLastMonth = 0.ToString();// lastMonthPosition.Where(O => O.TradeType == "银行理财").Sum(O => O.Pv).ToString(); - - model.HoldTrustProductAtTheEndOfThisMonth = 0.ToString();// latestMonthPosition.Where(O => O.TradeType == "信托").Sum(O => O.Pv).ToString(); - model.HoldTrustProductAtTheEndOfLastMonth = 0.ToString();// lastMonthPosition.Where(O => O.TradeType == "信托").Sum(O => O.Pv).ToString(); - - model.InsuranceProductsAreHeldAtTheEndOfThisMonth = 0.ToString();// latestMonthPosition.Where(O => O.TradeType == "保险").Sum(O => O.Pv).ToString(); - model.InsuranceProductsAreHeldAtTheEndOfLastMonth = 0.ToString();// lastMonthPosition.Where(O => O.TradeType == "保险").Sum(O => O.Pv).ToString(); - - model.HoldOtherProductsAtTheEndOfThisMonth = (latestMonthPosition.Where(O => !positionTradeTypes.Contains(O.TradeType)).Sum(O => (double?)O.Pv) ?? 0).ToString(); - model.HoldOtherProductsAtTheEndOfLastMonth = (lastMonthPosition.Where(O => !positionTradeTypes.Contains(O.TradeType)).Sum(O => (double?)O.Pv) ?? 0).ToString(); - - var monthEndTrades = (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - where tc.ValueDate >= monthStart && tc.ValueDate <= monthEnd && tc.Action != "系统操作-期权费" && !tc.IsDeleted && tc.ValidState != "InValid" - select new { t, tc.Amount }).ToArray(); - model.SettledSwapItemsAtThisMonth = latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换").GroupBy(O => O.id).Count().ToString(); - model.SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth = (latestMonthEndTradeInfos.Where(O => O.TradeType == "收益互换").Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.SwapIncomeCashFlow = (monthEndTrades.Where(O => O.t.TradeType == "收益互换").Sum(O => (double?)(O.Amount > 0 ? O.Amount : 0)) ?? 0).ToString(); - model.SwapExpensesCashFlow = (monthEndTrades.Where(O => O.t.TradeType == "收益互换").Sum(O => (double?)(O.Amount < 0 ? O.Amount : 0)) ?? 0).ToString(); - model.CashFlowCorrespondingToNetIncomeOnSwapMargin = (monthEndTrades.Where(O => O.t.TradeType == "收益互换").Sum(O => (double?)O.Amount) ?? 0).ToString(); - model.SwapHedgeCost = 0.ToString(); - - var tradeTypes = new List() { "收益互换", "远期" }; - model.SettledOptionItemsAtThisMonth = latestMonthEndTradeInfos.Where(O => !tradeTypes.Contains(O.TradeType)).GroupBy(O => O.id).Count().ToString(); - model.SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth = (latestMonthEndTradeInfos.Where(O => !tradeTypes.Contains(O.TradeType)).Sum(O => O.StockEqvNotional) ?? 0).ToString(); - model.OptionPremiumIncome = (monthEndTrades.Where(O => !tradeTypes.Contains(O.t.TradeType)).Sum(O => O.t.TradePrice * (O.t.BuySell == "买入" ? -1 : 1)) ?? 0).ToString(); - model.OptionHedgeCost = 0.ToString(); - - - var balanceOfSwapRealizedGainsAndLossesAtThisMonth = GetRealizedPnl(PredicateBuilder.Create(t => t.TradeType == "收益互换"), monthStart, monthEnd); - var balanceOfOptionRealizedGainsAndLossesAtThisMonth = GetRealizedPnl(PredicateBuilder.Create(t => !tradeTypes.Contains(t.TradeType)), monthStart, monthEnd); - model.BalanceOfSwapRealizedGainsAndLossesAtThisMonth = balanceOfSwapRealizedGainsAndLossesAtThisMonth.ToString(); - model.BalanceOfOptionRealizedGainsAndLossesAtThisMonth = balanceOfOptionRealizedGainsAndLossesAtThisMonth.ToString(); - - var balanceOfSwapRealizedGainsAndLossesAtThisYear = GetRealizedPnl(PredicateBuilder.Create(t => t.TradeType == "收益互换"), yearStart, yearEnd); - var balanceOfOptionRealizedGainsAndLossesAtThisYear = GetRealizedPnl(PredicateBuilder.Create(t => !tradeTypes.Contains(t.TradeType)), yearStart, yearEnd); - model.BalanceOfSwapRealizedGainsAndLossesAtThisYear = balanceOfSwapRealizedGainsAndLossesAtThisYear.ToString(); - model.BalanceOfOptionRealizedGainsAndLossesAtThisYear = balanceOfOptionRealizedGainsAndLossesAtThisYear.ToString(); - - var balanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth = GetPositionPnl(PredicateBuilder.Create(t => t.TradeType == "收益互换"), lastMonthEnd, monthEnd); - var balanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth = GetPositionPnl(PredicateBuilder.Create(t => !tradeTypes.Contains(t.TradeType)), lastMonthEnd, monthEnd); - model.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth = balanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth.ToString(); - model.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth = balanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth.ToString(); - - var balanceOfSwapChangedGainsAndLossesInFairValueAtThisYear = GetPositionPnl(PredicateBuilder.Create(t => t.TradeType == "收益互换"), lastYearEnd, yearEnd); - var balanceOfOptionChangedGainsAndLossesInFairValueAtThisYear = GetPositionPnl(PredicateBuilder.Create(t => !tradeTypes.Contains(t.TradeType)), lastYearEnd, yearEnd); - model.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear = balanceOfSwapChangedGainsAndLossesInFairValueAtThisYear.ToString(); - model.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear = balanceOfOptionChangedGainsAndLossesInFairValueAtThisYear.ToString(); - - model.BalanceOfSwapTotalGainsAndLossesAtThisMonth = (balanceOfSwapRealizedGainsAndLossesAtThisMonth + balanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth).ToString(); - model.BalanceOfOptionTotalGainsAndLossesAtThisMonth = (balanceOfOptionRealizedGainsAndLossesAtThisMonth + balanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth).ToString(); - - model.BalanceOfSwapTotalGainsAndLossesAtThisYear = (balanceOfSwapRealizedGainsAndLossesAtThisYear + balanceOfSwapChangedGainsAndLossesInFairValueAtThisYear).ToString(); - model.BalanceOfOptionTotalGainsAndLossesAtThisYear = (balanceOfOptionRealizedGainsAndLossesAtThisYear + balanceOfOptionChangedGainsAndLossesInFairValueAtThisYear).ToString(); - - model.MarginOfSubsistSwap = "0"; - model.HedgedMarketValueOfSwap = "0"; - model.LeverageRatiOfSwap = "0"; - model.MarginOfSubsistStockIndexSwap = "0"; - model.HedgedMarketValueOfStockIndexSwap = "0"; - model.LeverageRatioOfStockIndexSwap = "0"; - model.MarginOfSubsistStockSwap = "0"; - model.HedgedMarketValueOfStockSwap = "0"; - model.LeverageRatioOfStockSwap = "0"; - model.MarginandPremiumOfSubsistOption = "0"; - model.HedgedMarketValueOfOption = "0"; - model.LeverageRatioOfOption = "0"; - model.MarginandPremiumOfSubsistStockIndexOption = "0"; - model.HedgedMarketValueOfStockIndexOption = "0"; - model.LeverageRatioOfStockIndexOption = "0"; - model.MarginandPremiumOfSubsistStockOption = "0"; - model.HedgedMarketValueOfStockOption = "0"; - model.LeverageRatioOfStockOption = "0"; - - model.IncreaseBusinessDetailsThisMonthTuple = new List(); - var config = db.valuedate.FirstOrDefault(x => x.State == valuedate.当前使用); - foreach (var item in latestMonthNewTradeInfos) - { - var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); - - var newTrade = new IncreaseBusinessDetailsThisMonthModel(); - newTrade.NameOfSecuritiesCompany = config.SuperviseMainName; - newTrade.NameOfCounterparty = client.Name; - if (client.ClientType == "产品") - { - newTrade.CounterpartyProductName = client.Name; - } - newTrade.TransactionConfirmationNumber = base.GetBizIdFromInfoTag(item.ContractCode); - switch (item.TradeType) - { - case "收益互换": - newTrade.BusinessType = BusinessTypeMap["互换"]; - newTrade.ReturnSwapObjectSecondClass = GetSACUndrlygAssetDtldTypeMap(SwapUndrlygAssetDtldTypeMap, item.UnderlyingInstrumentType, item.CommodityCode); - break; - case "远期": - newTrade.BusinessType = BusinessTypeMap["远期"]; - break; - default: - newTrade.BusinessType = BusinessTypeMap["期权"]; - newTrade.OptionObjectSecondClass = GetSACUndrlygAssetDtldTypeMap(UndrlygAssetDtldTypeMap, item.UnderlyingInstrumentType, item.CommodityCode); - newTrade.NonAnnualOptionFee = ((item.PremiumRate ?? (item.TradePrice / item.OriginalStockEqvNotional) ?? 0) * 100).ToString("0.##"); - switch (item.TradeType) - { - case "香草期权": - newTrade.OptionType = OptionStructureTypeMap["香草"]; - break; - case "二元期权": - newTrade.OptionType = OptionStructureTypeMap["二元"]; - break; - case "价差期权": - newTrade.OptionType = OptionStructureTypeMap["价差"]; - break; - case "障碍期权": - newTrade.OptionType = OptionStructureTypeMap["障碍"]; - break; - case "双鲨期权": - newTrade.OptionType = OptionStructureTypeMap["双鲨"]; - break; - default: - newTrade.OptionType = OptionStructureTypeMap["其他"]; - break; - } - break; - } - newTrade.NotionalPrincipalAmountLNotionalPrincipalAmount = ((item.StockEqvNotional ?? 0) / 1e9).ToString("0.0000"); - //newTrade.SNotionalPrincipalAmount = ((item.StockEqvNotional ?? 0) / 1e9).ToString("0.0000");//当前版本中不存在多空组合的交易 - newTrade.StartDate = item.StartDate?.ToString("yyyy-MM-dd"); - newTrade.DueDate = item.ExerciseDate?.ToString("yyyy-MM-dd"); - newTrade.UndrlygAssetName = item.UnderlyingName; - newTrade.UndrlygAssetCode = item.UnderlyingCode; - newTrade.UndrlygAssetTradgPlc = string.IsNullOrWhiteSpace(item.MarketName) ? "其他" : item.MarketName; - switch (ConsGlobal.InstrumentType.GetDesc(item.UnderlyingInstrumentType)) - { - case "股票": - newTrade.InvestmentTargetType = UndrlygAssetTypeMap["权益类"]; - break; - case "股指期货": - case "商品期货": - case "商品现货": - newTrade.InvestmentTargetType = UndrlygAssetTypeMap["大宗商品"]; - break; - default: - newTrade.InvestmentTargetType = UndrlygAssetTypeMap["其他"]; - break; - } - model.IncreaseBusinessDetailsThisMonthTuple.Add(newTrade); - } - model.InventoryBusinessDetailsAtTheEndOfThisMonthTuple = new List(); - foreach (var item in latestTradeInfos) - { - var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); - - var newTrade = new InventoryBusinessDetailsAtTheEndOfThisMonthModel(); - newTrade.NameOfSecuritiesCompany = config.SuperviseMainName; - newTrade.NameOfCounterparty = client.Name; - if (client.ClientType == "产品") - { - newTrade.NameOfCounterpartyProduct = client.Name; - } - newTrade.TransactionConfirmationNumber = item.ContractCode; - switch (item.TradeType) - { - case "收益互换": - newTrade.BusinessType = BusinessTypeMap["互换"]; - newTrade.ExchangeSumInvestmentTargetType = GetSACUndrlygAssetDtldTypeMap(SwapUndrlygAssetDtldTypeMap, item.UnderlyingInstrumentType, item.CommodityCode); - break; - case "远期": - newTrade.BusinessType = BusinessTypeMap["远期"]; - break; - default: - newTrade.BusinessType = BusinessTypeMap["期权"]; - newTrade.OptionSumInvestmentTargetType = GetSACUndrlygAssetDtldTypeMap(UndrlygAssetDtldTypeMap, item.UnderlyingInstrumentType, item.CommodityCode); - newTrade.OptionFee = Math.Abs((item.PremiumRate ?? (item.TradePrice / item.OriginalStockEqvNotional) ?? 0) * 100).ToString("0.##"); - switch (item.TradeType) - { - case "香草期权": - newTrade.OptionType = OptionStructureTypeMap["香草"]; - break; - case "二元期权": - newTrade.OptionType = OptionStructureTypeMap["二元"]; - break; - case "价差期权": - newTrade.OptionType = OptionStructureTypeMap["价差"]; - break; - case "障碍期权": - newTrade.OptionType = OptionStructureTypeMap["障碍"]; - break; - case "双鲨期权": - newTrade.OptionType = OptionStructureTypeMap["双鲨"]; - break; - default: - newTrade.OptionType = OptionStructureTypeMap["其他"]; - break; - } - break; - } - newTrade.NotionalPrincipalAmountLNotionalPrincipalAmount = (item.StockEqvNotional / 1e9).ToString("0.0000"); - //newTrade.SNotionalPrincipalAmount = (item.StockEqvNotional / 1e9).ToString("0.0000");//当前版本中不存在多空组合的交易 - newTrade.StartDay = item.StartDate?.ToString("yyyy-MM-dd"); - newTrade.DueDate = item.ExerciseDate?.ToString("yyyy-MM-dd"); - newTrade.UndrlygAssetName = item.UnderlyingName; - newTrade.UndrlygAssetCode = item.UnderlyingCode; - newTrade.MaitainMarginRation = (item.PositionMarginRate * 100).ToString("0.00"); - var longShort = item.trade_swap?.GetLongShort ?? item.trade_swap?.PayLongShort; - if (longShort == "空头") - { - newTrade.ShortPositionContractValue = (item.Pv).ToString("0.00"); - } - else - { - newTrade.LongPositionContractValue = (item.Pv).ToString("0.00"); - } - newTrade.UndrlygAssetTradgPlc = string.IsNullOrWhiteSpace(item.MarketName) ? "其他" : item.MarketName; - switch (ConsGlobal.InstrumentType.GetDesc(item.UnderlyingInstrumentType)) - { - case "股票": - newTrade.SumInvestmentTargetType = UndrlygAssetTypeMap["权益类"]; - break; - case "股指期货": - case "商品期货": - case "商品现货": - newTrade.SumInvestmentTargetType = UndrlygAssetTypeMap["大宗商品"]; - break; - default: - newTrade.SumInvestmentTargetType = UndrlygAssetTypeMap["其他"]; - break; - } - model.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.Add(newTrade); - } - model.TargetCaseAndHedgeTuple = new List(); - var eodtradeposition = - (from ep in db.eod_trade_position - join um in db.underlying_manager on ep.UnderlyingCode equals um.UnderlyingCode - where ep.ValueDate == _reqInfo.SACReportDate.Value && ep.ClientId == 0 - select new { ep, um }) - .ToArray().GroupBy(O => O.ep.TradeType == "股票" ? O.ep.UnderlyingCode : O.um.CommodityCode) - .Select(O => new - { - O.Key, - Amount = O.Sum(B => B.ep.Amount * (B.ep.PositionType == "long" ? 1 : -1)), - Cost = O.Sum(B => B.ep.Cost * (B.ep.PositionType == "long" ? 1 : -1)), - O.FirstOrDefault()?.ep.TradeType, - O.FirstOrDefault()?.um.UnderlyingInstrumentType, - O.FirstOrDefault()?.um.CommodityCode, - O.FirstOrDefault()?.um.UnderlyingCode, - O.FirstOrDefault()?.um.MarketName, - }).ToArray(); - foreach (var item in eodtradeposition) - { - var info = new TargetCaseAndHedgeModel(); - info.NameOfSecuritiesCompany = config.SuperviseMainName; - switch (ConsGlobal.InstrumentType.GetDesc(item.UnderlyingInstrumentType)) - { - case "股票": - info.SumInvestmentTargetType = HedgeSACUndrlygAssetDtldTypeMap["权益类"]; - break; - case "股指期货": - case "商品期货": - case "商品现货": - info.SumInvestmentTargetType = HedgeSACUndrlygAssetDtldTypeMap["大宗商品"]; - break; - default: - info.SumInvestmentTargetType = HedgeSACUndrlygAssetDtldTypeMap["其他"]; - break; - } - switch (item.TradeType) - { - case "收益互换": - info.BusinessType = BusinessTypeMap["互换"]; - break; - default: - info.BusinessType = BusinessTypeMap["期权"]; - break; - } - info.SumInvestmentTargetName = item.Key; - info.UndrlygAssetCode = item.UnderlyingCode; - info.UndrlygAssetTradgPlc = item.MarketName; - info.BuyingImpulseVolume = "0"; - info.SellingImpulseVolume = "0"; - info.ImpulseVolume = "0"; - info.PositionAtTheEndOfThisMonth = item.Cost.ToString(); - info.TheNumberOfPositionsHeldAtTheEndOfThisMonth = item.Amount.ToString(); - info.AveragePriceAtTheEndOfTheMonth = (item.Cost / item.Amount).ToString(); - model.TargetCaseAndHedgeTuple.Add(info); - } - } - } - return model; - } - - private PeriodicReportSACModel GetPeriodicReportSACFromExcelAndDb() - { - var dbInfo = GetPeriodicReportSACFromDb(); - var excelInfo = GetPeriodicReportSACFromExcel(); - var model = new PeriodicReportSACModel(); - model.Year = _reqInfo.SACReportDate.Value.Year.ToString("0000"); - model.Month = _reqInfo.SACReportDate.Value.Month.ToString("0"); - - model.MainAgreementAddedThisMonth = Sum(dbInfo.MainAgreementAddedThisMonth, excelInfo.MainAgreementAddedThisMonth); - model.MainAgreementAccumulatedThisYear = Sum(dbInfo.MainAgreementAccumulatedThisYear, excelInfo.MainAgreementAccumulatedThisYear); - model.MainAgreementValidedAtEndOfThisMonth = Sum(dbInfo.MainAgreementValidedAtEndOfThisMonth, excelInfo.MainAgreementValidedAtEndOfThisMonth); - model.SupplementalAgreementAddedThisMonth = Sum(dbInfo.SupplementalAgreementAddedThisMonth, excelInfo.SupplementalAgreementAddedThisMonth); - model.SupplementalAgreementAccumulatedThisYear = Sum(dbInfo.SupplementalAgreementAccumulatedThisYear, excelInfo.SupplementalAgreementAccumulatedThisYear); - model.SupplementalAgreementValidedAtTheEndOfThisMonth = Sum(dbInfo.SupplementalAgreementValidedAtTheEndOfThisMonth, excelInfo.SupplementalAgreementValidedAtTheEndOfThisMonth); - model.PerformanceGuaranteeAgreementAddedThisMonth = Sum(dbInfo.PerformanceGuaranteeAgreementAddedThisMonth, excelInfo.PerformanceGuaranteeAgreementAddedThisMonth); - model.PerformanceGuaranteeAgreementAccumulatedThisYear = Sum(dbInfo.PerformanceGuaranteeAgreementAccumulatedThisYear, excelInfo.PerformanceGuaranteeAgreementAccumulatedThisYear); - model.PerformanceGuaranteeAgreementValidedAtEndOfThisMonth = Sum(dbInfo.PerformanceGuaranteeAgreementValidedAtEndOfThisMonth, excelInfo.PerformanceGuaranteeAgreementValidedAtEndOfThisMonth); - model.TransactionConfirmationAddedThisMonth = Sum(dbInfo.TransactionConfirmationAddedThisMonth, excelInfo.TransactionConfirmationAddedThisMonth); - model.TransactionConfirmationBookAccumulatedThisYear = Sum(dbInfo.TransactionConfirmationBookAccumulatedThisYear, excelInfo.TransactionConfirmationBookAccumulatedThisYear); - model.TransactionConfirmationValidedAtEndOfThisMonth = Sum(dbInfo.TransactionConfirmationValidedAtEndOfThisMonth, excelInfo.TransactionConfirmationValidedAtEndOfThisMonth); - - model.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionBusinessCorrespondence = Sum(dbInfo.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionBusinessCorrespondence, excelInfo.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionBusinessCorrespondence); - model.NetCapitalAtEndOfTheMonth = Sum(dbInfo.NetCapitalAtEndOfTheMonth, excelInfo.NetCapitalAtEndOfTheMonth); - model.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionsBusinessAccountedForTheProportionOfTheCorrespondingNetCapital = Sum(dbInfo.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionsBusinessAccountedForTheProportionOfTheCorrespondingNetCapital, excelInfo.ToCarryOutSelfEquitySecuritiesAndOTCDerivativesScaleStockOptionsBusinessAccountedForTheProportionOfTheCorrespondingNetCapital); - - model.OTCOptionHasSignedByLegalPerson = Sum(dbInfo.OTCOptionHasSignedByLegalPerson, excelInfo.OTCOptionHasSignedByLegalPerson); - model.OTCOptionsHaveContractedProducts = Sum(dbInfo.OTCOptionsHaveContractedProducts, excelInfo.OTCOptionsHaveContractedProducts); - model.OTCOptionsForTheMonthOfTheNewAddLegalPerson = Sum(dbInfo.OTCOptionsForTheMonthOfTheNewAddLegalPerson, excelInfo.OTCOptionsForTheMonthOfTheNewAddLegalPerson); - model.OTCOptionsForTheMonthOfTheNewAddProduct = Sum(dbInfo.OTCOptionsForTheMonthOfTheNewAddProduct, excelInfo.OTCOptionsForTheMonthOfTheNewAddProduct); - model.OTCOptionsLegalPersonInDurationForThisMouth = Sum(dbInfo.OTCOptionsLegalPersonInDurationForThisMouth, excelInfo.OTCOptionsLegalPersonInDurationForThisMouth); - model.OTCOptionsProductsInDurationForThisMouth = Sum(dbInfo.OTCOptionsProductsInDurationForThisMouth, excelInfo.OTCOptionsProductsInDurationForThisMouth); - - model.IncomeSwapHasSignedLegalPersonNumber = Sum(dbInfo.IncomeSwapHasSignedLegalPersonNumber, excelInfo.IncomeSwapHasSignedLegalPersonNumber); - model.IncomeSwapHasSignedProductNumber = Sum(dbInfo.IncomeSwapHasSignedProductNumber, excelInfo.IncomeSwapHasSignedProductNumber); - model.IncomeSwapForTheMonthOfTheNewAddLegalPerson = Sum(dbInfo.IncomeSwapForTheMonthOfTheNewAddLegalPerson, excelInfo.IncomeSwapForTheMonthOfTheNewAddLegalPerson); - model.IncomeSwapForTheMonthOfTheNewAddProduct = Sum(dbInfo.IncomeSwapForTheMonthOfTheNewAddProduct, excelInfo.IncomeSwapForTheMonthOfTheNewAddProduct); - model.IncomeSwapLegalPersonInDurationForThisMouth = Sum(dbInfo.IncomeSwapLegalPersonInDurationForThisMouth, excelInfo.IncomeSwapLegalPersonInDurationForThisMouth); - model.IncomeSwapProductsInDurationForThisMouth = Sum(dbInfo.IncomeSwapProductsInDurationForThisMouth, excelInfo.IncomeSwapProductsInDurationForThisMouth); - - model.OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale = Sum(dbInfo.OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale, excelInfo.OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale); - model.OTCOptionsWithinIndividualStocksLateLastMonthDurationScale = Sum(dbInfo.OTCOptionsWithinIndividualStocksLateLastMonthDurationScale, excelInfo.OTCOptionsWithinIndividualStocksLateLastMonthDurationScale); - model.OTCOptionsCommoditiesLastMonthDurationScale = Sum(dbInfo.OTCOptionsCommoditiesLastMonthDurationScale, excelInfo.OTCOptionsCommoditiesLastMonthDurationScale); - model.OTCOptionsOtherSubjectLastMonthDurationScale = Sum(dbInfo.OTCOptionsOtherSubjectLastMonthDurationScale, excelInfo.OTCOptionsOtherSubjectLastMonthDurationScale); - model.RevenueExchangeDomesticStockIndexLastMonthDurationScale = Sum(dbInfo.RevenueExchangeDomesticStockIndexLastMonthDurationScale, excelInfo.RevenueExchangeDomesticStockIndexLastMonthDurationScale); - model.RevenueExchangeDomesticIndividualStocksLastMonthDurationScale = Sum(dbInfo.RevenueExchangeDomesticIndividualStocksLastMonthDurationScale, excelInfo.RevenueExchangeDomesticIndividualStocksLastMonthDurationScale); - model.RevenueExchangeCommoditiesLastMonthDurationScale = Sum(dbInfo.RevenueExchangeCommoditiesLastMonthDurationScale, excelInfo.RevenueExchangeCommoditiesLastMonthDurationScale); - model.RevenueExchangeOtherSubjectLastMonthDurationScale = Sum(dbInfo.RevenueExchangeOtherSubjectLastMonthDurationScale, excelInfo.RevenueExchangeOtherSubjectLastMonthDurationScale); - model.TotalOfLastMonthDurationScale = Sum(dbInfo.TotalOfLastMonthDurationScale, excelInfo.TotalOfLastMonthDurationScale); - - model.OTCOptionsWithinTheIndexThisMonthOfTheNewScale = Sum(dbInfo.OTCOptionsWithinTheIndexThisMonthOfTheNewScale, excelInfo.OTCOptionsWithinTheIndexThisMonthOfTheNewScale); - model.OTCOptionsToAddScaleDomesticStocksInThisMonth = Sum(dbInfo.OTCOptionsToAddScaleDomesticStocksInThisMonth, excelInfo.OTCOptionsToAddScaleDomesticStocksInThisMonth); - model.OTCOptionsCommoditiesTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.OTCOptionsCommoditiesTheNewSizeOfTheIncreaseInThisMonth, excelInfo.OTCOptionsCommoditiesTheNewSizeOfTheIncreaseInThisMonth); - model.OTCOptionsOtherSubjectTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.OTCOptionsOtherSubjectTheNewSizeOfTheIncreaseInThisMonth, excelInfo.OTCOptionsOtherSubjectTheNewSizeOfTheIncreaseInThisMonth); - model.RevenueExchangeDomesticStockIndexTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.RevenueExchangeDomesticStockIndexTheNewSizeOfTheIncreaseInThisMonth, excelInfo.RevenueExchangeDomesticStockIndexTheNewSizeOfTheIncreaseInThisMonth); - model.RevenueExchangeDomesticIndividualStocksTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.RevenueExchangeDomesticIndividualStocksTheNewSizeOfTheIncreaseInThisMonth, excelInfo.RevenueExchangeDomesticIndividualStocksTheNewSizeOfTheIncreaseInThisMonth); - model.RevenueExchangeCommoditiesTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.RevenueExchangeCommoditiesTheNewSizeOfTheIncreaseInThisMonth, excelInfo.RevenueExchangeCommoditiesTheNewSizeOfTheIncreaseInThisMonth); - model.RevenueExchangeOtherSubjectTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.RevenueExchangeOtherSubjectTheNewSizeOfTheIncreaseInThisMonth, excelInfo.RevenueExchangeOtherSubjectTheNewSizeOfTheIncreaseInThisMonth); - model.TotalOfTheNewSizeOfTheIncreaseInThisMonth = Sum(dbInfo.TotalOfTheNewSizeOfTheIncreaseInThisMonth, excelInfo.TotalOfTheNewSizeOfTheIncreaseInThisMonth); - - model.OTCOptionsTerminateScaleDomesticStockIndexThisMonth = Sum(dbInfo.OTCOptionsTerminateScaleDomesticStockIndexThisMonth, excelInfo.OTCOptionsTerminateScaleDomesticStockIndexThisMonth); - model.OTCOptionsTerminateScaleDomesticStocksInThisMonth = Sum(dbInfo.OTCOptionsTerminateScaleDomesticStocksInThisMonth, excelInfo.OTCOptionsTerminateScaleDomesticStocksInThisMonth); - model.OTCOptionsCommoditiesTerminationOfTheScaleOfThisMonth = Sum(dbInfo.OTCOptionsCommoditiesTerminationOfTheScaleOfThisMonth, excelInfo.OTCOptionsCommoditiesTerminationOfTheScaleOfThisMonth); - model.OTCOptionsOtherSubjectTerminationOfTheScaleOfThisMonth = Sum(dbInfo.OTCOptionsOtherSubjectTerminationOfTheScaleOfThisMonth, excelInfo.OTCOptionsOtherSubjectTerminationOfTheScaleOfThisMonth); - model.RevenueExchangeDomesticStockIndexTerminationOfTheScaleOfThisMonth = Sum(dbInfo.RevenueExchangeDomesticStockIndexTerminationOfTheScaleOfThisMonth, excelInfo.RevenueExchangeDomesticStockIndexTerminationOfTheScaleOfThisMonth); - model.RevenueExchangeDomesticIndividualStocksTerminationOfTheScaleOfThisMonth = Sum(dbInfo.RevenueExchangeDomesticIndividualStocksTerminationOfTheScaleOfThisMonth, excelInfo.RevenueExchangeDomesticIndividualStocksTerminationOfTheScaleOfThisMonth); - model.RevenueExchangeCommoditiesTerminationOfTheScaleOfThisMonth = Sum(dbInfo.RevenueExchangeCommoditiesTerminationOfTheScaleOfThisMonth, excelInfo.RevenueExchangeCommoditiesTerminationOfTheScaleOfThisMonth); - model.RevenueExchangeOtherSubjectTerminationOfTheScaleOfThisMonth = Sum(dbInfo.RevenueExchangeOtherSubjectTerminationOfTheScaleOfThisMonth, excelInfo.RevenueExchangeOtherSubjectTerminationOfTheScaleOfThisMonth); - model.TotalOfTerminationOfTheScaleOfThisMonth = Sum(dbInfo.TotalOfTerminationOfTheScaleOfThisMonth, excelInfo.TotalOfTerminationOfTheScaleOfThisMonth); - - model.OTCStockIndexOptionsWithinThisMonthOfTheExistenceOfScale = Sum(dbInfo.OTCStockIndexOptionsWithinThisMonthOfTheExistenceOfScale, excelInfo.OTCStockIndexOptionsWithinThisMonthOfTheExistenceOfScale); - model.OTCOptionsWithinIndividualStocksInThisMonthDurationScale = Sum(dbInfo.OTCOptionsWithinIndividualStocksInThisMonthDurationScale, excelInfo.OTCOptionsWithinIndividualStocksInThisMonthDurationScale); - model.OTCOptionsCommoditiesInThisMonthDurationScale = Sum(dbInfo.OTCOptionsCommoditiesInThisMonthDurationScale, excelInfo.OTCOptionsCommoditiesInThisMonthDurationScale); - model.OTCOptionsOtherSubjectThisMonthDurationScale = Sum(dbInfo.OTCOptionsOtherSubjectThisMonthDurationScale, excelInfo.OTCOptionsOtherSubjectThisMonthDurationScale); - model.RevenueExchangeDomesticStockIndexThisMonthDurationScale = Sum(dbInfo.RevenueExchangeDomesticStockIndexThisMonthDurationScale, excelInfo.RevenueExchangeDomesticStockIndexThisMonthDurationScale); - model.RevenueExchangeDomesticIndividualStocksThisMonthDurationScale = Sum(dbInfo.RevenueExchangeDomesticIndividualStocksThisMonthDurationScale, excelInfo.RevenueExchangeDomesticIndividualStocksThisMonthDurationScale); - model.RevenueExchangeCommoditiesThisMonthDurationScale = Sum(dbInfo.RevenueExchangeCommoditiesThisMonthDurationScale, excelInfo.RevenueExchangeCommoditiesThisMonthDurationScale); - model.RevenueExchangeOtherSubjectThisMonthDurationScale = Sum(dbInfo.RevenueExchangeOtherSubjectThisMonthDurationScale, excelInfo.RevenueExchangeOtherSubjectThisMonthDurationScale); - model.TotalOfThisMonthDurationScale = Sum(dbInfo.TotalOfThisMonthDurationScale, excelInfo.TotalOfThisMonthDurationScale); - - model.OTCOptionsStockIndexThisYearCumulativeScaleOfNewTerritory = Sum(dbInfo.OTCOptionsStockIndexThisYearCumulativeScaleOfNewTerritory, excelInfo.OTCOptionsStockIndexThisYearCumulativeScaleOfNewTerritory); - model.OTCOptionsStockThisYearCumulativeScaleOfNewTerritory = Sum(dbInfo.OTCOptionsStockThisYearCumulativeScaleOfNewTerritory, excelInfo.OTCOptionsStockThisYearCumulativeScaleOfNewTerritory); - model.OTCOptionsCommoditiesThisYearCumulativeScaleOfNewTerritory = Sum(dbInfo.OTCOptionsCommoditiesThisYearCumulativeScaleOfNewTerritory, excelInfo.OTCOptionsCommoditiesThisYearCumulativeScaleOfNewTerritory); - model.OTCOptionsOtherSubjectThisYearCumulativeScaleOfNewTerritory = Sum(dbInfo.OTCOptionsOtherSubjectThisYearCumulativeScaleOfNewTerritory, excelInfo.OTCOptionsOtherSubjectThisYearCumulativeScaleOfNewTerritory); - model.IncomeSwapDomesticStockIndexHasAddedNewScaleInThisYear = Sum(dbInfo.IncomeSwapDomesticStockIndexHasAddedNewScaleInThisYear, excelInfo.IncomeSwapDomesticStockIndexHasAddedNewScaleInThisYear); - model.IncomeSwapDomesticStockHasAddedNewScaleInThisYear = Sum(dbInfo.IncomeSwapDomesticStockHasAddedNewScaleInThisYear, excelInfo.IncomeSwapDomesticStockHasAddedNewScaleInThisYear); - model.IncomeSwapCommoditiesIndexHasAddedNewScaleInThisYear = Sum(dbInfo.IncomeSwapCommoditiesIndexHasAddedNewScaleInThisYear, excelInfo.IncomeSwapCommoditiesIndexHasAddedNewScaleInThisYear); - model.IncomeSwapOtherSubjectIndexHasAddedNewScaleInThisYear = Sum(dbInfo.IncomeSwapOtherSubjectIndexHasAddedNewScaleInThisYear, excelInfo.IncomeSwapOtherSubjectIndexHasAddedNewScaleInThisYear); - model.TotalNewScaleInThisYear = Sum(dbInfo.TotalNewScaleInThisYear, excelInfo.TotalNewScaleInThisYear); - - model.OTCOptionsStockIndexAtTheEndOfLastMonth = Sum(dbInfo.OTCOptionsStockIndexAtTheEndOfLastMonth, excelInfo.OTCOptionsStockIndexAtTheEndOfLastMonth); - model.OTCOptionsStockAtTheEndOfLastMonth = Sum(dbInfo.OTCOptionsStockAtTheEndOfLastMonth, excelInfo.OTCOptionsStockAtTheEndOfLastMonth); - model.OTCOptionsCommoditiesAtTheEndOfLastMonth = Sum(dbInfo.OTCOptionsCommoditiesAtTheEndOfLastMonth, excelInfo.OTCOptionsCommoditiesAtTheEndOfLastMonth); - model.OTCOptionsOtherSubjectAtTheEndOfLastMonth = Sum(dbInfo.OTCOptionsOtherSubjectAtTheEndOfLastMonth, excelInfo.OTCOptionsOtherSubjectAtTheEndOfLastMonth); - model.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfLastMonth = Sum(dbInfo.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfLastMonth, excelInfo.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfLastMonth); - model.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfLastMonth = Sum(dbInfo.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfLastMonth, excelInfo.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfLastMonth); - model.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfLastMonth = Sum(dbInfo.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfLastMonth, excelInfo.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfLastMonth); - model.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfLastMonth = Sum(dbInfo.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfLastMonth, excelInfo.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfLastMonth); - model.TotalNumberOfContractsAtTheEndOfLastMonth = Sum(dbInfo.TotalNumberOfContractsAtTheEndOfLastMonth, excelInfo.TotalNumberOfContractsAtTheEndOfLastMonth); - - model.OTCOptionsStockIndexThisMonthNewDomesticContractNumber = Sum(dbInfo.OTCOptionsStockIndexThisMonthNewDomesticContractNumber, excelInfo.OTCOptionsStockIndexThisMonthNewDomesticContractNumber); - model.OTCOptionsStockThisMonthNewDomesticContractNumber = Sum(dbInfo.OTCOptionsStockThisMonthNewDomesticContractNumber, excelInfo.OTCOptionsStockThisMonthNewDomesticContractNumber); - model.OTCOptionsCommoditiesThisMonthNewDomesticContractNumber = Sum(dbInfo.OTCOptionsCommoditiesThisMonthNewDomesticContractNumber, excelInfo.OTCOptionsCommoditiesThisMonthNewDomesticContractNumber); - model.OTCOptionsOtherSubjectThisMonthNewDomesticContractNumber = Sum(dbInfo.OTCOptionsOtherSubjectThisMonthNewDomesticContractNumber, excelInfo.OTCOptionsOtherSubjectThisMonthNewDomesticContractNumber); - model.IncomeSwapDomesticStockIndexNewContractInThisMonth = Sum(dbInfo.IncomeSwapDomesticStockIndexNewContractInThisMonth, excelInfo.IncomeSwapDomesticStockIndexNewContractInThisMonth); - model.IncomeSwapDomesticStockNewContractInThisMonth = Sum(dbInfo.IncomeSwapDomesticStockNewContractInThisMonth, excelInfo.IncomeSwapDomesticStockNewContractInThisMonth); - model.IncomeSwapCommoditiesNewContractInThisMonth = Sum(dbInfo.IncomeSwapCommoditiesNewContractInThisMonth, excelInfo.IncomeSwapCommoditiesNewContractInThisMonth); - model.IncomeSwapOtherSubjectNewContractInThisMonth = Sum(dbInfo.IncomeSwapOtherSubjectNewContractInThisMonth, excelInfo.IncomeSwapOtherSubjectNewContractInThisMonth); - model.TotalNumberOfNewContractsInThisMonth = Sum(dbInfo.TotalNumberOfNewContractsInThisMonth, excelInfo.TotalNumberOfNewContractsInThisMonth); - - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockIndexNumber = Sum(dbInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockIndexNumber, excelInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockIndexNumber); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockNumber = Sum(dbInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockNumber, excelInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheStockNumber); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheCommoditiesNumber = Sum(dbInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheCommoditiesNumber, excelInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheCommoditiesNumber); - model.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheOtherSubjectNumber = Sum(dbInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheOtherSubjectNumber, excelInfo.OTCOptionsThisMonthToTerminateTheContractWithinTheTerritoryOfTheOtherSubjectNumber); - model.IncomeSwapDomesticStockIndexTerminatesTheNumberOfContractsThisMonth = Sum(dbInfo.IncomeSwapDomesticStockIndexTerminatesTheNumberOfContractsThisMonth, excelInfo.IncomeSwapDomesticStockIndexTerminatesTheNumberOfContractsThisMonth); - model.IncomeSwapDomesticStockTerminatesTheNumberOfContractsThisMonth = Sum(dbInfo.IncomeSwapDomesticStockTerminatesTheNumberOfContractsThisMonth, excelInfo.IncomeSwapDomesticStockTerminatesTheNumberOfContractsThisMonth); - model.IncomeSwapCommoditiesTerminatesTheNumberOfContractsThisMonth = Sum(dbInfo.IncomeSwapCommoditiesTerminatesTheNumberOfContractsThisMonth, excelInfo.IncomeSwapCommoditiesTerminatesTheNumberOfContractsThisMonth); - model.IncomeSwapOtherSubjectTerminatesTheNumberOfContractsThisMonth = Sum(dbInfo.IncomeSwapOtherSubjectTerminatesTheNumberOfContractsThisMonth, excelInfo.IncomeSwapOtherSubjectTerminatesTheNumberOfContractsThisMonth); - model.TotalNumberOfContractsTerminatedThisMonth = Sum(dbInfo.TotalNumberOfContractsTerminatedThisMonth, excelInfo.TotalNumberOfContractsTerminatedThisMonth); - - model.OTCDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.OTCDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.OTCDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth); - model.OTCDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.OTCDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.OTCDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth); - model.OTCCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.OTCCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.OTCCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth); - model.OTCOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.OTCOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.OTCOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth); - model.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.IncomeExchangeDomesticStockIndexNumberOfRemainingContractsAtTheEndOfThisMonth); - model.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.IncomeExchangeDomesticStockNumberOfRemainingContractsAtTheEndOfThisMonth); - model.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.IncomeExchangeCommoditiesNumberOfRemainingContractsAtTheEndOfThisMonth); - model.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth = Sum(dbInfo.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth, excelInfo.IncomeExchangeOtherSubjectNumberOfRemainingContractsAtTheEndOfThisMonth); - model.TotalNumberOfContractsAtTheEndOfThisMonth = Sum(dbInfo.TotalNumberOfContractsAtTheEndOfThisMonth, excelInfo.TotalNumberOfContractsAtTheEndOfThisMonth); - - model.OTCOptionsStockIndexCumulativeDomesticNewContractNumberInThisYear = Sum(dbInfo.OTCOptionsStockIndexCumulativeDomesticNewContractNumberInThisYear, excelInfo.OTCOptionsStockIndexCumulativeDomesticNewContractNumberInThisYear); - model.OTCOptionsStockCumulativeDomesticNewContractNumberInThisYear = Sum(dbInfo.OTCOptionsStockCumulativeDomesticNewContractNumberInThisYear, excelInfo.OTCOptionsStockCumulativeDomesticNewContractNumberInThisYear); - model.OTCOptionsCommoditiesCumulativeDomesticNewContractNumberInThisYear = Sum(dbInfo.OTCOptionsCommoditiesCumulativeDomesticNewContractNumberInThisYear, excelInfo.OTCOptionsCommoditiesCumulativeDomesticNewContractNumberInThisYear); - model.OTCOptionsOtherSubjectCumulativeDomesticNewContractNumberInThisYear = Sum(dbInfo.OTCOptionsOtherSubjectCumulativeDomesticNewContractNumberInThisYear, excelInfo.OTCOptionsOtherSubjectCumulativeDomesticNewContractNumberInThisYear); - model.IncomeSwapDomesticStockIndexCumulativeNumberOfNewContractsInThisYear = Sum(dbInfo.IncomeSwapDomesticStockIndexCumulativeNumberOfNewContractsInThisYear, excelInfo.IncomeSwapDomesticStockIndexCumulativeNumberOfNewContractsInThisYear); - model.IncomeSwapDomesticStockCumulativeNumberOfNewContractsInThisYear = Sum(dbInfo.IncomeSwapDomesticStockCumulativeNumberOfNewContractsInThisYear, excelInfo.IncomeSwapDomesticStockCumulativeNumberOfNewContractsInThisYear); - model.IncomeSwapCommoditiesCumulativeNumberOfNewContractsInThisYear = Sum(dbInfo.IncomeSwapCommoditiesCumulativeNumberOfNewContractsInThisYear, excelInfo.IncomeSwapCommoditiesCumulativeNumberOfNewContractsInThisYear); - model.IncomeSwapOtherSubjectCumulativeNumberOfNewContractsInThisYear = Sum(dbInfo.IncomeSwapOtherSubjectCumulativeNumberOfNewContractsInThisYear, excelInfo.IncomeSwapOtherSubjectCumulativeNumberOfNewContractsInThisYear); - model.TotalNumberOfNewContractsInThisYear = Sum(dbInfo.TotalNumberOfNewContractsInThisYear, excelInfo.TotalNumberOfNewContractsInThisYear); - - model.MarginOfSubsistSwap = Sum(dbInfo.MarginOfSubsistSwap, excelInfo.MarginOfSubsistSwap); - model.HedgedMarketValueOfSwap = Sum(dbInfo.HedgedMarketValueOfSwap, excelInfo.HedgedMarketValueOfSwap); - model.LeverageRatiOfSwap = Sum(dbInfo.LeverageRatiOfSwap, excelInfo.LeverageRatiOfSwap); - model.MarginOfSubsistStockIndexSwap = Sum(dbInfo.MarginOfSubsistStockIndexSwap, excelInfo.MarginOfSubsistStockIndexSwap); - model.HedgedMarketValueOfStockIndexSwap = Sum(dbInfo.HedgedMarketValueOfStockIndexSwap, excelInfo.HedgedMarketValueOfStockIndexSwap); - model.LeverageRatioOfStockIndexSwap = Sum(dbInfo.LeverageRatioOfStockIndexSwap, excelInfo.LeverageRatioOfStockIndexSwap); - model.MarginOfSubsistStockSwap = Sum(dbInfo.MarginOfSubsistStockSwap, excelInfo.MarginOfSubsistStockSwap); - model.HedgedMarketValueOfStockSwap = Sum(dbInfo.HedgedMarketValueOfStockSwap, excelInfo.HedgedMarketValueOfStockSwap); - model.LeverageRatioOfStockSwap = Sum(dbInfo.LeverageRatioOfStockSwap, excelInfo.LeverageRatioOfStockSwap); - model.MarginandPremiumOfSubsistOption = Sum(dbInfo.MarginandPremiumOfSubsistOption, excelInfo.MarginandPremiumOfSubsistOption); - model.HedgedMarketValueOfOption = Sum(dbInfo.HedgedMarketValueOfOption, excelInfo.HedgedMarketValueOfOption); - model.LeverageRatioOfOption = Sum(dbInfo.LeverageRatioOfOption, excelInfo.LeverageRatioOfOption); - model.MarginandPremiumOfSubsistStockIndexOption = Sum(dbInfo.MarginandPremiumOfSubsistStockIndexOption, excelInfo.MarginandPremiumOfSubsistStockIndexOption); - model.HedgedMarketValueOfStockIndexOption = Sum(dbInfo.HedgedMarketValueOfStockIndexOption, excelInfo.HedgedMarketValueOfStockIndexOption); - model.LeverageRatioOfStockIndexOption = Sum(dbInfo.LeverageRatioOfStockIndexOption, excelInfo.LeverageRatioOfStockIndexOption); - model.MarginandPremiumOfSubsistStockOption = Sum(dbInfo.MarginandPremiumOfSubsistStockOption, excelInfo.MarginandPremiumOfSubsistStockOption); - model.HedgedMarketValueOfStockOption = Sum(dbInfo.HedgedMarketValueOfStockOption, excelInfo.HedgedMarketValueOfStockOption); - model.LeverageRatioOfStockOption = Sum(dbInfo.LeverageRatioOfStockOption, excelInfo.LeverageRatioOfStockOption); - - model.TotalNominalPrincipalAmountOfSwapThisMonth = Sum(dbInfo.TotalNominalPrincipalAmountOfSwapThisMonth, excelInfo.TotalNominalPrincipalAmountOfSwapThisMonth); - model.TotalNominalPrincipalAmountOfSwapLastMonth = Sum(dbInfo.TotalNominalPrincipalAmountOfSwapLastMonth, excelInfo.TotalNominalPrincipalAmountOfSwapLastMonth); - - model.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth = Sum(dbInfo.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth, excelInfo.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeThisMonth); - model.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth = Sum(dbInfo.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth, excelInfo.TheValueOfTheStockSwapInTheCorrespondingPerformanceGuaranteeLastMonth); - - model.SwapCashCollateralValueThisMonth = Sum(dbInfo.SwapCashCollateralValueThisMonth, excelInfo.SwapCashCollateralValueThisMonth); - model.SwapCashCollateralValueLastMonth = Sum(dbInfo.SwapCashCollateralValueLastMonth, excelInfo.SwapCashCollateralValueLastMonth); - - model.SwapSecuritiesCollateralValueThisMonth = Sum(dbInfo.SwapSecuritiesCollateralValueThisMonth, excelInfo.SwapSecuritiesCollateralValueThisMonth); - model.SwapSecuritiesCollateralValueLastMonthThisMonth = Sum(dbInfo.SwapSecuritiesCollateralValueLastMonthThisMonth, excelInfo.SwapSecuritiesCollateralValueLastMonthThisMonth); - - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull, excelInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthFull); - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull, excelInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthFull); - - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet, excelInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessThisMonthNet); - model.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet, excelInfo.ProportionOfTheOverallPerformanceOfTheSwapBusinessLastMonthNet); - - model.SwapNumberOfDefaultCustomersAtThisMonthThisMonth = Sum(dbInfo.SwapNumberOfDefaultCustomersAtThisMonthThisMonth, excelInfo.SwapNumberOfDefaultCustomersAtThisMonthThisMonth); - model.SwapNumberOfDefaultCustomersAtThisMonthLastMonth = Sum(dbInfo.SwapNumberOfDefaultCustomersAtThisMonthLastMonth, excelInfo.SwapNumberOfDefaultCustomersAtThisMonthLastMonth); - - model.SwapDefaultTransactionNumberAtThisMonthThisMonth = Sum(dbInfo.SwapDefaultTransactionNumberAtThisMonthThisMonth, excelInfo.SwapDefaultTransactionNumberAtThisMonthThisMonth); - model.SwapDefaultTransactionNumberAtThisMonthLastMonth = Sum(dbInfo.SwapDefaultTransactionNumberAtThisMonthLastMonth, excelInfo.SwapDefaultTransactionNumberAtThisMonthLastMonth); - - model.TotalSwapDefaultCustomerNumberInThisYearThisMonth = Sum(dbInfo.TotalSwapDefaultCustomerNumberInThisYearThisMonth, excelInfo.TotalSwapDefaultCustomerNumberInThisYearThisMonth); - model.TotalSwapDefaultCustomerNumberInThisYearLastMonth = Sum(dbInfo.TotalSwapDefaultCustomerNumberInThisYearLastMonth, excelInfo.TotalSwapDefaultCustomerNumberInThisYearLastMonth); - - model.SwapNumberOfDefaultCustomersInThisYearThisMonth = Sum(dbInfo.SwapNumberOfDefaultCustomersInThisYearThisMonth, excelInfo.SwapNumberOfDefaultCustomersInThisYearThisMonth); - model.SwapNumberOfDefaultCustomersInThisYearLastMonth = Sum(dbInfo.SwapNumberOfDefaultCustomersInThisYearLastMonth, excelInfo.SwapNumberOfDefaultCustomersInThisYearLastMonth); - - model.TotalNominalPrincipalAmountOfOptionThisMonth = Sum(dbInfo.TotalNominalPrincipalAmountOfOptionThisMonth, excelInfo.TotalNominalPrincipalAmountOfOptionThisMonth); - model.TotalNominalPrincipalAmountOfOptionLastMonth = Sum(dbInfo.TotalNominalPrincipalAmountOfOptionLastMonth, excelInfo.TotalNominalPrincipalAmountOfOptionLastMonth); - - model.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth = Sum(dbInfo.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth, excelInfo.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeThisMonth); - model.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth = Sum(dbInfo.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth, excelInfo.TheValueOfTheStockOptionCorrespondingPerformanceGuaranteeLastMonth); - - model.OptionCashCollateralValueThisMonth = Sum(dbInfo.OptionCashCollateralValueThisMonth, excelInfo.OptionCashCollateralValueThisMonth); - model.OptionCashCollateralValueLastMonth = Sum(dbInfo.OptionCashCollateralValueLastMonth, excelInfo.OptionCashCollateralValueLastMonth); - - model.OptionSecuritiesCollateralValueThisMonth = Sum(dbInfo.OptionSecuritiesCollateralValueThisMonth, excelInfo.OptionSecuritiesCollateralValueThisMonth); - model.OptionSecuritiesCollateralValueLastMonth = Sum(dbInfo.OptionSecuritiesCollateralValueLastMonth, excelInfo.OptionSecuritiesCollateralValueLastMonth); - - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthFull = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthFull, excelInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthFull); - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthFull = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthFull, excelInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthFull); - - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthNet = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthNet, excelInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessThisMonthNet); - model.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthNet = Sum(dbInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthNet, excelInfo.ProportionOfTheOverallPerformanceOfTheOptionBusinessLastMonthNet); - - model.OptionNumberOfDefaultCustomersAtThisMonthThisMonth = Sum(dbInfo.OptionNumberOfDefaultCustomersAtThisMonthThisMonth, excelInfo.OptionNumberOfDefaultCustomersAtThisMonthThisMonth); - model.OptionNumberOfDefaultCustomersAtThisMonthLastMonth = Sum(dbInfo.OptionNumberOfDefaultCustomersAtThisMonthLastMonth, excelInfo.OptionNumberOfDefaultCustomersAtThisMonthLastMonth); - - model.OptionTransactionNumberAtThisMonthThisMonth = Sum(dbInfo.OptionTransactionNumberAtThisMonthThisMonth, excelInfo.OptionTransactionNumberAtThisMonthThisMonth); - model.OptionTransactionNumberAtThisMonthLastMonth = Sum(dbInfo.OptionTransactionNumberAtThisMonthLastMonth, excelInfo.OptionTransactionNumberAtThisMonthLastMonth); - - model.TotalOptionDefaultCustomerNumberInThisYearThisMonth = Sum(dbInfo.TotalOptionDefaultCustomerNumberInThisYearThisMonth, excelInfo.TotalOptionDefaultCustomerNumberInThisYearThisMonth); - model.TotalOptionDefaultCustomerNumberInThisYearLastMonth = Sum(dbInfo.TotalOptionDefaultCustomerNumberInThisYearLastMonth, excelInfo.TotalOptionDefaultCustomerNumberInThisYearLastMonth); - - model.OptionNumberOfDefaultCustomersInThisYearThisMonth = Sum(dbInfo.OptionNumberOfDefaultCustomersInThisYearThisMonth, excelInfo.OptionNumberOfDefaultCustomersInThisYearThisMonth); - model.OptionNumberOfDefaultCustomersInThisYearLastMonth = Sum(dbInfo.OptionNumberOfDefaultCustomersInThisYearLastMonth, excelInfo.OptionNumberOfDefaultCustomersInThisYearLastMonth); - - model.StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth = Sum(dbInfo.StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth, excelInfo.StockTradingCorrespondsToValueOfCollateralAtEndOfThisMonth); - model.StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth = Sum(dbInfo.StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth, excelInfo.StockTradingCorrespondsToValueOfCollateralAtEndOfLastMonth); - - model.CashBalanceAtEndOfThisMonth = Sum(dbInfo.CashBalanceAtEndOfThisMonth, excelInfo.CashBalanceAtEndOfThisMonth); - model.CashBalanceAtEndOfLastMonth = Sum(dbInfo.CashBalanceAtEndOfLastMonth, excelInfo.CashBalanceAtEndOfLastMonth); - - model.HoldStockMarketValueAtEndOfThisMonth = Sum(dbInfo.HoldStockMarketValueAtEndOfThisMonth, excelInfo.HoldStockMarketValueAtEndOfThisMonth); - model.HoldStockMarketValueAtEndOfLastMonth = Sum(dbInfo.HoldStockMarketValueAtEndOfLastMonth, excelInfo.HoldStockMarketValueAtEndOfLastMonth); - - model.HoldMarketValueOfBondsAtTheEndOfThisMonth = Sum(dbInfo.HoldMarketValueOfBondsAtTheEndOfThisMonth, excelInfo.HoldMarketValueOfBondsAtTheEndOfThisMonth); - model.HoldMarketValueOfBondsAtTheEndOfLastMonth = Sum(dbInfo.HoldMarketValueOfBondsAtTheEndOfLastMonth, excelInfo.HoldMarketValueOfBondsAtTheEndOfLastMonth); - - model.OwnedAssetManagementProductsAtTheEndOfThisMonth = Sum(dbInfo.OwnedAssetManagementProductsAtTheEndOfThisMonth, excelInfo.OwnedAssetManagementProductsAtTheEndOfThisMonth); - model.OwnedAssetManagementProductsAtTheEndOfLastMonth = Sum(dbInfo.OwnedAssetManagementProductsAtTheEndOfLastMonth, excelInfo.OwnedAssetManagementProductsAtTheEndOfLastMonth); - - model.OwnedBankFinanceAtTheEndOfThisMonth = Sum(dbInfo.OwnedBankFinanceAtTheEndOfThisMonth, excelInfo.OwnedBankFinanceAtTheEndOfThisMonth); - model.OwnedBankFinanceAtTheEndOfLastMonth = Sum(dbInfo.OwnedBankFinanceAtTheEndOfLastMonth, excelInfo.OwnedBankFinanceAtTheEndOfLastMonth); - - model.HoldTrustProductAtTheEndOfThisMonth = Sum(dbInfo.HoldTrustProductAtTheEndOfThisMonth, excelInfo.HoldTrustProductAtTheEndOfThisMonth); - model.HoldTrustProductAtTheEndOfLastMonth = Sum(dbInfo.HoldTrustProductAtTheEndOfLastMonth, excelInfo.HoldTrustProductAtTheEndOfLastMonth); - - model.InsuranceProductsAreHeldAtTheEndOfThisMonth = Sum(dbInfo.InsuranceProductsAreHeldAtTheEndOfThisMonth, excelInfo.InsuranceProductsAreHeldAtTheEndOfThisMonth); - model.InsuranceProductsAreHeldAtTheEndOfLastMonth = Sum(dbInfo.InsuranceProductsAreHeldAtTheEndOfLastMonth, excelInfo.InsuranceProductsAreHeldAtTheEndOfLastMonth); - - model.HoldOtherProductsAtTheEndOfThisMonth = Sum(dbInfo.HoldOtherProductsAtTheEndOfThisMonth, excelInfo.HoldOtherProductsAtTheEndOfThisMonth); - model.HoldOtherProductsAtTheEndOfLastMonth = Sum(dbInfo.HoldOtherProductsAtTheEndOfLastMonth, excelInfo.HoldOtherProductsAtTheEndOfLastMonth); - - model.SettledSwapItemsAtThisMonth = Sum(dbInfo.SettledSwapItemsAtThisMonth, excelInfo.SettledSwapItemsAtThisMonth); - model.SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth = Sum(dbInfo.SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth, excelInfo.SettledSwapTransactionInvolvesNotionalPrincipalAtThisMonth); - model.SwapIncomeCashFlow = Sum(dbInfo.SwapIncomeCashFlow, excelInfo.SwapIncomeCashFlow); - model.SwapExpensesCashFlow = Sum(dbInfo.SwapExpensesCashFlow, excelInfo.SwapExpensesCashFlow); - model.CashFlowCorrespondingToNetIncomeOnSwapMargin = Sum(dbInfo.CashFlowCorrespondingToNetIncomeOnSwapMargin, excelInfo.CashFlowCorrespondingToNetIncomeOnSwapMargin); - model.SwapHedgeCost = Sum(dbInfo.SwapHedgeCost, excelInfo.SwapHedgeCost); - - model.SettledOptionItemsAtThisMonth = Sum(dbInfo.SettledOptionItemsAtThisMonth, excelInfo.SettledOptionItemsAtThisMonth); - model.SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth = Sum(dbInfo.SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth, excelInfo.SettledOptionTransactionInvolvesNotionalPrincipalAtThisMonth); - model.OptionPremiumIncome = Sum(dbInfo.OptionPremiumIncome, excelInfo.OptionPremiumIncome); - model.OptionHedgeCost = Sum(dbInfo.OptionHedgeCost, excelInfo.OptionHedgeCost); - - model.BalanceOfSwapRealizedGainsAndLossesAtThisMonth = Sum(dbInfo.BalanceOfSwapRealizedGainsAndLossesAtThisMonth, excelInfo.BalanceOfSwapRealizedGainsAndLossesAtThisMonth); - model.BalanceOfOptionRealizedGainsAndLossesAtThisMonth = Sum(dbInfo.BalanceOfOptionRealizedGainsAndLossesAtThisMonth, excelInfo.BalanceOfOptionRealizedGainsAndLossesAtThisMonth); - - model.BalanceOfSwapRealizedGainsAndLossesAtThisYear = Sum(dbInfo.BalanceOfSwapRealizedGainsAndLossesAtThisYear, excelInfo.BalanceOfSwapRealizedGainsAndLossesAtThisYear); - model.BalanceOfOptionRealizedGainsAndLossesAtThisYear = Sum(dbInfo.BalanceOfOptionRealizedGainsAndLossesAtThisYear, excelInfo.BalanceOfOptionRealizedGainsAndLossesAtThisYear); - - model.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth = Sum(dbInfo.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth, excelInfo.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisMonth); - model.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth = Sum(dbInfo.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth, excelInfo.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisMonth); - - model.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear = Sum(dbInfo.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear, excelInfo.BalanceOfSwapChangedGainsAndLossesInFairValueAtThisYear); - model.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear = Sum(dbInfo.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear, excelInfo.BalanceOfOptionChangedGainsAndLossesInFairValueAtThisYear); - - model.BalanceOfSwapTotalGainsAndLossesAtThisMonth = Sum(dbInfo.BalanceOfSwapTotalGainsAndLossesAtThisMonth, excelInfo.BalanceOfSwapTotalGainsAndLossesAtThisMonth); - model.BalanceOfOptionTotalGainsAndLossesAtThisMonth = Sum(dbInfo.BalanceOfOptionTotalGainsAndLossesAtThisMonth, excelInfo.BalanceOfOptionTotalGainsAndLossesAtThisMonth); - - model.BalanceOfSwapTotalGainsAndLossesAtThisYear = Sum(dbInfo.BalanceOfSwapTotalGainsAndLossesAtThisYear, excelInfo.BalanceOfSwapTotalGainsAndLossesAtThisYear); - model.BalanceOfOptionTotalGainsAndLossesAtThisYear = Sum(dbInfo.BalanceOfOptionTotalGainsAndLossesAtThisYear, excelInfo.BalanceOfOptionTotalGainsAndLossesAtThisYear); - - model.IncreaseBusinessDetailsThisMonthTuple = new List(); - if (dbInfo.IncreaseBusinessDetailsThisMonthTuple != null) - { - model.IncreaseBusinessDetailsThisMonthTuple.AddRange(dbInfo.IncreaseBusinessDetailsThisMonthTuple); - } - if (excelInfo.IncreaseBusinessDetailsThisMonthTuple != null) - { - model.IncreaseBusinessDetailsThisMonthTuple.AddRange(excelInfo.IncreaseBusinessDetailsThisMonthTuple); - } - - model.InventoryBusinessDetailsAtTheEndOfThisMonthTuple = new List(); - if (dbInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) - { - model.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.AddRange(dbInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple); - } - if (excelInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) - { - model.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.AddRange(excelInfo.InventoryBusinessDetailsAtTheEndOfThisMonthTuple); - } - - model.TargetCaseAndHedgeTuple = new List(); - if (dbInfo.TargetCaseAndHedgeTuple != null) - { - model.TargetCaseAndHedgeTuple.AddRange(dbInfo.TargetCaseAndHedgeTuple); - } - if (excelInfo.TargetCaseAndHedgeTuple != null) - { - model.TargetCaseAndHedgeTuple.AddRange(excelInfo.TargetCaseAndHedgeTuple); - } - - return model; - } - - private string Sum(string param1, string param2) - { - var status1 = double.TryParse(param1, out var v1); - var status2 = double.TryParse(param2, out var v2); - if (status1 || status2) - { - return (v1 + v2).ToString(); - } - return ""; - } - private PeriodicReportSACModel GetPeriodicReportSACFromExcel() { var model = new PeriodicReportSACModel(); @@ -1234,7 +329,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private void GetClientInfo(PeriodicReportSACModel model, DataTable dt, int startRow, int startCol) { - int row = startRow + 0; + var row = startRow + 0; model.OTCOptionHasSignedByLegalPerson = GetDataSetValueToDouble(dt, row, startCol + 0).ToString(); model.OTCOptionsHaveContractedProducts = GetDataSetValueToDouble(dt, row, startCol + 1).ToString(); model.OTCOptionsForTheMonthOfTheNewAddLegalPerson = GetDataSetValueToDouble(dt, row, startCol + 2).ToString(); @@ -1258,7 +353,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private void GetExchangeInfo(PeriodicReportSACModel model, DataTable dt, int startRow, int startCol) { - int row = startRow + 0; + var row = startRow + 0; model.OTCStockIndexOptionsWithinTheLastMonthTheExistenceOfScale = GetDataSetValueToDouble(dt, row, startCol + 0).ToString(); model.OTCOptionsWithinIndividualStocksLateLastMonthDurationScale = GetDataSetValueToDouble(dt, row, startCol + 1).ToString(); model.OTCOptionsCommoditiesLastMonthDurationScale = GetDataSetValueToDouble(dt, row, startCol + 2).ToString(); @@ -1517,10 +612,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.PeriodicReportSAC != null) { - List listRoot = new List(); + var listRoot = new List(); var helper = new Common.CheckHelper(); var detailHelper = new Common.CheckHelper(); var detailAtHelper = new Common.CheckHelper(); @@ -1531,7 +626,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (model.PeriodicReportSAC.IncreaseBusinessDetailsThisMonthTuple != null) { - for (int i = 0; i < model.PeriodicReportSAC.IncreaseBusinessDetailsThisMonthTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportSAC.IncreaseBusinessDetailsThisMonthTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportSAC.IncreaseBusinessDetailsThisMonthTuple[i]; @@ -1541,15 +636,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("IncreaseBusinessDetailsThisMonthTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("IncreaseBusinessDetailsThisMonthTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportSAC.InventoryBusinessDetailsAtTheEndOfThisMonthTuple != null) { - for (int i = 0; i < model.PeriodicReportSAC.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportSAC.InventoryBusinessDetailsAtTheEndOfThisMonthTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportSAC.InventoryBusinessDetailsAtTheEndOfThisMonthTuple[i]; @@ -1559,15 +656,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("InventoryBusinessDetailsAtTheEndOfThisMonthTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("InventoryBusinessDetailsAtTheEndOfThisMonthTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (model.PeriodicReportSAC.TargetCaseAndHedgeTuple != null) { - for (int i = 0; i < model.PeriodicReportSAC.TargetCaseAndHedgeTuple.Count; i++) + for (var i = 0; i < model.PeriodicReportSAC.TargetCaseAndHedgeTuple.Count; i++) { var listItem = new List(); var item = model.PeriodicReportSAC.TargetCaseAndHedgeTuple[i]; @@ -1577,16 +676,20 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("TargetCaseAndHedgeTuple", i); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("TargetCaseAndHedgeTuple", i) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("PeriodicReportSAC"); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("PeriodicReportSAC") + { + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -1603,7 +706,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private double GetRealizedPnl(Expression> expression, DateTime startDate, DateTime endDate) { - var latestMonthIncomeQuery = from tc in DbContext.trade_cash join t in DbContext.trade.Where(expression) on tc.TradeId equals t.id where tc.ValueDate >= startDate && tc.ValueDate <= endDate && tc.ValidState != "InValid" && !tc.IsDeleted group tc by tc.TradeId into tcInfo select new { tcInfo.Key, Amount = tcInfo.Sum(O => (double?)O.Amount) }; + var latestMonthIncomeQuery = from tc in DbContext.trade_cash join t in DbContext.trade.Where(O => O.TradeType != "结构化交易").Where(expression) on tc.TradeId equals t.id where tc.ValueDate >= startDate && tc.ValueDate <= endDate && tc.ValidState != "InValid" && !tc.IsDeleted group tc by tc.TradeId into tcInfo select new { tcInfo.Key, Amount = tcInfo.Sum(O => (double?)O.Amount) }; var latestMonthIds = latestMonthIncomeQuery.Select(O => O.Key); var latestMonthIncome = latestMonthIncomeQuery.Sum(O => O.Amount) ?? 0; var lastMonthIncome = (from tc in DbContext.trade_cash where tc.ValueDate < startDate && latestMonthIds.Contains(tc.TradeId) && tc.ValidState != "InValid" && !tc.IsDeleted select tc.Amount).Sum(O => (double?)O) ?? 0; @@ -1619,7 +722,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private double GetPositionPnl(Expression> expression, DateTime lastEndDate, DateTime endDate) { - var swapLatestMonthIncomeQuery = from ep in DbContext.eod_trade_position join t in DbContext.trade.Where(expression) on ep.TradeId equals t.id where ep.ValueDate == endDate && ep.TradeId > 0 && ep.ClientId > 0 select new { ep.TradeId, ep.PositionPnL }; + var swapLatestMonthIncomeQuery = from ep in DbContext.eod_trade_position join t in DbContext.trade.Where(O => O.TradeType != "结构化交易").Where(expression) on ep.TradeId equals t.id where ep.ValueDate == endDate && ep.TradeId > 0 && ep.ClientId > 0 select new { ep.TradeId, ep.PositionPnL }; var swapLatestMonthIds = swapLatestMonthIncomeQuery.Select(O => O.TradeId); var swapLatestMonthIncome = swapLatestMonthIncomeQuery.Sum(O => (double?)O.PositionPnL) ?? 0; var swapLastMonthIncome = (from ep in DbContext.eod_trade_position where ep.ValueDate == lastEndDate && swapLatestMonthIds.Contains(ep.TradeId) select ep.PositionPnL).Sum(O => (double?)O) ?? 0; @@ -1644,13 +747,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } - var model = new IncreaseBusinessDetailsThisMonthModel(); - - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1); - model.NameOfCounterparty = GetDataSetValue(dt, i, 2); - model.CounterpartyProductName = GetDataSetValue(dt, i, 3); - model.TradeConfirmationNumber = GetDataSetValue(dt, i, 4); - model.TransactionConfirmationNumber = GetDataSetValue(dt, i, 5); + var model = new IncreaseBusinessDetailsThisMonthModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1), + NameOfCounterparty = GetDataSetValue(dt, i, 2), + CounterpartyProductName = GetDataSetValue(dt, i, 3), + TradeConfirmationNumber = GetDataSetValue(dt, i, 4), + TransactionConfirmationNumber = GetDataSetValue(dt, i, 5) + }; if (model.TransactionConfirmationNumber.IsNullOrWhiteSpace()) { model.TransactionConfirmationNumber = base.GetBizIdFromInfoTag(model.TradeConfirmationNumber); @@ -1664,7 +768,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.UndrlygAssetName = GetDataSetValue(dt, i, 12); model.UndrlygAssetCode = GetDataSetValue(dt, i, 13); model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 14); - model.OptionObjectSecondClass = ConsReport.UndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15)]; + model.OptionObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15)]; model.ReturnSwapObjectSecondClass = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 16)]; model.NonAnnualOptionFee = GetDataSetValue(dt, i, 17); model.OptionType = ConsReport.OptionStructureTypeMap[GetDataSetValue(dt, i, 18)]; @@ -1693,13 +797,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } - var model = new InventoryBusinessDetailsAtTheEndOfThisMonthModel(); - - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1); - model.NameOfCounterparty = GetDataSetValue(dt, i, 2); - model.NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3); - model.TradeConfirmationNumber = GetDataSetValue(dt, i, 4); - model.TransactionConfirmationNumber = GetDataSetValue(dt, i, 5); + var model = new InventoryBusinessDetailsAtTheEndOfThisMonthModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1), + NameOfCounterparty = GetDataSetValue(dt, i, 2), + NameOfCounterpartyProduct = GetDataSetValue(dt, i, 3), + TradeConfirmationNumber = GetDataSetValue(dt, i, 4), + TransactionConfirmationNumber = GetDataSetValue(dt, i, 5) + }; if (model.TransactionConfirmationNumber.IsNullOrWhiteSpace()) { model.TransactionConfirmationNumber = base.GetBizIdFromInfoTag(model.TradeConfirmationNumber); @@ -1713,7 +818,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.UndrlygAssetName = GetDataSetValue(dt, i, 12); model.UndrlygAssetCode = GetDataSetValue(dt, i, 13); model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 14); - model.OptionSumInvestmentTargetType = ConsReport.UndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15)]; + model.OptionSumInvestmentTargetType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 15)]; model.ExchangeSumInvestmentTargetType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 16)]; model.OptionFee = GetDataSetValue(dt, i, 17); model.OptionType = ConsReport.OptionStructureTypeMap[GetDataSetValue(dt, i, 18)]; @@ -1746,20 +851,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } - var model = new TargetCaseAndHedgeModel(); - - model.NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1); - model.BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 2)]; - model.SumInvestmentTargetType = ConsReport.HedgeSACUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 3)]; - model.SumInvestmentTargetName = GetDataSetValue(dt, i, 4); - model.UndrlygAssetCode = GetDataSetValue(dt, i, 5); - model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 6); - model.BuyingImpulseVolume = GetDataSetValue(dt, i, 7); - model.SellingImpulseVolume = GetDataSetValue(dt, i, 8); - model.ImpulseVolume = GetDataSetValue(dt, i, 9); - model.PositionAtTheEndOfThisMonth = GetDataSetValue(dt, i, 10); - model.TheNumberOfPositionsHeldAtTheEndOfThisMonth = GetDataSetValue(dt, i, 11); - model.AveragePriceAtTheEndOfTheMonth = GetDataSetValue(dt, i, 12); + var model = new TargetCaseAndHedgeModel + { + NameOfSecuritiesCompany = GetDataSetValue(dt, i, 1), + BusinessType = ConsReport.BusinessTypeMap[GetDataSetValue(dt, i, 2)], + SumInvestmentTargetType = ConsReport.HedgeSACUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 3)], + SumInvestmentTargetName = GetDataSetValue(dt, i, 4), + UndrlygAssetCode = GetDataSetValue(dt, i, 5), + UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 6), + BuyingImpulseVolume = GetDataSetValue(dt, i, 7), + SellingImpulseVolume = GetDataSetValue(dt, i, 8), + ImpulseVolume = GetDataSetValue(dt, i, 9), + PositionAtTheEndOfThisMonth = GetDataSetValue(dt, i, 10), + TheNumberOfPositionsHeldAtTheEndOfThisMonth = GetDataSetValue(dt, i, 11), + AveragePriceAtTheEndOfTheMonth = GetDataSetValue(dt, i, 12) + }; result.Add(model); } @@ -1777,6 +883,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + //定期报告中不存在编号,也就不存在修改编号的情况; + throw new NotImplementedException(); + } + public override bool BeforeOfGenerated(out string errMsg) { errMsg = ""; diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportService.cs index c0377027..eee1e5ed 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportService.cs @@ -1,6 +1,11 @@ -using System.Data; +using NPOI.SS.Formula.Functions; +using OfficeOpenXml.Drawing.Slicer.Style; +using System; +using System.Data; +using System.Text; using System.Text.RegularExpressions; using System.Xml; +using System.Xml.Serialization; using YieldChain.Helpers; using YLErp.BLL; using YLErp.Commons; @@ -9,7 +14,11 @@ using YLErp.Helpers; using YLErp.Modules.ClientModule; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; +using YLErp.Office; +using YLErp.Office.ExcelModule; +using static YLErp.Commons.ExcelHelper; using static YLErp.DBModels.Consts.ConsReport; +using ExcelHelper = YLErp.Commons.ExcelHelper; namespace YLErp.Modules.SuperviseReportModule.SAC.Service { @@ -19,14 +28,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { } + /// /// 生成报送文件锁 /// - private static AutoResetEvent generateSuperviseLock = new AutoResetEvent(true); + private static readonly AutoResetEvent generateSuperviseLock = new(true); /// /// 操作报送文件锁 /// - private static AutoResetEvent optionSuperviseLock = new AutoResetEvent(true); + private static readonly AutoResetEvent optionSuperviseLock = new(true); #region 生成报送文件 @@ -37,22 +47,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// public List Execute(ReportInfo req) { - LogFactory.GetLogger("Execute").Info($"7"); if (req.ReportTypes == null || req.ReportTypes.Count == 0) { throw new ServiceException("请选择要报送的类型"); } - LogFactory.GetLogger("Execute").Info($"8"); - List reportList = new List(); + var reportList = new List(); var useBreak = false; try { - LogFactory.GetLogger("Execute").Info($"9"); generateSuperviseLock.WaitOne(); - ReportStatusModel reportStatus = new ReportStatusModel(); + var reportStatus = new ReportStatusModel(); do { - LogFactory.GetLogger("Execute").Info($"10"); reportStatus.ResetCurrentLength(); //放开存在未报送报告时,阻塞其他报告生成的限制,可能引起的业务中先后顺序的问题(比如一定要先新增后修改的问题)需要客户自己判断; //var report = DbContext.supervise_report.Where(O => O.ReportType == SuperviseReportTypeEnum.SAC && O.ReportReponseStatus <= ReportSentStatus.SENDING).FirstOrDefault(); @@ -60,26 +66,25 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service //{ // throw new ServiceException($"{UserBLL.GetById((int)report.optUserId)?.Name} 名下存在未发送或发送中的记录,请稍后操作"); //} - LogFactory.GetLogger("Execute").Info($"10"); - Dictionary serviceDict = new Dictionary(); + var serviceDict = new Dictionary(); req.ReportTypes.Sort(); foreach (var item in req.ReportTypes) { - SuperviseReportTypeEnum type = (SuperviseReportTypeEnum)item; + var type = (SuperviseReportTypeEnum)item; var service = ReportBaseService.ReportFactory(OptUser, type); - if (!service.CheckRequestParamer(req, out string errMsg)) + if (!service.CheckRequestParamer(req, out var errMsg)) { throw new ServiceException(errMsg); } serviceDict[item] = service; } - LogFactory.GetLogger("Execute").Info($"11"); ReportBaseService.MaxExceIndex = queryCurrentExceIndex(); - List checkMsgArr = new List(); - ReportResponse res = new ReportResponse(); - res.Infos = new List(); - res.Index = queryCurrentFileIndex(req.ReportDate); - LogFactory.GetLogger("Execute").Info($"12"); + var checkMsgArr = new List(); + var res = new ReportResponse + { + Infos = new List(), + Index = queryCurrentFileIndex(req.ReportDate) + }; foreach (var service in serviceDict) { try @@ -128,9 +133,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { foreach (var item in service.Value.ValidOperationType) { - LogFactory.GetLogger("Execute").Info($"OperationType:" + item.ToString()); model = service.Value.Execute(req, item); - LogFactory.GetLogger("Execute").Info($"OperationType1:" + item.ToString()); res.Infos.Add(model); checkMsgArr.Add(service.Value.CheckValue(model, out _)); } @@ -156,11 +159,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (checkMsgArr.Any(O => O != null)) { - var exception = new ServiceException("数据校验未通过"); - exception.Tag = checkMsgArr.Where(O => O != null).ToList(); + var Tag = new ExceptionExtensionInfo + { + Tag = checkMsgArr.Where(O => O != null).ToList(), + }; + //生成文件会报错,暂时先不开放这个功能 + var savePath = $"~/App_Docs/Download/Report/Output/{OptUser.UserId}/报送文件_{DateTime.Now.ToString("yyyyMMddHHmmss")}.zip"; + GenerateUploadZipFile(res, savePath); + Tag.ErrFilePath = savePath; + var exception = new ServiceException("数据校验未通过") + { + Tag = Tag + }; throw exception; } - string zipPath = ""; + var zipPath = ""; try { optionSuperviseLock.WaitOne(); @@ -172,12 +185,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } foreach (var item in serviceDict) { - if (!item.Value.BeforeOfGenerated(out string errMsg)) + if (!item.Value.BeforeOfGenerated(out var errMsg)) { throw new ServiceException(errMsg); } } - DBModels.SuperviseReport reportInfo = new DBModels.SuperviseReport() + var reportInfo = new DBModels.SuperviseReport() { ReportType = SuperviseReportTypeEnum.SAC, ReportDate = req.ReportDate, @@ -222,7 +235,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private int queryCurrentExceIndex() { var exceId = DbContext.sac_report_notes.OrderByDescending(O => O.ExceId).Select(O => O.ExceId).FirstOrDefault(); - int index = 1; + var index = 1; if (!string.IsNullOrWhiteSpace(exceId)) { exceId = Regex.Match(exceId, @"\d{8}$").Value; @@ -239,9 +252,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private int queryCurrentFileIndex(DateTime date) { var fileId = DbContext.supervise_report.Where(O => O.ReportDate == date && O.ReportType == SuperviseReportTypeEnum.SAC).OrderByDescending(O => O.FileTag).Select(O => O.FileTag).FirstOrDefault(); - int index = 1; + var index = 1; if (!string.IsNullOrWhiteSpace(fileId)) { + if (fileId.EndsWith("_checked")) + { + fileId = fileId.Replace("_checked", ""); + } fileId = Regex.Match(fileId, @"\d{4}$").Value; index = int.Parse(fileId) + 1; } @@ -274,7 +291,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { return Return.Fail("文件不存在"); } - string targetPath = PS.Config.ErpElement.SAC_FDEPOutboxPath ?? ""; + var targetPath = PS.Config.ErpElement.SAC_FDEPOutboxPath ?? ""; if (string.IsNullOrWhiteSpace(targetPath) && string.IsNullOrWhiteSpace(PS.Config.ErpElement.SAC_RemotePath_Outbox)) { return Return.Fail("发件箱地址不存在"); @@ -301,7 +318,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { if (PS.Config.ErpElement.SAC_RemotePath_Outbox.ToLower().StartsWith("ftp")) { - ftpHelper = new FtpHelper(PS.Config.ErpElement.SAC_RemotePath_Outbox, PS.Config.ErpElement.SAC_RemoteUser, PS.Config.ErpElement.SAC_RemotePassword, PS.Config.ErpElement.SAC_FtpUsePassive, 3000, PS.Config.ErpElement.SAC_EnableSsl); + ftpHelper = new FtpHelper(PS.Config.ErpElement.SAC_RemotePath_Outbox, PS.Config.ErpElement.SAC_RemoteUser, PS.Config.ErpElement.SAC_RemotePassword, PS.Config.ErpElement.SAC_FtpUsePassive, 30000, PS.Config.ErpElement.SAC_EnableSsl); } else { @@ -321,7 +338,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } else { - if (ftpHelper.UploadFile(absPath, targetPath, out string msg)) + if (ftpHelper.UploadFile(absPath, targetPath, out var msg)) { File.Create(absPath + ".ok").Close(); ftpHelper.UploadFile(absPath + ".ok", targetPath, out msg); @@ -369,7 +386,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { try { - var xmlFileTag = (fileTag ?? "").Replace("YSP_", ""); + var xmlFileTag = fileTag.Replace("YSP_", ""); var query = DbContext.supervise_report.Where(O => O.FileTag.StartsWith(fileTag) || O.FileTag.StartsWith(xmlFileTag)); var tags = query.Select(O => O.FileTag); DbContext.supervise_report.RemoveRange(query); @@ -385,10 +402,41 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } + /// + /// 修改了结报送记录的状态 + /// + /// + /// + /// + public static void ChangeSettleReportStatus(YLContext db, int tradeId, DateTime reportStartDate) + { + var codeList = db.trade_contract_r.Where(O => O.TradeId == tradeId && O.Type == "交易确认书").Select(O => O.ContractCode).ToList(); + foreach (var code in codeList) + { + var notes = (from note in db.sac_report_notes + where + note.IsValid + && note.InfoTag.Contains("_" + code.Replace("_", "-") + "_了结") + && note.ReportDate >= reportStartDate + && !note.changeStatus + select note); + foreach (var item in notes) + { + var dict = JsonHelper.Deserialize>(item.InfoCache); + if (dict.TryGetValue("ValueDate", out var dateStr) && + DateTime.TryParse(dateStr, out var date) && date < reportStartDate) + { + continue; + } + item.changeStatus = true; + } + } + } + #region 处理报送响应文件 - private static readonly HashSet _responseFileNames = new HashSet(); - private static readonly HashSet _errFileNames = new HashSet(); + private static readonly HashSet _responseFileNames = new(); + private static readonly HashSet _errFileNames = new(); private const string responseDir = "/App_Docs/Download/ReportResponse/"; private const string tempDir = "/App_Docs/Download/ReportResponse/Temp/"; private static bool runStatus = false; @@ -409,14 +457,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (PS.Config.ErpElement.SAC_RemotePath.ToLower().StartsWith("ftp")) { - ftpHelper = new FtpHelper(PS.Config.ErpElement.SAC_RemotePath, PS.Config.ErpElement.SAC_RemoteUser, PS.Config.ErpElement.SAC_RemotePassword, PS.Config.ErpElement.SAC_FtpUsePassive, 3000, PS.Config.ErpElement.SAC_EnableSsl); + ftpHelper = new FtpHelper(PS.Config.ErpElement.SAC_RemotePath, PS.Config.ErpElement.SAC_RemoteUser, PS.Config.ErpElement.SAC_RemotePassword, PS.Config.ErpElement.SAC_FtpUsePassive, 30000, PS.Config.ErpElement.SAC_EnableSsl); } else { identityScope = new IdentityScope(PS.Config.ErpElement.SAC_RemoteUser, PS.Config.ErpElement.SAC_RemotePath, PS.Config.ErpElement.SAC_RemotePassword); } } - string path = PS.Config.ErpElement.SAC_FDEPInboxPath ?? ""; + var path = PS.Config.ErpElement.SAC_FDEPInboxPath ?? ""; if (string.IsNullOrWhiteSpace(path) && string.IsNullOrWhiteSpace(PS.Config.ErpElement.SAC_RemotePath)) { return; } if (path.ToLower().Contains("{yyyy}")) @@ -433,30 +481,43 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (ftpHelper == null ? !Directory.Exists(path) : !ftpHelper.ExistDirectorie(path)) { - return; + if (ftpHelper != null) + { + try + { + ftpHelper.GetDirectories(path); + } + catch + { + return; + } + } + else + { + return; + } } - - string[] fileNames = ftpHelper == null ? Directory.GetFiles(path) : ftpHelper.GetDirectories(path); + var fileNames = ftpHelper == null ? Directory.GetFiles(path) : ftpHelper.GetDirectories(path); var fileNameArr = fileNames.Except(_responseFileNames).Except(_errFileNames).ToArray(); - string resDir = OtcAppContext.MapPath(responseDir); + var resDir = OtcAppContext.MapPath(responseDir); if (!Directory.Exists(resDir)) { Directory.CreateDirectory(resDir); } - string tDir = OtcAppContext.MapPath(tempDir); + var tDir = OtcAppContext.MapPath(tempDir); if (!Directory.Exists(tDir)) { Directory.CreateDirectory(tDir); } - string targetName = ""; - string msg = ""; + var targetName = ""; + var msg = ""; foreach (var item in fileNameArr) { targetName = Path.Combine(resDir, Path.GetFileName(item)); var extensionName = Path.GetExtension(targetName); - if (extensionName.ToLower() != ".zip" || File.Exists(targetName)) + if (extensionName.ToLower() != ".zip" || !Regex.IsMatch(targetName, @"OTC_\w{6}_\w{6}_YSP_20\d{6}_\d{4}") || File.Exists(targetName)) { _responseFileNames.Add(item); continue; @@ -513,173 +574,174 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private static void setTimeOutReportResponse() { - using (var db = DbContextFactory.GetYLDbContext()) + using var db = DbContextFactory.GetYLDbContext(); + var time = DateTime.Now.AddMinutes(-10); + var timeOutQuery = db.supervise_report.Where(O => O.ReportReponseStatus == ReportSentStatus.SENDING && O.optDate < time); + foreach (var item in timeOutQuery) { - var time = DateTime.Now.AddMinutes(-10); - var timeOutQuery = db.supervise_report.Where(O => O.ReportReponseStatus == ReportSentStatus.SENDING && O.optDate < time); - foreach (var item in timeOutQuery) - { - item.ReportReponseStatus = ReportSentStatus.ERROR; - item.ReportReponseCode = "-000001"; - item.ReportReponseMessage = "超时"; - } - db.SaveChanges(); + item.ReportReponseStatus = ReportSentStatus.ERROR; + item.ReportReponseCode = "-000001"; + item.ReportReponseMessage = "协会尚未返回结果,等待中..."; } + db.SaveChanges(); } private static void saveReportResponse(string path, string zipPath) { var files = Directory.EnumerateFiles(path); - using (var db = DbContextFactory.GetYLDbContext()) + using var db = DbContextFactory.GetYLDbContext(); + var status = new List(); + var fileTagList = new List(); + foreach (var item in files) { - List status = new List(); - List fileTagList = new List(); - foreach (var item in files) + LogFactory.GetLogger("ListensResponse").Info($"处理文件:{item}"); + var tag = Path.GetFileNameWithoutExtension(item); + var arr = tag.Split('_').ToList(); + if (arr.Count < 6) { - LogFactory.GetLogger("ListensResponse").Info($"处理文件:{item}"); - var tag = Path.GetFileNameWithoutExtension(item); - var arr = tag.Split('_').ToList(); - if (arr.Count < 6) + continue; + } + if (arr.Count == 6) + { + arr.Insert(3, "YSP"); + } + var temp = arr[1]; + arr[1] = arr[2]; + arr[2] = temp; + arr.RemoveAt(arr.Count - 1); + tag = string.Join("_", arr); + var tag2 = string.Join("_", arr) + "_checked"; + fileTagList.Add(tag); + fileTagList.Add(tag2); + LogFactory.GetLogger("ListensResponse").Info($"生成tag:{tag}"); + var reportInfo = db.supervise_report.Where(O => O.FileTag == tag || O.FileTag == tag2).FirstOrDefault(); + if (reportInfo == null) + { + continue; + } + LogFactory.GetLogger("ListensResponse").Info($"找到文件记录:{reportInfo.id}"); + var xml = File.ReadAllText(item); + var model = XmlHelper.Deserialize(xml); + reportInfo.ReportReponseCode = model.Header.RetCode; + reportInfo.ReportReponseMessage = model.Header.RetMsg; + reportInfo.ReportReponseStatus = reportInfo.ReportReponseCode == "000000" && (reportInfo.ReportType != SuperviseReportTypeEnum.SAC || status.All(O => O)) ? ReportSentStatus.SUCCESS : ReportSentStatus.ERROR; + reportInfo.optDate = DateTime.Now; + status.Add(reportInfo.ReportReponseCode == "000000"); + if (reportInfo.ReportType == SuperviseReportTypeEnum.SAC) + { + LogFactory.GetLogger("ListensResponse").Info($"修改压缩文件记录:{reportInfo.id}"); + reportInfo.ReportReponsePath = zipPath; + } + else + { + if (model.Body == null) { continue; } - if (arr.Count == 6) - { - arr.Insert(3, "YSP"); - } - var temp = arr[1]; - arr[1] = arr[2]; - arr[2] = temp; - arr.RemoveAt(arr.Count - 1); - tag = string.Join("_", arr); - fileTagList.Add(tag); - LogFactory.GetLogger("ListensResponse").Info($"生成tag:{tag}"); - var reportInfo = db.supervise_report.Where(O => O.FileTag == tag).FirstOrDefault(); - if (reportInfo == null) - { - continue; - } - LogFactory.GetLogger("ListensResponse").Info($"找到文件记录:{reportInfo.id}"); - var xml = File.ReadAllText(item); - ReportRootModel model = XmlHelper.Deserialize(xml); - reportInfo.ReportReponseCode = model.Header.RetCode; - reportInfo.ReportReponseMessage = model.Header.RetMsg; - reportInfo.ReportReponseStatus = reportInfo.ReportReponseCode == "000000" && (reportInfo.ReportType != SuperviseReportTypeEnum.SAC || status.All(O => O)) ? ReportSentStatus.SUCCESS : ReportSentStatus.ERROR; - reportInfo.optDate = DateTime.Now; - status.Add(reportInfo.ReportReponseCode == "000000"); - if (reportInfo.ReportType == SuperviseReportTypeEnum.SAC) - { - LogFactory.GetLogger("ListensResponse").Info($"修改压缩文件记录:{reportInfo.id}"); - reportInfo.ReportReponsePath = zipPath; - } - else - { - if (model.Body == null) - { - continue; - } - var kingstarViewResponseSqlList = new List(); + var kingstarViewResponseSqlList = new List(); - switch (reportInfo.ReportType) - { - case SuperviseReportTypeEnum.SAC_MasterAgrmt: - setSacNotes(db, model.Body.MasterAgrmt, model.Header); - break; - case SuperviseReportTypeEnum.SAC_MasterAgrmtProduct: - setSacNotes(db, model.Body.MasterAgrmtProduct, model.Header); - break; - case SuperviseReportTypeEnum.SAC_SupAgrmt: - setSacNotes(db, model.Body.SupAgrmt, model.Header); - break; - case SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt: - setSacNotes(db, model.Body.PerformanceGuaranteeAgrmt, model.Header); - break; - case SuperviseReportTypeEnum.SAC_OptionConfirmation: - setSacNotes(db, model.Body.OptionConfirmation, model.Header); - break; - case SuperviseReportTypeEnum.SAC_SwapConfirmation: - setSacNotes(db, model.Body.SwapConfirmation, model.Header); - LogFactory.GetLogger("kingstarViewResponse").Info($"开始业务:SwapConfirmation"); - CreateKingstarViewResponseSql(db, kingstarViewResponseSqlList, model.Body.SwapConfirmation); - LogFactory.GetLogger("kingstarViewResponse").Info($"结束业务:SwapConfirmation"); - break; - case SuperviseReportTypeEnum.SAC_OptionTermination: - model.Body.OptionTermination.ForEach(O => { ((ReportBaseModel)O).BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); - setSacNotes(db, model.Body.OptionTermination, model.Header); - break; - case SuperviseReportTypeEnum.SAC_SwapDurationManagement: - model.Body.SwapDurationManagement.ForEach(O => { ((ReportBaseModel)O).BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); - setSacNotes(db, model.Body.SwapDurationManagement, model.Header); - LogFactory.GetLogger("kingstarViewResponse").Info($"开始业务:SwapDurationManagement"); - CreateKingstarViewResponseSql(db, kingstarViewResponseSqlList, model.Body.SwapDurationManagement); - LogFactory.GetLogger("kingstarViewResponse").Info($"结束业务:SwapDurationManagement"); - break; - case SuperviseReportTypeEnum.SAC_PeriodicReportSAC: - ((ReportBaseModel)model.Body.PeriodicReportSAC).BizID = model.Body.PeriodicReportSAC.BizID; - ((ReportBaseModel)model.Body.PeriodicReportSAC).DurationEventNO = model.Body.PeriodicReportSAC.DurationEventNO; - setSacNotes(db, model.Body.PeriodicReportSAC, model.Header); - break; - case SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII: - ((ReportBaseModel)model.Body.PeriodicReportNAFMII).BizID = model.Body.PeriodicReportNAFMII.BizID; - ((ReportBaseModel)model.Body.PeriodicReportNAFMII).DurationEventNO = model.Body.PeriodicReportNAFMII.DurationEventNO; - setSacNotes(db, model.Body.PeriodicReportNAFMII, model.Header); - break; - case SuperviseReportTypeEnum.SAC_PeriodicReportISDA: - ((ReportBaseModel)model.Body.PeriodicReportISDA).BizID = model.Body.PeriodicReportISDA.BizID; - ((ReportBaseModel)model.Body.PeriodicReportISDA).DurationEventNO = model.Body.PeriodicReportISDA.DurationEventNO; - setSacNotes(db, model.Body.PeriodicReportISDA, model.Header); - break; - case SuperviseReportTypeEnum.SAC_EventReport: - ((ReportBaseModel)model.Body.EventReport).BizID = model.Body.EventReport.BizID; - ((ReportBaseModel)model.Body.EventReport).DurationEventNO = model.Body.EventReport.DurationEventNO; - setSacNotes(db, model.Body.EventReport, model.Header); - break; - case SuperviseReportTypeEnum.SAC_OtherReport: - ((ReportBaseModel)model.Body.OtherReport).BizID = model.Body.OtherReport.BizID; - ((ReportBaseModel)model.Body.OtherReport).DurationEventNO = model.Body.OtherReport.DurationEventNO; - setSacNotes(db, model.Body.OtherReport, model.Header); - break; - case SuperviseReportTypeEnum.SAC_PeriodicReportQuarter: - ((ReportBaseModel)model.Body.PeriodicReportQuarter).BizID = model.Body.PeriodicReportQuarter.BizID; - ((ReportBaseModel)model.Body.PeriodicReportQuarter).DurationEventNO = model.Body.PeriodicReportQuarter.DurationEventNO; - setSacNotes(db, model.Body.PeriodicReportQuarter, model.Header); - break; - case SuperviseReportTypeEnum.SAC_ContractNumberProcess: - ((ReportBaseModel)model.Body.ContractNumberProcess).BizID = model.Body.ContractNumberProcess.BizID; - ((ReportBaseModel)model.Body.ContractNumberProcess).DurationEventNO = model.Body.ContractNumberProcess.DurationEventNO; - setSacNotes(db, model.Body.ContractNumberProcess, model.Header); - break; - case SuperviseReportTypeEnum.SAC_SwapEquityPayment: - model.Body.SwapEquityPayment.ForEach(O => { ((ReportBaseModel)O).BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); - setSacNotes(db, model.Body.SwapEquityPayment, model.Header); - LogFactory.GetLogger("kingstarViewResponse").Info($"开始业务:SwapEquityPayment"); - CreateKingstarViewResponseSql(db, kingstarViewResponseSqlList, model.Body.SwapEquityPayment); - LogFactory.GetLogger("kingstarViewResponse").Info($"结束业务:SwapEquityPayment"); - break; - case SuperviseReportTypeEnum.SAC_ConfirmationAtt: - model.Body.ConfirmationAtt.ForEach(O => { ((ReportBaseModel)O).BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); - setSacNotes(db, model.Body.ConfirmationAtt, model.Header); - //金仕达视图 - LogFactory.GetLogger("kingstarViewResponse").Info($"开始业务:ConfirmationAtt"); - CreateKingstarViewResponseSql(db, kingstarViewResponseSqlList, model.Body.ConfirmationAtt); - LogFactory.GetLogger("kingstarViewResponse").Info($"结束业务:ConfirmationAtt"); - break; - default: - break; - } - if (kingstarViewResponseSqlList.Count > 0) - { KingstarViewResponse(kingstarViewResponseSqlList); } + switch (reportInfo.ReportType) + { + case SuperviseReportTypeEnum.SAC_MasterAgrmt: + setSacNotes(db, model.Body.MasterAgrmt, model.Header); + break; + case SuperviseReportTypeEnum.SAC_MasterAgrmtProduct: + setSacNotes(db, model.Body.MasterAgrmtProduct, model.Header); + break; + case SuperviseReportTypeEnum.SAC_SupAgrmt: + setSacNotes(db, model.Body.SupAgrmt, model.Header); + break; + case SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt: + setSacNotes(db, model.Body.PerformanceGuaranteeAgrmt, model.Header); + break; + case SuperviseReportTypeEnum.SAC_OptionConfirmation: + setSacNotes(db, model.Body.OptionConfirmation, model.Header); + break; + case SuperviseReportTypeEnum.SAC_SwapConfirmation: + setSacNotes(db, model.Body.SwapConfirmation, model.Header); + break; + case SuperviseReportTypeEnum.SAC_OptionTermination: + model.Body.OptionTermination.ForEach(O => { ((ReportBaseModel)O).BizID = O.BizID; O.DurationEventNO = O.DurationEventNO; }); + setSacNotes(db, model.Body.OptionTermination, model.Header); + break; + case SuperviseReportTypeEnum.SAC_SwapDurationManagement: + model.Body.SwapDurationManagement.ForEach(O => { O.BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); + setSacNotes(db, model.Body.SwapDurationManagement, model.Header); + break; + case SuperviseReportTypeEnum.SAC_PeriodicReportSAC: + ((ReportBaseModel)model.Body.PeriodicReportSAC).BizID = model.Body.PeriodicReportSAC.BizID; + model.Body.PeriodicReportSAC.DurationEventNO = model.Body.PeriodicReportSAC.DurationEventNO; + setSacNotes(db, model.Body.PeriodicReportSAC, model.Header); + break; + case SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII: + ((ReportBaseModel)model.Body.PeriodicReportNAFMII).BizID = model.Body.PeriodicReportNAFMII.BizID; + model.Body.PeriodicReportNAFMII.DurationEventNO = model.Body.PeriodicReportNAFMII.DurationEventNO; + setSacNotes(db, model.Body.PeriodicReportNAFMII, model.Header); + break; + case SuperviseReportTypeEnum.SAC_PeriodicReportISDA: + ((ReportBaseModel)model.Body.PeriodicReportISDA).BizID = model.Body.PeriodicReportISDA.BizID; + model.Body.PeriodicReportISDA.DurationEventNO = model.Body.PeriodicReportISDA.DurationEventNO; + setSacNotes(db, model.Body.PeriodicReportISDA, model.Header); + break; + case SuperviseReportTypeEnum.SAC_EventReport: + ((ReportBaseModel)model.Body.EventReport).BizID = model.Body.EventReport.BizID; + model.Body.EventReport.DurationEventNO = model.Body.EventReport.DurationEventNO; + setSacNotes(db, model.Body.EventReport, model.Header); + break; + case SuperviseReportTypeEnum.SAC_OtherReport: + ((ReportBaseModel)model.Body.OtherReport).BizID = model.Body.OtherReport.BizID; + model.Body.OtherReport.DurationEventNO = model.Body.OtherReport.DurationEventNO; + setSacNotes(db, model.Body.OtherReport, model.Header); + break; + case SuperviseReportTypeEnum.SAC_PeriodicReportQuarter: + ((ReportBaseModel)model.Body.PeriodicReportQuarter).BizID = model.Body.PeriodicReportQuarter.BizID; + model.Body.PeriodicReportQuarter.DurationEventNO = model.Body.PeriodicReportQuarter.DurationEventNO; + setSacNotes(db, model.Body.PeriodicReportQuarter, model.Header); + break; + case SuperviseReportTypeEnum.SAC_ContractNumberProcess: + if (model.Body.ContractNumberProcess == null && model.Body.MasterAgrmt != null) + { + model.Body.ContractNumberProcess = new ContractNumberProcessModel(); + model.Body.ContractNumberProcess.BizID = model.Body.MasterAgrmt.First().BizID; + model.Body.ContractNumberProcess.RetMsg = model.Body.MasterAgrmt.First().RetMsg; + model.Body.ContractNumberProcess.RetCode = model.Body.MasterAgrmt.First().RetCode; + model.Body.ContractNumberProcess.ExceID = model.Body.MasterAgrmt.First().ExceID; + } + model.Body.ContractNumberProcess.BizID = model.Body.ContractNumberProcess.BizID; + setSacNotes(db, model.Body.ContractNumberProcess, model.Header); + break; + case SuperviseReportTypeEnum.SAC_SwapEquityPayment: + model.Body.SwapEquityPayment.ForEach(O => { O.BizID = O.BizID; ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; }); + setSacNotes(db, model.Body.SwapEquityPayment, model.Header); + break; + case SuperviseReportTypeEnum.SAC_ConfirmationAtt: + case SuperviseReportTypeEnum.SAC_OptionConfirmationAtt: + model.Body.ConfirmationAtt.ForEach(O => { O.BizID = O.BizID; O.DurationEventNO = O.DurationEventNO; }); + setSacNotes(db, model.Body.ConfirmationAtt, model.Header); + break; + case SuperviseReportTypeEnum.SAC_ValuationInformation: + model.Body.ValuationInformation.ForEach(O => + { + ((ReportBaseModel)O).BizID = O.BizID; + ((ReportBaseModel)O).DurationEventNO = O.DurationEventNO; + }); + setSacNotes(db, model.Body.ValuationInformation, model.Header); + break; + default: + break; } - db.SaveChanges(); + if (kingstarViewResponseSqlList.Count > 0) + { KingstarViewResponse(kingstarViewResponseSqlList); } } + db.SaveChanges(); + } - var subSystemInboxPath = PS.Config.ClientElement.SAC_SubSystemInboxPath; - LogFactory.GetLogger("ListensResponse").Info($"开始x1111subSystemInboxPath:{subSystemInboxPath}"); - LogFactory.GetLogger("ListensResponse").Info($"Path:{path}"); - if (!string.IsNullOrEmpty(subSystemInboxPath)) - { - ResponseSubsystem(db, path, subSystemInboxPath, fileTagList); - } + var subSystemInboxPath = PS.Config.ClientElement.SAC_SubSystemInboxPath; + LogFactory.GetLogger("ListensResponse").Info($"开始subSystemInboxPath:{subSystemInboxPath}"); + LogFactory.GetLogger("ListensResponse").Info($"Path:{path}"); + if (!string.IsNullOrEmpty(subSystemInboxPath)) + { + ResponseSubsystem(db, path, subSystemInboxPath, fileTagList); } } @@ -700,7 +762,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("ListensResponse").Info($"fileTagList:{string.Join(",", fileTagList)}"); var responseRootDir = OtcAppContext.MapPath(responseSubsystemDir); if (!Directory.Exists(responseRootDir)) + { Directory.CreateDirectory(responseRootDir); + } + LogFactory.GetLogger("ListensResponse").Info($"responseRootDir:{responseRootDir}"); var noteList = db.sac_report_notes.Where(O => fileTagList.Contains(O.FileTag) && O.InfoCache.Contains("Subsystem")).Select(O => O.InfoCache).ToArray().Select(O => Regex.Match(O, @"(?<=SubFileTag)[^,]+(?=,)").Value).ToHashSet(); LogFactory.GetLogger("ListensResponse").Info($"noteListCount:{noteList.Count()}"); @@ -726,9 +791,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("ListensResponse").Info($"targetName:{targetName}"); LogFactory.GetLogger("ListensResponse").Info($"fileName:{fileName}"); File.Copy(fileName, targetName); - LogFactory.GetLogger("ListensResponse").Info($"okxxxx"); } - string[] tempFileNames = Directory.GetFiles(resDir); + var tempFileNames = Directory.GetFiles(resDir); var totalFilePath = ""; var groupFileDic = new Dictionary>(); foreach (var fileItem in tempFileNames) @@ -754,7 +818,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var tag = Path.GetFileNameWithoutExtension(fileItem); LogFactory.GetLogger("ListensResponse").Info("fileItem:" + fileItem); LogFactory.GetLogger("ListensResponse").Info("tag.Length" + tag.Length); - if (tag.Length >= 41) smallFileCount++; + if (tag.Length >= 41) + { + smallFileCount++; + } } if (smallFileCount == 0) { @@ -767,9 +834,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("ListensResponse").Info($"smallFileCount!=0"); var newFileName = RenameTotalXmlFileName(resDir, totalFilePath, filetag); UpdateTotalXmlFileNumber(newFileName, filetag); - LogFactory.GetLogger("ListensResponse").Info("yyyyyzzzz"); CreateSubsystemResponse(resDir, subSystemInboxPath, filetag); - LogFactory.GetLogger("ListensResponse").Info("sssz"); } } } @@ -782,7 +847,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var totalTag = Path.GetFileNameWithoutExtension(totalFilePath); var newFileName = Path.Combine(resDir, CovertResponseTag(filetag) + totalTag.Substring(31) + ".xml"); - FileInfo fi = new FileInfo(totalFilePath); + var fi = new FileInfo(totalFilePath); fi.MoveTo(newFileName); //File.Move(totalFilePath, newFileName); @@ -794,10 +859,13 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { var oldFileTag = Path.GetFileNameWithoutExtension(xmlFile);//OTC_123654_000899_YSP_20220714_0007 var newFileName = Path.Combine(resDir, CovertResponseTag(filetag) + oldFileTag.Substring(31) + ".xml"); - FileInfo fi = new FileInfo(xmlFile); + var fi = new FileInfo(xmlFile); fi.MoveTo(newFileName); if (xmlFile != newFileName) + { File.Delete(xmlFile); + } + LogFactory.GetLogger("ListensResponse").Info($"move:{xmlFile} to {newFileName}"); //RenameFile(xmlFile, newFileName); } @@ -816,13 +884,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service arr[2] = temp; var tag = string.Join("_", arr); if (removeYsp) + { tag = tag.Replace("_YSP", ""); + } + return tag; } private static void ClearResDirContent(string resDir) { - string[] fileList = Directory.GetFiles(resDir); + var fileList = Directory.GetFiles(resDir); foreach (var file in fileList) { File.Delete(file); @@ -870,7 +941,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var layerName = "/Root/Body"; var bodyNode = xmldoc.SelectSingleNode(layerName); var bodyChildlist = bodyNode.ChildNodes; - int totalCount = bodyChildlist.Count; + var totalCount = bodyChildlist.Count; var tag = ""; for (var i = 0; i < totalCount; i++) { @@ -904,8 +975,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - var source = ""; - if (!infoCacheDict.TryGetValue("Source", out source) || string.IsNullOrEmpty(source) || source != "Subsystem") + if (!infoCacheDict.TryGetValue("Source", out var source) || string.IsNullOrEmpty(source) || source != "Subsystem") { bodyNode.RemoveChild(bodyChildNode); i--; @@ -913,8 +983,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - var oldExcelId = ""; - if (!infoCacheDict.TryGetValue("ExceID", out oldExcelId) || string.IsNullOrEmpty(oldExcelId)) + if (!infoCacheDict.TryGetValue("ExceID", out var oldExcelId) || string.IsNullOrEmpty(oldExcelId)) { bodyNode.RemoveChild(bodyChildNode); i--; @@ -946,7 +1015,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public static void CreateKingstarViewResponseSql(YLContext db, List kingstarViewResponseList, IEnumerable model) { - string schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; + var schema = PS.Config.ErpElement.KingstarViewTableSchema.IsNullOrWhiteSpace() ? "" : $"\"{PS.Config.ErpElement.KingstarViewTableSchema}\"."; var exceIds = model.Select(O => O.ExceID); LogFactory.GetLogger("kingstarViewResponse").Info($"exceIds:{string.Join(",", exceIds)}"); var dict = db.sac_report_notes.Where(O => exceIds.Contains(O.ExceId)).ToDictionary(K => K.ExceId, V => V); @@ -954,11 +1023,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service foreach (var item in model) { LogFactory.GetLogger("kingstarViewResponse").Info($"开始excelId:{item.ExceID}"); - if (!dict.ContainsKey(item.ExceID)) continue; + if (!dict.ContainsKey(item.ExceID)) + { + continue; + } var note = dict[item.ExceID]; var infoCacheDict = JsonHelper.Deserialize>(note.InfoCache); - if (infoCacheDict["Source"] != "KingstarView") continue; + if (infoCacheDict["Source"] != "KingstarView") + { + continue; + } var curDate = DateTime.Now.ToString("yyyy-MM-dd 00:00:00"); var batchDate = DateTime.Now.ToString("yyyyMMdd"); @@ -982,7 +1057,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } - infoCacheDict.TryGetValue("Tag", out string bizzID); + infoCacheDict.TryGetValue("Tag", out var bizzID); var rptID = item.BizID; var sqlMapping = $"INSERT INTO {schema}TRANS_RPT_MAPPING(BIZZ_ID,RPT_ID,BIZZ_TYPE,CREATED_DATETIME,PUSH_TIME,EVENT_DATE,EVENT_NO)VALUES('{bizzID}','{rptID}','{bizzType}',to_date('{curDate}', 'yyyy-mm-dd hh24:mi:ss'),to_date('{curTime}', 'yyyy-mm-dd hh24:mi:ss'),to_date('{curDate}', 'yyyy-mm-dd hh24:mi:ss'),'{eventNo}')"; LogFactory.GetLogger("kingstarViewResponse").Info($"sqlMapping:{sqlMapping}"); @@ -1014,7 +1089,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { var exceIds = model.Select(O => O.ExceID); var dict = db.sac_report_notes.Where(O => exceIds.Contains(O.ExceId)).ToDictionary(K => K.ExceId, V => V); - List sendFileId = new List(); + var sendFileId = new List(); foreach (var item in model) { if (!dict.ContainsKey(item.ExceID)) @@ -1031,17 +1106,19 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service LogFactory.GetLogger("ListensResponse").Info($"更新文件明细:{note.ToJson()}"); if (note.ReportResponse) { - Dictionary infoCacheDict = JsonHelper.Deserialize>(note.InfoCache); - infoCacheDict["DurationEventNO"] = item.DurationEventNO ?? ""; - note.InfoCache = infoCacheDict.ToJson(); + var infoCacheDict = JsonHelper.Deserialize>(note.InfoCache); + if (infoCacheDict != null) + { + infoCacheDict["DurationEventNO"] = item.DurationEventNO ?? ""; + note.InfoCache = infoCacheDict.ToJson(); + } if (note.ReportType == SuperviseReportTypeEnum.SAC_MasterAgrmt || note.ReportType == SuperviseReportTypeEnum.SAC_MasterAgrmtProduct || note.ReportType == SuperviseReportTypeEnum.SAC_SupAgrmt || note.ReportType == SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt) { - int dataId = 0; LogFactory.GetLogger("ListensResponse").Info($"客户协议相关明细:{note.DataId}"); - if (int.TryParse(note.DataId, out dataId)) + if (int.TryParse(note.DataId, out var dataId)) { sendFileId.Add(dataId); } @@ -1052,7 +1129,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { EditTradeDueDate(db, note); - }//如果是废止报告,要把该报告对应的所有新增和修改的报告状态修改为无效 + } + else if (note.ReportType == SuperviseReportTypeEnum.SAC_ContractNumberProcess) + { + var obj = JsonHelper.Deserialize(note.BizId); + EditContractNumber(db, obj, out var protocolNumberDict); + EditProtocolNumberSentStatus(protocolNumberDict); + } + //如果是废止报告,要把该报告对应的所有新增和修改的报告状态修改为无效 if (note.InfoTag.EndsWith("_D")) { ValidSacNote(db, note); @@ -1067,6 +1151,253 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } + /// + /// 修改协议文件报送状态 + /// + /// + private static void EditProtocolNumberSentStatus(Dictionary> protocolNumberDict) + { + if (protocolNumberDict.Count < 0) + { + var clientDb = DbContextFactory.GetClientDbContext(OptUserInfo.SystemUser); + if (protocolNumberDict.ContainsKey(SuperviseReportTypeEnum.SAC_MasterAgrmt)) + { + var list = protocolNumberDict[SuperviseReportTypeEnum.SAC_MasterAgrmt]; + var changeList = clientDb.client_file.Where(O => O.HasSent && O.FileTypeName == ConsGlobal.ClientFileType.MainProtocol && list.Contains(O.ProtocolNumber)); + foreach (var changeObj in changeList) + { + changeObj.HasSent = false; + } + } + if (protocolNumberDict.ContainsKey(SuperviseReportTypeEnum.SAC_SupAgrmt)) + { + var list = protocolNumberDict[SuperviseReportTypeEnum.SAC_SupAgrmt]; + var changeList = clientDb.client_file.Where(O => O.HasSent && O.FileTypeName == ConsGlobal.ClientFileType.EnhanceProtocol && list.Contains(O.ProtocolNumber)); + foreach (var changeObj in changeList) + { + changeObj.HasSent = false; + } + } + clientDb.SaveChanges(); + } + } + + /// + /// 修改双方约定编号 + /// + /// + /// + /// + public static void EditContractNumber(YLContext db, ContractNumberProcessModel obj, out Dictionary> protocolNumberDict) + { + var dict = new Dictionary(); + obj.OptionConfirmationTuple.ForEach(O => + { + if (O.ConfirmationID.IsNullOrWhiteSpace() || O.ConfirmationNo.IsNullOrWhiteSpace()) + { + return; + } + dict[O.ConfirmationID] = O.ConfirmationNo; + }); + obj.SwapConfirmationTuple.ForEach(O => + { + if (O.ConfirmationID.IsNullOrWhiteSpace() || O.ConfirmationNo.IsNullOrWhiteSpace()) + { + return; + } + dict[O.ConfirmationID] = O.ConfirmationNo; + }); + obj.MasterAgrmtTuple.ForEach(O => + { + if (O.MasterAgrmtID.IsNullOrWhiteSpace() || O.MasterAgrmtNo.IsNullOrWhiteSpace()) + { + return; + } + dict[O.MasterAgrmtID] = O.MasterAgrmtNo; + }); + obj.SupAgrmtTuple.ForEach(O => + { + if (O.SupAgrmtID.IsNullOrWhiteSpace() || O.SupAgrmtNo.IsNullOrWhiteSpace()) + { + return; + } + dict[O.SupAgrmtID] = O.SupAgrmtNo; + }); + EditContractNumber(db, dict, out protocolNumberDict); + } + + private static void EditContractNumber(YLContext db, Dictionary dict, out Dictionary> protocolNumberDict) + { + protocolNumberDict = new Dictionary>(); + var infoTagList = new HashSet(); + var keys = dict.Keys; + var objs = db.sac_report_notes.Where(O => O.IsValid && keys.Contains(O.BizId)); + var serviceDict = new Dictionary(); + foreach (var item in objs) + { + var reportType = item.ReportType; + if (!serviceDict.ContainsKey(reportType)) + { + serviceDict[reportType] = ReportBaseService.ReportFactory(OptUserInfo.SystemUser, reportType); + } + var newCode = dict[item.BizId]; + item.InfoTag = serviceDict[reportType].ChangeCodeOfInfoTag(item.InfoTag, newCode, out var originalCode); + if (reportType == SuperviseReportTypeEnum.SAC_MasterAgrmt + || reportType == SuperviseReportTypeEnum.SAC_SupAgrmt) + { + if (!protocolNumberDict.ContainsKey(reportType)) + { + protocolNumberDict[reportType] = new List(); + } + protocolNumberDict[reportType].Add(originalCode); + } + infoTagList.Add(item.InfoTag); + } + var tempList = DbContextFactory.GetYLDbContext().sac_report_notes.Where(O => infoTagList.Contains(O.InfoTag)); + if (tempList.Any()) + { + throw new ServiceException("修改后的InfoTag存在重复"); + } + } + + public static void EditContractNumber(Stream inputStream) + { + var serviceDict = new Dictionary(); + var colConfig = new DataColumnModel[3]; + colConfig[0] = new DataColumnModel("数据类型", nameof(InnerContractNumberModel.NumberType)); + colConfig[1] = new DataColumnModel("原双方约定", nameof(InnerContractNumberModel.OriginalCode)); + colConfig[2] = new DataColumnModel("新双方约定", nameof(InnerContractNumberModel.NewCode)); + var dict = new ExcelHelper().ExcelToListT(colConfig, inputStream); + if (!dict.ContainsKey("Sheet1")) + { + throw new ServiceException("模板错误"); + } + var db = DbContextFactory.GetYLDbContext(); + var temp_List = dict["Sheet1"]; + checkContractNumber(temp_List); + + var list = new List(); + foreach (var item in temp_List) + { + if (item.NumberType.IsNullOrWhiteSpace() + || item.OriginalCode.IsNullOrWhiteSpace() + || item.NewCode.IsNullOrWhiteSpace()) + { + break; + } + list.Add(item); + var reportType = SuperviseReportTypeEnum.SAC; + switch (item.NumberType) + { + case "主协议编号": + reportType = SuperviseReportTypeEnum.SAC_MasterAgrmt; + break; + case "补充协议编号": + reportType = SuperviseReportTypeEnum.SAC_SupAgrmt; + break; + case "代签产品名称": + reportType = SuperviseReportTypeEnum.SAC_MasterAgrmtProduct; + break; + case "期权交易确认书编号": + reportType = SuperviseReportTypeEnum.SAC_OptionConfirmation; + break; + case "互换交易确认书编号": + reportType = SuperviseReportTypeEnum.SAC_SwapConfirmation; + break; + default: + continue; + } + var originCode = $"_{item.OriginalCode.Replace("_", "-")}_"; + var bizDict = + db.sac_report_notes + .Where(O => + O.ReportType == reportType + && O.IsValid + && O.ReportResponse + && O.InfoTag.Contains(originCode)) + .ToArray().GroupBy(O => O.BizId) + .ToDictionary(K => K.Key, V => V.FirstOrDefault().InfoTag); + foreach (var bizId in bizDict) + { + if ((reportType == SuperviseReportTypeEnum.SAC_SupAgrmt + || reportType == SuperviseReportTypeEnum.SAC_MasterAgrmtProduct) + && !Regex.IsMatch(bizId.Value, originCode + @"\w$")) + { + continue; + } + item.BizId = bizId.Key;//同一个编号只会有一条记录,不应该存在多条; + break; + } + } + var errArr = list.Where(O => O.BizId.IsNullOrWhiteSpace()).Select(O => O.OriginalCode); + if (errArr.Any()) + { + throw new ServiceException($"下列原编号未找到对应记录:\r\n{string.Join(",", errArr)}\r\n请确认后重新操作"); + } + var bizIdList = list.ToDictionary(K => K.BizId, V => V.NewCode); + EditContractNumber(db, bizIdList, out var protocolNumberDict); + EditProtocolNumberSentStatus(protocolNumberDict); + db.SaveChanges(); + } + + /// + /// 检查传入的双方约定编号是否重复 + /// + /// + /// + private static void checkContractNumber(List temp_List) + { + // 检查重复 数据类型 [0]原编号;[1]新编号; + var dict = new Dictionary[]>(); + var originCode = new List(); + var targetCode = new List(); + foreach (var item in temp_List) + { + if (item.NumberType.IsNullOrWhiteSpace() + || item.OriginalCode.IsNullOrWhiteSpace() + || item.NewCode.IsNullOrWhiteSpace()) + { + break; + } + var numberType = item.NumberType; + if (item.NumberType == "期权交易确认书编号") + { + numberType = "确认书编号"; + } + else if (item.NumberType == "互换交易确认书编号") + { + numberType = "确认书编号"; + } + if (!dict.ContainsKey(numberType)) + { + dict[numberType] = new HashSet[2]; + dict[numberType][0] = new HashSet(); + dict[numberType][1] = new HashSet(); + } + if (!dict[numberType][0].Add(item.OriginalCode)) + { + originCode.Add(item.OriginalCode); + } + if (!dict[numberType][1].Add(item.NewCode)) + { + targetCode.Add(item.NewCode); + } + } + var sb = new StringBuilder(); + if (originCode.Any()) + { + sb.AppendLine($"原编号存在重复:\r\n{string.Join(",", originCode)}"); + } + if (targetCode.Any()) + { + sb.AppendLine($"新编号存在重复:\r\n{string.Join(",", targetCode)}"); + } + if (sb.Length > 0) + { + throw new ServiceException(sb.ToString()); + } + } + /// /// 修改交易报告记录中的到期日 /// @@ -1104,8 +1435,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private static void ValidSacNote(YLContext db, SACReportNotes note) { - Dictionary infoCacheDict = JsonHelper.Deserialize>(note.InfoCache); - if (!infoCacheDict.TryGetValue("Tag", out string tag)) + var infoCacheDict = JsonHelper.Deserialize>(note.InfoCache); + if (!infoCacheDict.TryGetValue("Tag", out var tag)) { tag = " "; } @@ -1122,14 +1453,29 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service || O.ReportType == SuperviseReportTypeEnum.SAC_SwapDurationManagement || O.ReportType == SuperviseReportTypeEnum.SAC_SwapEquityPayment || O.InfoCache.Contains(tag)) && - O.InfoTag.Contains(infoTag)).ToArray(); + O.InfoTag.Contains(infoTag)).ToList(); + if (note.ReportType == SuperviseReportTypeEnum.SAC_SwapDurationManagement) + { + if (!infoCacheDict.TryGetValue("DurationEventNO", out string durationeventno)) + { + durationeventno = " "; + } + durationeventno = $"\"DurationEventNO\":\"{durationeventno}\""; + infoTag = $"A1016_{note.InfoTag.Split('_')[1]}_"; + arr.AddRange(db.sac_report_notes + .Where(O => + O.IsValid && + O.ReportType == SuperviseReportTypeEnum.SAC_SwapEquityPayment && + O.InfoTag.StartsWith(infoTag) && + O.InfoCache.Contains(durationeventno)).ToList()); + } foreach (var item1 in arr) { if (!note.InfoTag.Contains("_展期_") && (item1.ReportType == SuperviseReportTypeEnum.SAC_OptionTermination || item1.ReportType == SuperviseReportTypeEnum.SAC_SwapDurationManagement)) { - Dictionary dict2 = JsonHelper.Deserialize>(item1.InfoCache); + var dict2 = JsonHelper.Deserialize>(item1.InfoCache); if (!infoCacheDict.ContainsKey("ValueDate") || !dict2.ContainsKey("ValueDate") || infoCacheDict["ValueDate"] != dict2["ValueDate"]) { @@ -1139,6 +1485,26 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service item1.IsValid = false; } } + public class InnerContractNumberModel + { + /// + /// 编号类型 + /// + public string NumberType { get; set; } + /// + /// 原编号 + /// + public string OriginalCode { get; set; } + /// + /// 新编号 + /// + public string NewCode { get; set; } + /// + /// BizId + /// 协会唯一编号 + /// + public string BizId { get; set; } + } #endregion @@ -1164,22 +1530,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// public ReturnInfo QueryReportInfo(DateTime reportDate) { - DateTime lastMonthEnd = reportDate.AddDays(-reportDate.Day); + var lastMonthEnd = reportDate.AddDays(-reportDate.Day); var superviseReport = DbContext.supervise_report .Where(O => O.ReportDate <= reportDate) .OrderByDescending(O => O.ReportDate) .ThenByDescending(O => O.optDate) .FirstOrDefault(); - if (PS.Config.Company == Configuration.CompanyEnum.中金 && superviseReport == null) + + var info = new ReportInfo { - superviseReport = DbContext.supervise_report - .OrderByDescending(O => O.ReportDate) - .ThenByDescending(O => O.optDate) - .FirstOrDefault(); - } - ReportInfo info = new ReportInfo(); - info.ReportDate = reportDate; + ReportDate = reportDate + }; if (superviseReport != null) { info.SenderCode = superviseReport.SenderCode; @@ -1206,31 +1568,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public List> QueryDetails(int id) { var tag = DbContext.supervise_report.Where(O => O.id == id).Select(O => O.FileTag).FirstOrDefault(); - tag = (tag ?? "").Replace("YSP_", ""); - var reports = (from report in DbContext.supervise_report.Where(O => O.FileTag.StartsWith(tag)) - join notes in DbContext.sac_report_notes on report.FileTag equals notes.FileTag + tag = (tag ?? "").Replace("YSP_", "").Replace("_checked", ""); + var reportList_temp = DbContext.supervise_report.Where(O => O.FileTag.StartsWith(tag)).ToList(); + var fileTagList_temp = reportList_temp.Select(O => O.FileTag).ToList(); + var noteList_temp = DbContext.sac_report_notes.Where(O => fileTagList_temp.Contains(O.FileTag)).ToList(); + + var reports = (from report in reportList_temp + join notes in noteList_temp on report.FileTag equals notes.FileTag select new { report, notes }).ToArray().GroupBy(O => O.report.FileTag) .ToDictionary(K => K.First().report, V => V.Select(O => O.notes).Distinct().ToList()); - List> result = new List>(); + var result = new List>(); foreach (var item in reports) { - Dictionary dict = new Dictionary(); - dict["FileTag"] = item.Key.FileTag; - dict["FileType"] = EnumHelper.GetDescriptionByName(item.Key.ReportType); - dict["ExceId"] = "-"; - dict["BizID"] = "-"; - dict["RetCode"] = item.Key.ReportReponseCode; - dict["RetMsg"] = item.Key.ReportReponseMessage; + var dict = new Dictionary + { + ["FileTag"] = item.Key.FileTag, + ["FileType"] = EnumHelper.GetDescriptionByName(item.Key.ReportType), + ["ExceId"] = "-", + ["BizID"] = "-", + ["RetCode"] = item.Key.ReportReponseCode, + ["RetMsg"] = item.Key.ReportReponseMessage + }; result.Add(dict); foreach (var note in item.Value) { - dict = new Dictionary(); - dict["FileTag"] = note.InfoCache; - dict["FileType"] = "-"; - dict["ExceId"] = note.ExceId; - dict["BizID"] = note.BizId; - dict["RetCode"] = note.RetCode; - dict["RetMsg"] = note.RetMsg; + dict = new Dictionary + { + ["FileTag"] = note.InfoCache, + ["FileType"] = "-", + ["ExceId"] = note.ExceId, + ["BizID"] = note.BizId, + ["RetCode"] = note.RetCode, + ["RetMsg"] = note.RetMsg + }; result.Add(dict); } } @@ -1242,12 +1612,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// /// /// - public Dictionary> QueryReportDesc(List pGroups = null) + public Dictionary> QueryReportDesc(List? pGroups = null) { - if (pGroups == null) - { - pGroups = new List(); - } + pGroups ??= new List(); if (pGroups.Count == 0) { pGroups.Add(DBModels.Consts.ConsAppConfig.ReportDescOption); @@ -1271,7 +1638,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// public int SaveReportDesc(Dictionary> obj) { - List pGroups = new List { + var pGroups = new List { DBModels.Consts.ConsAppConfig.ReportDescOption, DBModels.Consts.ConsAppConfig.ReportDescSwap }; @@ -1304,343 +1671,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// public List GetSupervisePreview(string fileTag, string fileType) { -#if DEBUG - - { - //var requestPath = OtcAppContext.MapPath("/App_Docs/Download/Report"); - //var ds = Directory.GetFiles(requestPath, "*.zip"); - //foreach (var item in ds) - //{ - // var filename = Path.GetFileNameWithoutExtension(item); - // string[] farr = filename.Split('_'); - // var datetime = DateTime.ParseExact(farr[3], "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture); - // var pathStr = ZipHelper.unZipFile(item, Path.GetDirectoryName(item), out string msg); - // if (msg != "解压失败") - // { - // bool status = false; - // var fs = Directory.GetFiles(pathStr, "*.xml"); - // SuperviseReport dbreport = null; - // List list = new List(); - // foreach (var fname in fs) - // { - // var xml = File.ReadAllText(fname); - // var obj = XmlHelper.Deserialize(xml); - // var filetag = Path.GetFileNameWithoutExtension(fname); - // var reportType = SuperviseReportTypeEnum.SAC; - // farr = filetag.Split('_'); - // var dataFlag = (DataFlagsEnum)Enum.Parse(typeof(DataFlagsEnum), farr[5]); - // if ((int)dataFlag >= 4 && (int)dataFlag <= 7) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag + 1; - // } - // else if ((int)dataFlag == 8) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag - 4; - // } - // else if ((int)dataFlag >= 9 && (int)dataFlag <= 10) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag + 3; - // } - // else if ((int)dataFlag >= 11 && (int)dataFlag <= 13) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag - 2; - // } - // else - // { - // reportType = (SuperviseReportTypeEnum)dataFlag; - // } - - // List modeList = null; - // switch (reportType) - // { - // case SuperviseReportTypeEnum.SAC_MasterAgrmt: - // modeList = obj.Body.MasterAgrmt.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_MasterAgrmtProduct: - // modeList = obj.Body.MasterAgrmtProduct.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SupAgrmt: - // modeList = obj.Body.SupAgrmt.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt: - // modeList = obj.Body.PerformanceGuaranteeAgrmt.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_OptionConfirmation: - // modeList = obj.Body.OptionConfirmation.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SwapConfirmation: - // modeList = obj.Body.SwapConfirmation.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_OptionTermination: - // modeList = obj.Body.OptionTermination.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SwapTermination: - // modeList = obj.Body.SwapTermination.Cast().ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportSAC: - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportSAC }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII: - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportNAFMII }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportISDA: - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportISDA }; - // break; - // case SuperviseReportTypeEnum.SAC_EventReport: - // modeList = new List() { (ReportBaseModel)obj.Body.EventReport }; - // break; - // case SuperviseReportTypeEnum.SAC_OtherReport: - // modeList = new List() { (ReportBaseModel)obj.Body.OtherReport }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportQuarter: - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportQuarter }; - // break; - // case SuperviseReportTypeEnum.SAC_ContractNumberProcess: - // modeList = new List() { (ReportBaseModel)obj.Body.ContractNumberProcess }; - // break; - // default: - // break; - // } - // foreach (var mitem in modeList) - // { - // if (string.IsNullOrEmpty(mitem.ExceID)) - // { - // status = false; - // continue; - // } - // status = true; - // var notes = DbContext.sac_report_notes.Where(O => O.ExceId == mitem.ExceID).FirstOrDefault(); - // if (notes == null) - // { - // var dbnotes = new SACReportNotes() - // { - // FileTag = filetag, - // ReportType = reportType, - // InfoTag = "", - // ReportDate = datetime, - // ExceId = mitem.ExceID ?? "", - // BizId = "", - // changeStatus = false, - // InfoCache = "", - // ReportResponse = false, - // RetCode = "", - // RetMsg = "", - // DataId = "", - // IsValid = true, - // CreateTime = DateTime.Now, - // OptTime = DateTime.Now - // }; - // DbContext.sac_report_notes.Add(dbnotes); - // } - // } - // if (status) - // { - // dbreport = DbContext.supervise_report.Where(O => O.FileTag == fname).FirstOrDefault(); - // if (dbreport == null) - // { - // var dbre = new SuperviseReport() - // { - // ReportType = reportType, - // ReportDate = datetime, - // SenderCode = farr[1], - // ReceiverCode = farr[2], - // LastMonthCash = 0, - // LatestMonthCash = 0, - // LatestNetAssets = 0, - // EventReportStatus = 0, - // OtherReportStatus = 0, - // FileTag = filetag, - // FilePath = "", - // ReportReponseStatus = ReportSentStatus.SENDING, - // ReportReponseCode = "", - // ReportReponseMessage = "", - // ReportReponsePath = "", - // optDate = DateTime.Now, - // optUserId = UserId - // }; - // list.Add(dbre); - // } - // } - // } - // if (status) - // { - // dbreport = DbContext.supervise_report.Where(O => O.FileTag == item).FirstOrDefault(); - // if (dbreport == null) - // { - // var dbre = new SuperviseReport() - // { - // ReportType = SuperviseReportTypeEnum.SAC, - // ReportDate = datetime, - // SenderCode = farr[1], - // ReceiverCode = farr[2], - // LastMonthCash = 0, - // LatestMonthCash = 0, - // LatestNetAssets = 0, - // EventReportStatus = 0, - // OtherReportStatus = 0, - // FileTag = filename, - // FilePath = "/App_Docs/Download/Report/" + Path.GetFileName(item), - // ReportReponseStatus = ReportSentStatus.SENDING, - // ReportReponseCode = "", - // ReportReponseMessage = "", - // ReportReponsePath = "", - // optDate = DateTime.Now, - // optUserId = UserId - // }; - // list.Add(dbre); - // DbContext.supervise_report.AddRange(list); - // DbContext.SaveChanges(); - // list.Clear(); - // } - // } - // } - //} - } - { - //var requestPath = OtcAppContext.MapPath("/App_Docs/Download/ReportResponse"); - //var ds = Directory.GetFiles(requestPath, "*.zip"); - //foreach (var item in ds) - //{ - // var filename = Path.GetFileNameWithoutExtension(item); - // string[] farr = filename.Split('_'); - // string temp = farr[1]; - // farr[1] = farr[2]; - // farr[2] = temp; - // filename = string.Join("_", farr); - // var datetime = DateTime.ParseExact(farr[3], "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture); - // var pathStr = ZipHelper.unZipFile(item, Path.GetDirectoryName(item), out string msg); - // if (msg != "解压失败") - // { - // var fs = Directory.GetFiles(pathStr, "*.xml"); - // SuperviseReport dbreport = null; - - // foreach (var fname in fs) - // { - // var filetag = Path.GetFileNameWithoutExtension(fname); - // farr = filetag.Split('_'); - // temp = farr[1]; - // farr[1] = farr[2]; - // farr[2] = temp; - // filetag = string.Join("_", farr).Replace("_R", ""); - - // var xml = File.ReadAllText(fname); - // var obj = XmlHelper.Deserialize(xml); - // if (obj.Header.RetCode == "000000") - // { - // var reportType = SuperviseReportTypeEnum.SAC; - // if (farr[5] != "R") - // { - // var dataFlag = (DataFlagsEnum)Enum.Parse(typeof(DataFlagsEnum), farr[5]); - // if ((int)dataFlag >= 4 && (int)dataFlag <= 7) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag + 1; - // } - // else if ((int)dataFlag == 8) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag - 4; - // } - // else if ((int)dataFlag >= 9 && (int)dataFlag <= 10) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag + 3; - // } - // else if ((int)dataFlag >= 11 && (int)dataFlag <= 13) - // { - // reportType = (SuperviseReportTypeEnum)dataFlag - 2; - // } - // else - // { - // reportType = (SuperviseReportTypeEnum)dataFlag; - // } - // List modeList = null; - // switch (reportType) - // { - // case SuperviseReportTypeEnum.SAC_MasterAgrmt: - // modeList = obj.Body.MasterAgrmt.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_MasterAgrmtProduct: - // modeList = obj.Body.MasterAgrmtProduct.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SupAgrmt: - // modeList = obj.Body.SupAgrmt.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_PerformanceGuaranteeAgrmt: - // modeList = obj.Body.PerformanceGuaranteeAgrmt.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_OptionConfirmation: - // modeList = obj.Body.OptionConfirmation.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SwapConfirmation: - // modeList = obj.Body.SwapConfirmation.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_OptionTermination: - // modeList = obj.Body.OptionTermination.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_SwapTermination: - // modeList = obj.Body.SwapTermination.Select(O => { var tt = ((ReportBaseModel)O); tt.BizID = O.BizID; return tt; }).ToList(); - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportSAC: - // ((ReportBaseModel)obj.Body.PeriodicReportSAC).BizID = obj.Body.PeriodicReportSAC.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportSAC }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportNAFMII: - // ((ReportBaseModel)obj.Body.PeriodicReportNAFMII).BizID = obj.Body.PeriodicReportNAFMII.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportNAFMII }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportISDA: - // ((ReportBaseModel)obj.Body.PeriodicReportISDA).BizID = obj.Body.PeriodicReportISDA.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportISDA }; - // break; - // case SuperviseReportTypeEnum.SAC_EventReport: - // ((ReportBaseModel)obj.Body.EventReport).BizID = obj.Body.EventReport.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.EventReport }; - // break; - // case SuperviseReportTypeEnum.SAC_OtherReport: - // ((ReportBaseModel)obj.Body.OtherReport).BizID = obj.Body.OtherReport.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.OtherReport }; - // break; - // case SuperviseReportTypeEnum.SAC_PeriodicReportQuarter: - // ((ReportBaseModel)obj.Body.PeriodicReportQuarter).BizID = obj.Body.PeriodicReportQuarter.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.PeriodicReportQuarter }; - // break; - // case SuperviseReportTypeEnum.SAC_ContractNumberProcess: - // ((ReportBaseModel)obj.Body.ContractNumberProcess).BizID = obj.Body.ContractNumberProcess.BizID; - // modeList = new List() { (ReportBaseModel)obj.Body.ContractNumberProcess }; - // break; - // default: - // break; - // } - // foreach (var mitem in modeList) - // { - // var notes = DbContext.sac_report_notes.Where(O => O.ExceId == mitem.ExceID).FirstOrDefault(); - // if (notes == null) - // { - // continue; - // } - // notes.BizId = mitem.BizID; - // notes.ReportResponse = mitem.RetCode == "000000"; - // notes.RetCode = mitem.RetCode; - // notes.RetMsg = mitem.RetMsg; - // }; - // } - // } - // dbreport = DbContext.supervise_report.Where(O => O.FileTag == filetag).FirstOrDefault(); - // if (dbreport != null) - // { - // dbreport.ReportReponseStatus = obj.Header.RetCode == "000000" ? ReportSentStatus.SUCCESS : ReportSentStatus.ERROR; - // dbreport.ReportReponseCode = obj.Header.RetCode; - // dbreport.ReportReponseMessage = obj.Header.RetMsg; - // dbreport.ReportReponsePath = obj.Header.BusiDataType == DataFlagsEnum.NONE ? "/App_Docs/Download/Report/" + Path.GetFileName(item) : ""; - // } - // } - // } - // DbContext.SaveChanges(); - //} - } - -#endif - - List result = new List(); - string[] arr = fileTag.Split('_');//OTC_151089_000899_20210104_0002_A1008_A + var result = new List(); + var arr = fileTag.Split('_');//OTC_151089_000899_20210104_0002_A1008_A var rootPath = OtcAppContext.MapPath("/App_Docs/Download/"); var pathName = string.Empty; var xmlPath = string.Empty; @@ -1652,6 +1684,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service rootPath = Path.Combine(rootPath, "Report");//zip文件目录 zipPath = Path.Combine(rootPath, pathName + ".zip");//zip文件路径 if (!File.Exists(zipPath)) + { + pathName = $"{arr[0]}_{arr[1]}_{arr[2]}_YSP_{arr[3]}_{arr[4]}_checked"; //目录名 + zipPath = Path.Combine(rootPath, pathName + ".zip"); //zip文件路径 + } + if (!File.Exists(zipPath)) { pathName = $"{arr[0]}_{arr[1]}_{arr[2]}_{arr[3]}_{arr[4]}";//目录名 zipPath = Path.Combine(rootPath, pathName + ".zip");//zip文件路径 @@ -1683,7 +1720,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service if (!Directory.Exists(pathName)) { Directory.CreateDirectory(pathName); - ZipHelper.unZipFile(zipPath, rootPath, out string msg); + ZipHelper.unZipFile(zipPath, rootPath, out var msg); if (msg.StartsWith("解压失败")) { Directory.Delete(pathName, true); @@ -1691,10 +1728,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service throw new ServiceException(msg); } } - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(xmlPath); var node = doc.GetElementsByTagName("Root")[0]; - SacInfo info = new SacInfo(node.Name, ""); + var info = new SacInfo(node.Name, ""); ReadXmlNode(node, info); info.formatFieldDescription(); result.Add(info); @@ -1717,7 +1754,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private void ReadXmlNode(XmlNode node, SacInfo sacInfo) { - if ((node.HasChildNodes && node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text)) + if (node.HasChildNodes && node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == XmlNodeType.Text) { sacInfo.FieldValue = node.InnerText; } @@ -1733,5 +1770,56 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } #endregion + + #region 导出 + /// + /// 导出 + /// + /// + /// + /// + public string ExportDetailsV2(int id, string fileTag, string path) + { + var reportHelper = new ReportInfoHelper(); + try + { + if (!reportHelper.Init(id, fileTag) || !reportHelper.SaveToZipFile(path)) + { + throw new ServiceException(reportHelper.ErrorMsg); + } + } + catch (Exception ex) + { + LogFactory.GetLogger("ExportDetails").Error(ex); + throw new ServiceException(ex.Message); + } + return path; + } + + #endregion + + #region 生成待重新上传的报送文件压缩包 + + private string GenerateUploadZipFile(ReportResponse res, string savePath) + { + if (res is null) + { + throw new ArgumentNullException(nameof(res)); + } + + if (string.IsNullOrWhiteSpace(savePath)) + { + throw new ArgumentException($"“{nameof(savePath)}”不能为 null 或空白。", nameof(savePath)); + } + + var reportHelper = new ReportInfoHelper(); + if (!reportHelper.Init(res) || !reportHelper.SaveToZipFile(savePath)) + { + throw new ServiceException(reportHelper.ErrorMsg); + } + return savePath; + } + + #endregion } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSupAgrmtService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSupAgrmtService.cs index 5bc40b14..ee214f6e 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSupAgrmtService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSupAgrmtService.cs @@ -19,158 +19,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1003; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_SupAgrmt; - List noteList = new List(); - private List _cacheCodeList = new List(); + + readonly List noteList = new(); + private readonly List _cacheCodeList = new(); protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetSupAgrmtModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - LogFactory.GetLogger("GenerateBody").Info($"System:1"); - try - { - - - using (var baseDb = DbContextFactory.GetClientDbContext(null)) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var fileObjList = (from c in baseDb.client - join cf in baseDb.client_file - on c.id equals cf.ClientId - where c.ProcessStatus == "已开户" && cf.HasSent == false && cf.IsValid && - cf.FileTypeName == ConsGlobal.ClientFileType.EnhanceProtocol && cf.OptState == _operationType && - ((c.ProcessOptDate >= _reqInfo.ReportDate && c.ProcessOptDate < nextDate && cf.OptDate < nextDate) ||//如果这一天开户,则把这一天之前(含这一天)的所有文件都报送了 - (cf.OptDate >= _reqInfo.ReportDate && cf.OptDate < nextDate && c.ProcessOptDate < _reqInfo.ReportDate))//如果这一天不是开户日期,则只在报送日期大于开户日期时,报送当日修改的文件 - && cf.ApprovalOrder < 1 - select new - { - cf.id, - cf.OptState, - cf.ProtocolNumber, - cf.MainProtocolNumber, - cf.SignDate, - cf.FilePath, - cf.FileName, - cf.FileDesc, - }).ToArray(); - var cacheKey = $"{BusiDataType}"; - foreach (var item in fileObjList) - { - var info = new SupAgrmtModel(); - info.MasterAgrmtNo = item.MainProtocolNumber; - info.OperationType = item.OptState; - info.SupAgrmtNo = item.ProtocolNumber; - info.SigningDate = item.SignDate?.ToString("yyyy-MM-dd"); - info.SupAgrmtType = ReportTypeMap[item.OptState == OptFlagsEnum.A ? "首次" : "变更"]; - info.SupAgrmtRemark = item.FileDesc; - info.SupAgrmtAttTuple = new List(); - var tuple = new SupAgrmtAttModel(); - tuple.SupAgrmtAtt = item.FileName; - var cacheValue = info.MasterAgrmtNo + "_" + info.SupAgrmtNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - info.SupAgrmtAttTuple.Add(tuple); - - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{info.SupAgrmtNo}\",\"Source\":\"System\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.SupAgrmtID = note.BizId; - } - info.ExceID = base.formatExceID(); - if (!ReportStatus.CheckFileLength(item.FilePath)) - { - break; - } - else - { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - } - dataList.Add(info); - fileList.Add(item.FilePath); - note.id = 0; - note.DataId = item.id.ToString(); - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - catch(Exception ex) - { - LogFactory.GetLogger("GenerateBody").Info($"System:发生异常:" + ex.ToString()); ; - } - - } - LogFactory.GetLogger("GenerateBody").Info($"System:2"); var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.SupAgrmt = dataList; @@ -179,7 +60,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(SupAgrmtModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -208,9 +89,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } - if(model.SupAgrmtAttTuple != null && model.SupAgrmtAttTuple.Count > 0) + if (model.SupAgrmtAttTuple != null && model.SupAgrmtAttTuple.Count > 0) { - fileList.AddRange(model.SupAgrmtAttTuple.Select(x => x.SupAgrmtAtt)); + fileList.AddRange(model.SupAgrmtAttTuple.Select(x => x.SupAgrmtAtt)!); } model.ExceID = base.formatExceID(); note.id = 0; @@ -232,13 +113,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private List GetSupAgrmtModel(ref List fileList) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("补充协议")) { - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["补充协议"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["补充协议"]; + for (var i = 1; i < dt!.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -248,12 +128,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][2]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -263,40 +149,38 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - SupAgrmtModel model = new SupAgrmtModel(); - - model.OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U; - model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); - model.SupAgrmtNo = GetDataSetValue(dt, i, 1); + var model = new SupAgrmtModel + { + OperationType = optType == OptFlagsEnum.A ? OptFlagsEnum.A : OptFlagsEnum.U, + MasterAgrmtNo = GetDataSetValue(dt, i, 0), + SupAgrmtNo = GetDataSetValue(dt, i, 1) + }; var cacheValue = model.MasterAgrmtNo + "_" + model.SupAgrmtNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } model.SupAgrmtType = ConsReport.ReportTypeMap[optType == OptFlagsEnum.A ? "首次" : "变更"]; model.SigningDate = GetDataSetValue(dt, i, 3); model.SupAgrmtRemark = GetDataSetValue(dt, i, 4); - string[] atts = ((GetDataSetValue(dt, i, 5)) ?? "").Split(','); + var atts = ((GetDataSetValue(dt, i, 5)) ?? "").Split(','); foreach (var item in atts) { if (string.IsNullOrWhiteSpace(item)) { continue; } - string path = Path.Combine(sourcePath, item); + var path = Path.Combine(sourcePath, item); if (!ReportStatus.CheckFileLength(path)) { break; } - if (model.SupAgrmtAttTuple == null) - { - model.SupAgrmtAttTuple = new List(); - } + model.SupAgrmtAttTuple ??= new List(); model.SupAgrmtAttTuple.Add(new SupAgrmtAttModel() { SupAgrmtAtt = item }); fileList.Add(path); } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + var note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -332,7 +216,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (model.SupAgrmtAttTuple?.Count > 0) { - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); model.ExceID = base.formatExceID(); result.Add(model); note.id = 0; @@ -357,7 +241,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private string formatInfoTag(SupAgrmtModel model, bool suffixType = false) { - string result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.SupAgrmtNo.Replace("_", "-")}_"; + var result = $"{BusiDataType}_{model.MasterAgrmtNo.Replace("_", "-")}_{model.SupAgrmtNo.Replace("_", "-")}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -365,25 +249,41 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 4) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[2]; + arr[2] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.SupAgrmt != null) { - CheckHelper helper = new Common.CheckHelper(); - CheckHelper attHelper = new CheckHelper(); - for (int i = 0; i < model.SupAgrmt.Count; i++) + var helper = new Common.CheckHelper(); + var attHelper = new CheckHelper(); + for (var i = 0; i < model.SupAgrmt.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.SupAgrmt[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (item.SupAgrmtAttTuple != null) { - for (int j = 0; j < item.SupAgrmtAttTuple.Count; j++) + for (var j = 0; j < item.SupAgrmtAttTuple.Count; j++) { var listItem = new List(); var tuple = item.SupAgrmtAttTuple[j]; @@ -393,16 +293,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("SupAgrmtAttTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("SupAgrmtAttTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("SupAgrmt", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("SupAgrmt", i) + { + FieldValue = item.MasterAgrmtNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -428,7 +333,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs index dc60da35..803e97bc 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationAttService.cs @@ -1,8 +1,9 @@ -using System.Data; +using System.Data; using YieldChain.Helpers; using YLErp.BLL; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; using static YLErp.DBModels.Consts.ConsReport; @@ -21,258 +22,51 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1017; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_ConfirmationAtt; - List noteList = new List(); + + readonly List noteList = new(); + IEnumerable SACReportNotesCache = null; + IEnumerable SACReportNotesCache_confirmation = null; protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + SACReportNotesCache = base.InitReportNotes(ReportType); + SACReportNotesCache_confirmation = base.InitReportNotes(SuperviseReportTypeEnum.SAC_SwapConfirmation); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { - dataList = GetSwapConfirmationAttModel(out fileList); + dataList = GetSwapConfirmationAttModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var nextDataDate = _reqInfo.DataDate.AddDays(1); - using (var db = new YLContext()) - { - var codeList = ReportStatus.GetCacheInfo(cacheKey); - var query = (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r - on tc.id equals tr.TradeCashId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - join ts in db.trade_swap - on t.id equals ts.TradeId - where - ((_operationType == OptFlagsEnum.A && t.TradeDate >= _reqInfo.DataDate && t.TradeDate < nextDataDate)//新增时使用交易日期判断 - || (_operationType != OptFlagsEnum.A && tc.OptDate >= _reqInfo.ReportDate && tc.OptDate < nextDate)//补正和废止时使用操作日期判断 - || tr.OptDate >= _reqInfo.DataDate) - && (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid)) - && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换" - && tc.Action == "系统操作-期权费" - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - ts.IsGetFloatingProfit, - ts.IsPayFloatingProfit, - ts.GetVarietyId, - ts.PayVarietyId, - ts.GetUnderlyingCode, - ts.PayUnderlyingCode, - ts.GetLongShort, - ts.PayLongShort, - ts.GetSpotPrice, - ts.PaySpotPrice, - ts.GetTradePrice, - ts.PayTradePrice, - ts.GetSwapTimeAndRate, - ts.PaySwapTimeAndRate, - ts.GetFixedProfit, - ts.PayFixedProfit, - ts.GetMarginRate, - ts.PayMarginRate, - ts.GetTradeAmount, - ts.PayTradeAmount, - tr.ContractCode, - td.Paths, - td.StampDocumentFileName, - t.QuoteCurrency, - t.SettlementCurrency, - ts.GetUnAnnualRate, - ts.GetSingleFee, - ts.PayUnAnnualRate, - ts.PaySingleFee, - }).OrderBy(O => O.OptDate).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray(); - - List ids = query.Select(O => O.id).ToList(); - List delIds = new List(); - if (_operationType == OptFlagsEnum.D) - { - delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList(); - } - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - Dictionary reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescSwap).ToDictionary(K => K.PName, V => V.PValue); - foreach (var item in query) - { - var cacheValue = item.id.ToString(); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - //如果存在重复数据,则始终用较新的数据 - SwapConfirmationAttModel info = new SwapConfirmationAttModel(); - - info.ConfirmationNo = item.ContractCode; - var confirmationNote = base.GetReportNotes(SuperviseReportTypeEnum.SAC_SwapConfirmation, $"_{info.ConfirmationNo.Replace("_", "-")}_").FirstOrDefault(); - var currentCodes = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString());//取出这一次报送交易要素的交易编号 - if (!currentCodes.Contains(item.id.ToString()) && (confirmationNote == null || !confirmationNote.ReportResponse)) - { - continue;//跳过交易要素还没报送的确认书附件; - } - SACReportNotes note = base.GetReportNotes(formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - info.OperationType = OptFlagsEnum.A; - note = new SACReportNotes() - { - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - if (!note.changeStatus) - { - continue;//交易没有被修改过,跳过 - } - info.OperationType = OptFlagsEnum.U; - note.IsValid = true; - break; - case OptFlagsEnum.D: - if (!delIds.Contains(item.id)) - { - continue;//交易没有被删除,跳过 - } - info.OperationType = OptFlagsEnum.D; - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); - if (info.OperationType != _operationType) - { - continue; - } - if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradecashValid || !item.tradeContractRValid)) - {//非废止报送中,应跳过所有存在无效数据的数据 - continue; - } - if (metaDic.ContainsKey(item.id)) - { - var metaInfo = metaDic[item.id]; - var tradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : ""; - if (tradingPlace == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId;//确认书编号; - } - - - string path = item.StampDocumentFileName ?? item.Paths; - if (!path.StartsWith("\\") || path.StartsWith("/")) - { - path = "\\" + path; - } - var absolutePath = OtcAppContext.MapPath(path); - absolutePath = Path.ChangeExtension(absolutePath, "pdf"); - info.ConfirmationFilesTuple = new List() { new ConfirmationFilesTupleModel() { ConfirmationFiles = Path.GetFileName(absolutePath) } }; - info.ExceID = base.formatExceID(); - if (!ReportStatus.CheckFileLength(absolutePath)) - { - break; - } - fileList.Add(absolutePath); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.InfoCache = $"{{\"DueDate\":\"{item.OptDate?.ToString("yyyy-MM-dd")}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}"; - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.DataId = item.tcId.ToString(); - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView) - { - dataList.AddRange(GetSwapConfirmationAttModelFromView(out fileList)); - } - - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.ConfirmationAtt = dataList; return model; } - public bool AddSubsystemNote(SwapConfirmationAttModel model, List fileList, string tag) + public bool AddSubsystemNote(ConfirmationAttModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -305,7 +99,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { fileList.AddRange(model.ConfirmationFilesTuple.Select(x => x.ConfirmationFiles)); } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -323,16 +117,14 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - private List GetSwapConfirmationAttModel(out List fileList) + private List GetSwapConfirmationAttModel(ref List fileList) { - fileList = new List(); - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("收益互换确认书附件明细")) { - var cacheKey = $"{BusiDataType}"; - DataTable dt = _excelDataSource.Tables["收益互换确认书附件明细"]; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["收益互换确认书附件明细"]; + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -342,12 +134,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][1]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -357,12 +155,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - SwapConfirmationAttModel model = new SwapConfirmationAttModel(); - - model.ConfirmationNo = GetDataSetValue(dt, i, 0); - model.OperationType = optType; - var cacheValue = model.ConfirmationNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + var model = new ConfirmationAttModel + { + ConfirmationNo = GetDataSetValue(dt, i, 0), + OperationType = optType + }; + var cacheValue = (model.ConfirmationNo ?? "").ToString(); + if (cacheValue.IsNullOrWhiteSpace()) + { + continue; + } + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } @@ -378,10 +181,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service break; } fileList.Add(path); - model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { ConfirmationFiles = f }); + model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { IsSwap = "true", ConfirmationFiles = f }); } } - List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); + List notes = base.GetReportNotes(ReportType, formatInfoTag(model), dataSource: SACReportNotesCache); var note = notes.LastOrDefault(O => O.InfoCache.Contains(cacheValue)); if (note == null && _operationType == OptFlagsEnum.A) { @@ -417,9 +220,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.BizID = note.BizId; } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -440,126 +243,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - private List GetSwapConfirmationAttModelFromView(out List fileList) + private string formatInfoTag(ConfirmationAttModel model, bool suffixType = false) { - fileList = new List(); - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("交易确认书附件")) - { - var ftpHelper = new FtpHelper(PS.Config.ErpElement.KingstarView_RemotePath, PS.Config.ErpElement.KingstarView_RemoteUser, PS.Config.ErpElement.KingstarView_RemotePassword, PS.Config.ErpElement.KingstarView_FtpUsePassive, 3000, PS.Config.ErpElement.KingstarView_EnableSsl); - var cacheKey = $"{BusiDataType}"; - DataTable dt = _viewDataSource.Tables["交易确认书附件"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - var optType = OptFlagsEnum.NONE; - switch (GetDataSetValue(dt, i, "OPERATIONTYPE")) - { - case "A": - optType = OptFlagsEnum.A; - break; - case "U": - optType = OptFlagsEnum.U; - break; - case "D": - optType = OptFlagsEnum.D; - break; - } - if (optType != _operationType) - { - continue; - } - - SwapConfirmationAttModel model = new SwapConfirmationAttModel(); - model.IgnoreCheck = true; - model.ConfirmationNo = GetDataSetValue(dt, i, "CONFIRMATIONNO"); - model.OperationType = optType; - var cacheValue = model.ConfirmationNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - - model.ConfirmationFilesTuple = new List(); - ; - var files = GetDataSetValue(dt, i, "CONFIRMATIONFILES").Split(','); - foreach (var f in files) - { - if (!string.IsNullOrWhiteSpace(f)) - { - var downloadRet = ftpHelper.DownloadFile(CreateViewAttDownloadPath(f), ViewLocalAttFileDir + @"\kingstar\", out string message); - LogFactory.GetLogger("ftpHelper.DownloadFile").Info($"下载结果:{ViewLocalAttFileDir},{f},{downloadRet}"); - var path = downloadRet; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - model.ConfirmationFilesTuple.Add(new ConfirmationFilesTupleModel() { ConfirmationFiles = Path.GetFileName(path) }); - } - } - List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); - var note = notes.LastOrDefault(O => O.InfoCache.Contains(cacheValue)); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"KingstarView\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - - if (_operationType != OptFlagsEnum.A) - { - model.BizID = note.BizId; - } - model.ExceID = base.formatExceID(); - result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - note.id = 0; - note.ExceId = model.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(model, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - return result; - } - - - private string formatInfoTag(SwapConfirmationAttModel model, bool suffixType = false) - { - string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_确认书_"; + var result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_确认书_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -567,25 +253,56 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 5) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.ConfirmationAtt != null) { - CheckHelper helper = new CheckHelper(); - for (int i = 0; i < model.ConfirmationAtt.Count; i++) + var helper = new CheckHelper(); + var attHelper = new CheckHelper(); + for (var i = 0; i < model.ConfirmationAtt.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.ConfirmationAtt[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); + if (item.ConfirmationFilesTuple != null) + { + for (int j = 0; j < item.ConfirmationFilesTuple.Count; j++) + { + var att = item.ConfirmationFilesTuple[j]; + attHelper.ExecuteCheck(att, (name, value, msg) => + { + listRoot.Add(new SacInfo(name, value, msg)); + }); + } + } if (listRoot.Count > 0) { - var errMsg = new SacInfo("SwapConfirmationAtt", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("SwapConfirmationAtt", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -609,7 +326,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs index b77f1ffd..7d980eac 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapConfirmationService.cs @@ -1,11 +1,11 @@ -using BaseOUDAL; -using NPOI.SS.Formula.Functions; +using BaseOUDAL; using Qdp.Foundation.Implementations; using System.Data; using YieldChain.Helpers; using YLErp.BLL; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Helpers; using YLErp.Modules.EodModule; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; @@ -31,438 +31,35 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_SwapConfirmation; - List noteList = new List(); + + readonly List noteList = new(); + IEnumerable SACReportNotesCache = null; protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; - LogFactory.GetLogger("GenerateBody").Info($"SAC_ReportDataSource:" + PS.Config.ErpElement.SAC_ReportDataSource.ToString()); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + SACReportNotesCache = base.InitReportNotes(ReportType); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetSwapConfirmationModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var nextDataDate = _reqInfo.DataDate.AddDays(1); - using (var db = new YLContext()) - { - var codeList = ReportStatus.GetCacheInfo(cacheKey); - var query = (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r - on tc.id equals tr.TradeCashId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - join ts in db.trade_swap - on t.id equals ts.TradeId - where - ((_operationType == OptFlagsEnum.A && t.TradeDate >= _reqInfo.DataDate && t.TradeDate < nextDataDate)//新增时使用交易日期判断 - || (_operationType != OptFlagsEnum.A && tc.OptDate >= _reqInfo.ReportDate && tc.OptDate < nextDate))//补正和废止时使用操作日期判断 - && (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid)) - && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换" - && tc.Action == "系统操作-期权费" - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - ts.IsGetFloatingProfit, - ts.IsPayFloatingProfit, - ts.GetVarietyId, - ts.PayVarietyId, - ts.GetUnderlyingCode, - ts.PayUnderlyingCode, - ts.GetLongShort, - ts.PayLongShort, - ts.GetSpotPrice, - ts.PaySpotPrice, - ts.GetTradePrice, - ts.PayTradePrice, - ts.GetSwapTimeAndRate, - ts.PaySwapTimeAndRate, - ts.GetFixedProfit, - ts.PayFixedProfit, - ts.GetMarginRate, - ts.PayMarginRate, - ts.GetTradeAmount, - ts.PayTradeAmount, - tr.ContractCode, - td.Paths, - t.QuoteCurrency, - t.SettlementCurrency, - ts.GetUnAnnualRate, - ts.GetSingleFee, - ts.PayUnAnnualRate, - ts.PaySingleFee, - ts.SwapType, - td.Comments, - }).OrderBy(O => O.OptDate).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray(); - - List ids = query.Select(O => O.id).ToList(); - List delIds = new List(); - if (_operationType == OptFlagsEnum.D) - { - delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList(); - } - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - Dictionary reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescSwap).ToDictionary(K => K.PName, V => V.PValue); - foreach (var item in query) - { - var cacheValue = item.id.ToString(); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - //如果存在重复数据,则始终用较新的数据 - SwapConfirmationModel info = new SwapConfirmationModel(); - - //info.TradeId = item.id.ToString(); - info.ConfirmationNo = item.ContractCode; - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(info)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - info.OperationType = OptFlagsEnum.A; - note = new SACReportNotes() - { - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - if (!note.changeStatus) - { - continue;//交易没有被修改过,跳过 - } - info.OperationType = OptFlagsEnum.U; - note.IsValid = true; - break; - case OptFlagsEnum.D: - if (!delIds.Contains(item.id)) - { - continue;//交易没有被删除,跳过 - } - info.OperationType = OptFlagsEnum.D; - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); - if (info.OperationType != _operationType) - { - continue; - } - if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradecashValid || !item.tradeContractRValid)) - {//非废止报送中,应跳过所有存在无效数据的数据 - continue; - } - if (metaDic.ContainsKey(item.id)) - { - var metaInfo = metaDic[item.id]; - info.MasterAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.MainProtocolCode) ? metaInfo[ConsTradeMetaKey.MainProtocolCode] : ""; - info.SupAgrmtNo = metaInfo.ContainsKey(ConsTradeMetaKey.SupProtocolCode) ? metaInfo[ConsTradeMetaKey.SupProtocolCode] : ""; - info.ClearingAgency = metaInfo.ContainsKey(ConsTradeMetaKey.ClearingAgency) ? ClearingAgencyMap[metaInfo[ConsTradeMetaKey.ClearingAgency]] : ""; - info.TradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : ""; - if (info.TradingPlace == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.ConfirmationID = note.BizId;//确认书编号; - } - info.ConfirmationType = ReportTypeMap[info.OperationType == OptFlagsEnum.A ? "首次" : "变更"]; - info.FillParty = FillPartyMap["甲方"]; - if (item.SwapType == "普通") - { - var longShort = item.IsPayFloatingProfit ? item.PayLongShort : item.GetLongShort; - info.SwapType = ConsReport.SwapTypeMap["客户" + longShort]; - } - else - { - info.SwapType = ConsReport.SwapTypeMap[item.SwapType]; - } - var variety = DataCacheProvider.GetVariety(item.UnderlyingCode); - var customizedResultsGet = QdpHelper.ParseAutocallCustomizedInfo(item.GetSwapTimeAndRate); - var getSwapRates = customizedResultsGet.Item2?.Distinct(); - var customizedResultsPay = QdpHelper.ParseAutocallCustomizedInfo(item.PaySwapTimeAndRate); - var paySwapRates = customizedResultsPay.Item2?.Distinct(); - - var rates = item.IsPayFloatingProfit ? getSwapRates : paySwapRates; - var paymentMethod = new PaymentMethodModel(); - if (GetPaySide(item.IsPayFloatingProfit, info.ClearingAgency)) - { - var underlyingCode = string.IsNullOrWhiteSpace(item.GetUnderlyingCode) ? item.PayUnderlyingCode : item.GetUnderlyingCode; - var um = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode); - info.PtyAUndrlygAssetNo = um.CommodityCode == "组合标的" ? UndrlygAssetNoMap["组合标的"] : UndrlygAssetNoMap["单一标的"]; - if (rates.Count() == 1) - { - info.PaymentMethod = PaymentMethodMap["固定利率收益"]; - paymentMethod.FixedInterestRate = (rates.First() * 100).ToString(); - } - else - { - info.PaymentMethod = PaymentMethodMap["浮动利率收益"]; - paymentMethod.FloatInterestRate = ConsReport.RefRateTypeMap["其他"]; - paymentMethod.ReferenceofFloatingInterestRate = "其他"; - paymentMethod.BasePoint = "0"; - } - } - else - { - info.PtyAUndrlygAssetNo = UndrlygAssetNoMap["单一标的"]; - if (rates.Count() == 1) - { - info.PaymentMethod = PaymentMethodMap["固定利率收益"]; - paymentMethod.FixedInterestRate = (rates.First() * 100).ToString(); - } - else - { - info.PaymentMethod = PaymentMethodMap["浮动利率收益"]; - paymentMethod.FloatInterestRate = ConsReport.RefRateTypeMap["其他"]; - paymentMethod.ReferenceofFloatingInterestRate = "其他"; - paymentMethod.BasePoint = "其他"; - paymentMethod.BasePoint = "0"; - } - } - paymentMethod.PaymentMethod = info.PaymentMethod; - paymentMethod.Payer = item.IsPayFloatingProfit ? ConsReport.PayerMap["乙方"] : ConsReport.PayerMap["甲方"]; - - var getSwapDates = customizedResultsGet.Item1?.Distinct(); - if (getSwapDates?.Count() == 1) - { - Date date = getSwapDates.First(); - paymentMethod.PaymentFreq = date == new Date(item.TradeDate.Value) ? PaymentFreqMap["期初支付"] : PaymentFreqMap["期末支付"]; - } - else - { - paymentMethod.PaymentFreq = PaymentFreqMap["期间多次支付"]; - } - var paySwapDates = customizedResultsPay.Item1?.Distinct(); - if (paySwapDates?.Count() == 1) - { - Date date = paySwapDates.First(); - paymentMethod.PaymentFreq = date == new Date(item.TradeDate.Value) ? PaymentFreqMap["期初支付"] : PaymentFreqMap["期末支付"]; - } - else - { - paymentMethod.PaymentFreq = PaymentFreqMap["期间多次支付"]; - } - info.StartDate = item.TradeDate?.ToString("yyyy-MM-dd"); - info.DueDate = item.ExerciseDate?.ToString("yyyy-MM-dd"); - info.SettlementDate = (item.SettlementDate ?? item.ExerciseDate)?.ToString("yyyy-MM-dd"); - if (PS.Config.Company == Configuration.CompanyEnum.中金) - { - var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode); - if (um.CloseDate != null && um.CloseDate != DateTime.MinValue) - { - info.DueDate = um.CloseDate?.ToString("yyyy-MM-dd"); - } - - } - var currency = (item.SettlementCurrency == "CNH" ? "CNY" : item.SettlementCurrency) ?? "CNY"; - info.Currency = ((int)(CurrencyEnum)Enum.Parse(typeof(CurrencyEnum), currency.ToUpper())).ToString();// ((int)CurrencyEnum.CNY).ToString(); - var rate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(item.QuoteCurrency, "CNY", _reqInfo.DataDate); - info.NotinalPrincipleAmt = (item.OriginalStockEqvNotional * rate)?.ToString("0.00"); - info.UndrlygAssetType = string.IsNullOrWhiteSpace(variety.MainCategoryDesc) ? UndrlygAssetTypeMap["其他"] : UndrlygAssetTypeMap[variety.MainCategoryDesc]; - //系统中的交易修改时必须回退,所以报送不存在修改时还存在有效的存续期记录的情况; - //if (info.OperationType == OptFlagsEnum.U) - //{ - // if (reportCacheDic.ContainsKey("DueDate") && !reportCacheDic["DueDate"].StartsWith(info.DueDate) && !info.DueDate.StartsWith(reportCacheDic["DueDate"])) - // { - // throw new ServiceException("补正时,如果该交易还存在有效的存续期记录,到期日字段不能修改"); - // } - // if (reportCacheDic.ContainsKey("NotinalPrincipleAmt") && reportCacheDic["NotinalPrincipleAmt"] != info.NotinalPrincipleAmt && reportCacheDic["NotinalPrincipleAmt"] != item.OriginalStockEqvNotional?.ToString("0")) - // { - // throw new ServiceException("补正时,如果该交易还存在有效的存续期记录,名义本金额(人民币)字段不能修改"); - // } - //} - #region 履约担保 - - var files = db.trade_file.Where(O => O.TradeId == item.id).ToArray(); - info.PerformanceGuaranteeType = item.MarginType == MarginTypeEnum.NONE ? PerformanceGuaranteeMap["无履约担保"] : PerformanceGuaranteeMap["部分担保"]; - if (item.MarginType != MarginTypeEnum.NONE) - { - info.PerformanceCollProvider = PerformanceCollProviderMap["乙方"]; - info.PartyUseColl = ConsReport.BoolMap[valuedateBLL.SystemDate.PartyUseColl || PS.Config.Company == Configuration.CompanyEnum.东莞 ? "是" : "否"];//todo:读取用户输入 - info.CollInstruction = valuedateBLL.SystemDate.CollInstruction;//todo:读取用户输入 - info.CalculateCollInterest = BoolMap["否"]; - info.PerformanceCollInitialRatio = (item.GetMarginRate * 100)?.ToString("0.##");//获取客户预付金率 - info.PerformanceCollAddtlRatio = "100"; - info.PerformanceCollOffsetRatio = "100"; - info.MaintainGuaranteeRatio = info.PerformanceCollInitialRatio; - if (PS.Config.Company == Configuration.CompanyEnum.中金) - { - info.PerformanceCollAddtlRatio = info.PerformanceCollInitialRatio; - info.PerformanceCollOffsetRatio = info.PerformanceCollInitialRatio; - info.MaintainGuaranteeRatio = info.PerformanceCollInitialRatio; - } - - var file_PerformanceGuarante = files.FirstOrDefault(O => O.Path.ToLower().EndsWith("履约保证书.pdf")); - info.PerformanceGuaranteeAtt = Path.GetFileName(file_PerformanceGuarante?.Path); - info.PerformanceGuaranteeRemark = file_PerformanceGuarante?.Description; - info.Remark = item.Comments; - info.PerformanceCollTuple = new List(); - info.PerformanceCollTuple.Add(new SwapPerformanceGuaranteeAttModel() - { - PerformanceCollType = PerformanceCollTypeMap["现金"], - PerformanceCollRange = /*item.MarginType == MarginTypeEnum.DEFAULT ? PerformanceCollRangeMap["本笔交易对应主协议框架下的所有交易"] :*/ PerformanceCollRangeMap["仅本笔交易"] - }); - if (!ReportStatus.CheckFileLength(file_PerformanceGuarante?.Path)) - { - break; - } - fileList.Add(file_PerformanceGuarante?.Path); - } - else - { - info.PerformanceCollInitialRatio = "0"; - info.MaintainGuaranteeRatio = "0"; - } - - #endregion - var file_ComplianceOpinion = files.FirstOrDefault(O => O.Path.ToLower().EndsWith("合规意见书.pdf")); - if (!string.IsNullOrWhiteSpace(file_ComplianceOpinion?.Path)) - { - string fileName = Path.GetFileName(file_ComplianceOpinion?.Path); - info.ComplianceOpinion = fileName; - if (!ReportStatus.CheckFileLength(file_ComplianceOpinion?.Path)) - { - break; - } - fileList.Add(file_ComplianceOpinion?.Path); - } - - var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); - switch (PS.Config.Company) - { - case Configuration.CompanyEnum.中金: - GetCalculationInfoFromZhongJin(info, item.QuoteCurrency, item.IsPayFloatingProfit, item.IsPayFloatingProfit ? item.PayLongShort : item.GetLongShort, client.BoundSide); - break; - default: - string defaultDesc = reportDescDic.ContainsKey("默认") ? reportDescDic["默认"] : ""; - info.PtyAPrOfitCalculationInfo = reportDescDic.ContainsKey("甲方支付乙方") && !string.IsNullOrWhiteSpace(reportDescDic["甲方支付乙方"]) ? reportDescDic["甲方支付乙方"] : defaultDesc;//说明 - //info.PtyBProfitCalculationInfo = reportDescDic.ContainsKey("乙方支付甲方") && !string.IsNullOrWhiteSpace(reportDescDic["乙方支付甲方"]) ? reportDescDic["乙方支付甲方"] : defaultDesc;//说明 - break; - } - if (client.ClientType == "产品") - { - using (var baseDb = new ClientDBContext()) - { - if (PS.Config.Company == Configuration.CompanyEnum.中金) - { - info.FillParty = FillPartyMap["甲方"]; - info.PtyBPdctName = new ClientModule.ClientQueryService(OptUser).GetProductName(client.id) ?? ""; - info.PytBPdctCode = client.ProductNumber ?? ""; - } - else - { - //var clientFile = baseDb.client_file.Where(O => ((O.FileTypeName == ConsGlobal.ClientFileType.MainProtocol && O.ProtocolNumber == info.MasterAgrmtNo) || (O.FileTypeName == ConsGlobal.ClientFileType.AllographProduct && O.MainProtocolNumber == info.MasterAgrmtNo)) && O.ClientId == client.id && O.IsValid).AsEnumerable().GroupBy(O => O.FileTypeName).ToDictionary(K => K.Key, V => V.FirstOrDefault()); - //if (!clientFile.ContainsKey(ConsGlobal.ClientFileType.MainProtocol)) - //{ - // throw new ServiceException($"{client.Name} 主协议文件不存在,生成失败!"); - //} - ////下面这行注释掉是因为目前系统报送互换时只处理了报送方是甲方的情况,假如报送方为乙方,则所有涉及支付方向的参数都应该对调; - ////info.FillParty = FillPartyMap[clientFile[ConsGlobal.ClientFileType.MainProtocol].ReportorRole]; - //info.FillParty = FillPartyMap["甲方"]; - //var productFile = clientFile.ContainsKey(ConsGlobal.ClientFileType.AllographProduct) ? clientFile[ConsGlobal.ClientFileType.AllographProduct] : null; - if (info.FillParty == FillPartyMap["甲方"]) - { - info.PtyBPdctName = client.Name ?? ""; - info.PytBPdctCode = client.Number ?? ""; - } - else - { - info.PtyAPdctName = client.Name ?? ""; - info.PytAPdctCode = client.Number ?? ""; - } - } - } - } - info.CostPaymentTuple = new List() { paymentMethod }; - info.ExceID = base.formatExceID(); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - ReportStatus.AddCacheInfo($"{cacheKey}_{info.ConfirmationNo}", info.NotinalPrincipleAmt); - dataList.Add(info); - note.id = 0; - note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{info.NotinalPrincipleAmt}\",\"DueDate\":\"{info.DueDate}\",\"Tag\":\"{info.ConfirmationNo}\",\"Source\":\"System\"}}"; - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.DataId = item.tcId.ToString(); - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView) - { - LogFactory.GetLogger("GenerateBody").Info($"SAC_ReportDataSourceEnum.KingstarView"); - dataList.AddRange(GetSwapConfirmationModelFromView(ref fileList)); - } - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } fileList = fileList.Distinct().ToList(); noData = dataList.Count == 0; @@ -472,7 +69,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(SwapConfirmationModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -513,7 +110,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList.Add(model.ComplianceOpinion); } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -531,54 +128,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - - /// - /// 中金填写收益说明 - /// - /// - /// - /// - private void GetCalculationInfoFromZhongJin(SwapConfirmationModel info, string quoteCurrency, bool IsPaySide, string longShort, BoundSideEnum side) - { - //根据现金流支付方式 - info.PtyAPrOfitCalculationInfo = GetSingleCalculationInfo(info.PaymentMethod); - - var currency = (quoteCurrency == "CNH" || string.IsNullOrWhiteSpace(quoteCurrency)) ? "CNY" : quoteCurrency; - var qCurrency = ((CurrencyEnum)Enum.Parse(typeof(CurrencyEnum), currency)); - if (qCurrency != CurrencyEnum.CNY) - { - info.PtyAPrOfitCalculationInfo += "*结算汇率"; - //info.PtyBProfitCalculationInfo += "*结算汇率"; - } - } - - private string GetSingleCalculationInfo(string paymentMethod) - { - switch (paymentMethod) - { - case "0": - return "(期初价格-期末价格)*标的资产数量"; - case "1": - return "(期末价格 - 期初价格) * 标的资产数量"; - case "2": - return ""; - case "3": - return "标的资产数量*期初价格*固定收益率"; - default: - return ""; - } - } - private List GetSwapConfirmationModel(ref List fileList) { - List result = new List(); - string path = ""; + var result = new List(); + var path = ""; if (_excelDataSource != null && _excelDataSource.Tables.Contains("互换交易确认书明细")) { - var cacheKey = $"{BusiDataType}"; - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - DataTable dt = _excelDataSource.Tables["互换交易确认书明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["互换交易确认书明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -588,12 +146,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][3]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -603,19 +167,22 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - SwapConfirmationModel model = new SwapConfirmationModel(); - - model.OperationType = optType; - model.MasterAgrmtNo = GetDataSetValue(dt, i, 0); - model.SupAgrmtNo = GetDataSetValue(dt, i, 1); - model.ConfirmationNo = GetDataSetValue(dt, i, 2); - model.ConfirmationType = ConsReport.ReportTypeMap[optType == OptFlagsEnum.A ? "首次" : "变更"]; - model.FillParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 4)]; - model.SwapType = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 5)]; - model.StartDate = GetDataSetValue(dt, i, 6); - model.DueDate = GetDataSetValue(dt, i, 7); - model.SettlementDate = GetDataSetValue(dt, i, 8); - if (Enum.TryParse(GetDataSetValue(dt, i, 9).ToUpper(), out CurrencyEnum currency)) + var model = new SwapConfirmationModel + { + OperationType = optType, + MasterAgrmtNo = GetDataSetValue(dt, i, 0), + SupAgrmtNo = GetDataSetValue(dt, i, 1), + ConfirmationNo = GetDataSetValue(dt, i, 2), + ConfirmationType = ConsReport.ReportTypeMap[optType == OptFlagsEnum.A ? "首次" : "变更"], + FillParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 4)], + SwapType = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 5)], + StartDate = GetDataSetValue(dt, i, 6), + DueDate = GetDataSetValue(dt, i, 7), + SettlementDate = GetDataSetValue(dt, i, 8) + }; + var currencyStr = GetDataSetValue(dt, i, 9); + currencyStr = currencyStr == "其他" ? "Other" : currencyStr; + if (Enum.TryParse(currencyStr.ToUpper(), out CurrencyEnum currency)) { model.Currency = ((int)currency).ToString(); } @@ -653,12 +220,16 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var notinalPrincipleAmt = GetDataSetValueToDouble(dt, i, 10); - var cacheValue = model.ConfirmationNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + var cacheValue = (model.ConfirmationNo ?? "").ToString(); + if (cacheValue.IsNullOrWhiteSpace()) { continue; } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) + { + continue; + } + var note = base.GetReportNotes(ReportType, formatInfoTag(model), dataSource: SACReportNotesCache).FirstOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { note = new SACReportNotes() @@ -686,7 +257,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service default: throw new ServiceException("未知操作类型"); } - Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); + var reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); if (_operationType == OptFlagsEnum.U) { if (reportCacheDic.ContainsKey("DueDate") && !reportCacheDic["DueDate"].StartsWith(model.DueDate) && !model.DueDate.StartsWith(reportCacheDic["DueDate"])) @@ -721,9 +292,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } fileList.Add(path); } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Template\"}}"; note.ExceId = model.ExceID; @@ -744,244 +315,36 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - private List GetSwapConfirmationModelFromView(ref List fileList) - { - var ftpHelper = new FtpHelper(PS.Config.ErpElement.KingstarView_RemotePath, PS.Config.ErpElement.KingstarView_RemoteUser, PS.Config.ErpElement.KingstarView_RemotePassword, PS.Config.ErpElement.KingstarView_FtpUsePassive, 3000, PS.Config.ErpElement.KingstarView_EnableSsl); - List result = new List(); - string path = ""; - if (_viewDataSource != null && _viewDataSource.Tables.Contains("交易确认书")) - { - var cacheKey = $"{BusiDataType}"; - DataTable dt = _viewDataSource.Tables["交易确认书"]; - LogFactory.GetLogger("GetSwapConfirmationModelFromView").Info($"交易确认书记录数:" + dt.Rows.Count); - for (int i = 0; i < dt.Rows.Count; i++) - { - LogFactory.GetLogger("GetSwapConfirmationModelFromView").Info($"交易确认书记录数:" + dt.Rows.Count); - var operateType = GetDataSetValue(dt, i, "OPERATIONTYPE"); - LogFactory.GetLogger("GetSwapConfirmationModelFromView").Info($"OperateType:" + operateType.ToString()); - var optType = OptFlagsEnum.NONE; - switch (GetDataSetValue(dt, i, "OPERATIONTYPE")) - { - case "A": - optType = OptFlagsEnum.A; - break; - case "U": - optType = OptFlagsEnum.U; - break; - case "D": - optType = OptFlagsEnum.D; - break; - } - if (optType != _operationType) - { - continue; - } - - SwapConfirmationModel model = new SwapConfirmationModel(); - model.IgnoreCheck = true; - model.OperationType = optType; - model.MasterAgrmtNo = GetDataSetValue(dt, i, "MASTERAGRMTNO"); - model.SupAgrmtNo = GetDataSetValue(dt, i, "SUPAGRMNO"); - model.ConfirmationNo = GetDataSetValue(dt, i, "CONFIRMATIONNO"); - model.ConfirmationType = ConsReport.ReportTypeMap[optType == OptFlagsEnum.A ? "首次" : "变更"]; - model.FillParty = GetDataSetValue(dt, i, "FILLPARTY"); - model.SwapType = GetDataSetValue(dt, i, "SWAPTYPE"); - model.StartDate = GetDataSetValue(dt, i, "STARTDATE"); - model.DueDate = GetDataSetValue(dt, i, "DUEDATE"); - model.SettlementDate = GetDataSetValue(dt, i, "SETTLEMENTDATE"); - - model.Currency = GetDataSetValue(dt, i, "CURRENCY"); - - model.NotinalPrincipleAmt = GetDataSetValue(dt, i, "NOTIONALPRINCIPLEAMT"); - model.ClearingAgency = GetDataSetValue(dt, i, "CLEARINGAGENCY"); - model.TradingPlace = GetDataSetValue(dt, i, "TRADINGPLACE"); - model.TradingPlaceOther = GetDataSetValue(dt, i, "TRADINGPLACEOTHER"); - model.UndrlygAssetType = GetDataSetValue(dt, i, "UNDRLYGASSETTYPE"); - model.ConfirmationRemark = GetDataSetValue(dt, i, "CONFIRMATIONREMARK"); - model.PerformanceGuaranteeType = GetDataSetValue(dt, i, "PERFORMANCEGUARANTEETYPE"); - model.PerformanceCollProvider = GetDataSetValue(dt, i, "PERFORMANCECOLLPROVIDER"); - model.PartyUseColl = GetDataSetValue(dt, i, "PARTYUSECOLL"); - model.CollInstruction = GetDataSetValue(dt, i, "COLLINSTRUCTION"); - model.CalculateCollInterest = GetDataSetValue(dt, i, "CALCULATECOLLINTEREST"); - model.PerformanceCollInitialRatio = GetDataSetValue(dt, i, "PERFORMANCECOLLINITIALRATIO"); - model.PerformanceCollAddtlRatio = GetDataSetValue(dt, i, "PERFORMANCECOLLADDTLRATIO"); - model.PerformanceCollOffsetRatio = GetDataSetValue(dt, i, "PERFORMANCECOLLOFFSETRATIO"); - model.MaintainGuaranteeRatio = GetDataSetValue(dt, i, "MAINTAINGUARANTEERATIO"); - model.PerformanceGuaranteeAtt = GetDataSetValue(dt, i, "PERFORMANCEGUARANTEEATT"); - model.PerformanceGuaranteeRemark = GetDataSetValue(dt, i, "PERFORMANCEGUARANTEEREMARK"); - model.Remark = GetDataSetValue(dt, i, "REMARK"); - model.ComplianceOpinion = GetDataSetValue(dt, i, "COMPLIANCEOPINION"); - model.PtyAUndrlygAssetNo = GetDataSetValue(dt, i, "PTYAUNDRLYGASSETNO"); - model.PtyAPrOfitCalculationInfo = GetDataSetValue(dt, i, "PTYAPROFITCALCULATIONINFO"); - model.PtyAProfitRemark = GetDataSetValue(dt, i, "PTYAPROFITREMARK"); - model.PtyAPdctName = GetDataSetValue(dt, i, "PTYAPDCTNAME"); - model.PytAPdctCode = GetDataSetValue(dt, i, "PTYAPDCTCODE"); - model.PtyBPdctName = GetDataSetValue(dt, i, "PTYBPDCTNAME"); - model.PytBPdctCode = GetDataSetValue(dt, i, "PTYBPDCTCODE"); - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); - - model.CostPaymentTuple = GetCostPaymentTupleFromView(model.ConfirmationNo); - model.PerformanceCollTuple = GetPerformanceGuaranteeAttModelFromView(model.ConfirmationNo); - - var notinalPrincipleAmt = GetDataSetValueToDouble(dt, i, "NOTIONALPRINCIPLEAMT"); - - var cacheValue = model.ConfirmationNo; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model)).FirstOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - Dictionary reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); - if (_operationType == OptFlagsEnum.U) - { - if (reportCacheDic.ContainsKey("DueDate") && !reportCacheDic["DueDate"].StartsWith(model.DueDate) && !model.DueDate.StartsWith(reportCacheDic["DueDate"])) - { - throw new ServiceException("补正时,如果该交易还有存续期记录,到期日字段不能修改"); - } - if (reportCacheDic.ContainsKey("NotinalPrincipleAmt") && reportCacheDic["NotinalPrincipleAmt"] != model.NotinalPrincipleAmt && reportCacheDic["NotinalPrincipleAmt"] != notinalPrincipleAmt.ToString("0")) - { - throw new ServiceException("补正时,如果该交易还有存续期记录,名义本金额(人民币)字段不能修改"); - } - } - } - if (model.OperationType != OptFlagsEnum.A) - { - model.ConfirmationID = note.BizId;//确认书编号; - } - if (!string.IsNullOrWhiteSpace(model.PerformanceGuaranteeAtt)) - { - var downloadRet = ftpHelper.DownloadFile(CreateViewAttDownloadPath(model.PerformanceGuaranteeAtt), ViewLocalAttFileDir + @"\kingstar\", out string message); - LogFactory.GetLogger("ftpHelper.DownloadFile").Info($"下载结果:{ViewLocalAttFileDir},{model.PerformanceGuaranteeAtt},{downloadRet}"); - path = downloadRet; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - model.PerformanceGuaranteeAtt = Path.GetFileName(path); - } - if (!string.IsNullOrWhiteSpace(model.ComplianceOpinion)) - { - var downloadRet = ftpHelper.DownloadFile(CreateViewAttDownloadPath(model.ComplianceOpinion), ViewLocalAttFileDir + @"\kingstar\", out string message); - LogFactory.GetLogger("ftpHelper.DownloadFile").Info($"下载结果:{ViewLocalAttFileDir},{model.ComplianceOpinion},{downloadRet}"); - path = downloadRet; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - model.ComplianceOpinion = Path.GetFileName(path); - } - model.ExceID = base.formatExceID(); - result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - note.id = 0; - note.InfoCache = $"{{\"NotinalPrincipleAmt\":\"{model.NotinalPrincipleAmt}\",\"DueDate\":\"{model.DueDate}\",\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"KingstarView\"}}"; - note.ExceId = model.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(model, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - return result; - } - private List GetCostPaymentTuple(string confirmationNo) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("收益互换交易费用支付端")) { - DataTable dt = _excelDataSource.Tables["收益互换交易费用支付端"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["收益互换交易费用支付端"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != confirmationNo) + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; } - PaymentMethodModel model = new PaymentMethodModel(); - model.PaymentMethod = ConsReport.PaymentMethodMap[GetDataSetValue(dt, i, 1)]; - model.Payer = ConsReport.PayerMap[GetDataSetValue(dt, i, 2)]; - model.PaymentFreq = ConsReport.PaymentFreqMap[GetDataSetValue(dt, i, 3)]; - model.FixedInterestRate = GetDataSetValue(dt, i, 4); - model.FloatInterestRate = ConsReport.RefRateTypeMap[GetDataSetValue(dt, i, 5)]; - model.ReferenceofFloatingInterestRate = GetDataSetValue(dt, i, 6); - model.BasePoint = GetDataSetValue(dt, i, 7); - model.Blank1 = GetDataSetValue(dt, i, 8); - model.Blank2 = GetDataSetValue(dt, i, 9); - - result.Add(model); - } - } - return result; - } - - private List GetCostPaymentTupleFromView(string confirmationNo) - { - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("费用端支付")) - { - DataTable dt = _viewDataSource.Tables["费用端支付"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - - if (GetDataSetValue(dt, i, "CONFIRMATIONNO") != confirmationNo) + var model = new PaymentMethodModel { - continue; - } - - PaymentMethodModel model = new PaymentMethodModel(); - model.PaymentMethod = GetDataSetValue(dt, i, "PAYMENTMETHOD"); - model.Payer = GetDataSetValue(dt, i, "PAYER"); - model.PaymentFreq = GetDataSetValue(dt, i, "PAYMENTFREQ"); - model.FixedInterestRate = GetDataSetValue(dt, i, "FIXEDINTERESTRATE"); - model.FloatInterestRate = GetDataSetValue(dt, i, "FLOATINTERESTRATE"); - model.ReferenceofFloatingInterestRate = GetDataSetValue(dt, i, "REFFLOATINGINTERESTRATE"); - model.BasePoint = GetDataSetValue(dt, i, "BASEPOINT"); - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); + PaymentMethod = ConsReport.PaymentMethodMap[GetDataSetValue(dt, i, 1)], + Payer = ConsReport.PayerMap[GetDataSetValue(dt, i, 2)], + PaymentFreq = ConsReport.PaymentFreqMap[GetDataSetValue(dt, i, 3)], + FixedInterestRate = GetDataSetValue(dt, i, 4), + FloatInterestRate = ConsReport.RefRateTypeMap[GetDataSetValue(dt, i, 5)], + ReferenceofFloatingInterestRate = GetDataSetValue(dt, i, 6), + BasePoint = GetDataSetValue(dt, i, 7), + Blank1 = GetDataSetValue(dt, i, 8), + Blank2 = GetDataSetValue(dt, i, 9) + }; result.Add(model); } @@ -991,64 +354,39 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private List GetPerformanceGuaranteeAttModel(string confirmationNo) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("履约担保品明细")) { - DataTable dt = _excelDataSource.Tables["履约担保品明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["履约担保品明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != confirmationNo) + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; } - SwapPerformanceGuaranteeAttModel model = new SwapPerformanceGuaranteeAttModel(); - - model.PerformanceCollType = ConsReport.PerformanceCollTypeMap[GetDataSetValue(dt, i, 1)]; - model.PerformanceCollRange = ConsReport.PerformanceCollRangeMap[GetDataSetValue(dt, i, 2)]; - model.MultiConfirmationID = GetDataSetValue(dt, i, 3); - model.Remarks = GetDataSetValue(dt, i, 4); + var model = new SwapPerformanceGuaranteeAttModel + { + PerformanceCollType = ConsReport.PerformanceCollTypeMap[GetDataSetValue(dt, i, 1)], + PerformanceCollRange = ConsReport.PerformanceCollRangeMap[GetDataSetValue(dt, i, 2)], + MultiConfirmationID = GetDataSetValue(dt, i, 3), + Remarks = GetDataSetValue(dt, i, 4) + }; result.Add(model); } } return result; } - - private List GetPerformanceGuaranteeAttModelFromView(string confirmationNo) + + private string formatInfoTag(SwapConfirmationModel model, bool suffixType = false) { - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("履约担保品")) - { - DataTable dt = _viewDataSource.Tables["履约担保品"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - - if (GetDataSetValue(dt, i, "CONFIRMATIONNO") != confirmationNo) - { - continue; - } - - SwapPerformanceGuaranteeAttModel model = new SwapPerformanceGuaranteeAttModel(); - model.PerformanceCollType = GetDataSetValue(dt, i, "PERFORMANCECOLLTYPE"); - model.PerformanceCollRange = GetDataSetValue(dt, i, "PERFORMANCECOLLRANGE"); - model.MultiConfirmationID = GetDataSetValue(dt, i, "MULTICONFIRMATIONID"); - model.Remarks = GetDataSetValue(dt, i, "REMARKS"); - - result.Add(model); - } - } - return result; - } - - private string formatInfoTag(SwapConfirmationModel model, bool suffixType = false, bool isSettlement = false) - { - string result = $"{(isSettlement ? "" : BusiDataType.ToString())}_{model.ConfirmationNo.Replace("_", "-")}_{(isSettlement ? "" : "成交_")}"; + var result = $"{BusiDataType.ToString()}_{model.ConfirmationNo.Replace("_", "-")}_成交_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -1056,26 +394,42 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 4) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.SwapConfirmation != null) { - CheckHelper helper = new Common.CheckHelper(); - CheckHelper pAttHelper = new Common.CheckHelper(); - CheckHelper cAttHelper = new Common.CheckHelper(); - for (int i = 0; i < model.SwapConfirmation.Count; i++) + var helper = new Common.CheckHelper(); + var pAttHelper = new Common.CheckHelper(); + var cAttHelper = new Common.CheckHelper(); + for (var i = 0; i < model.SwapConfirmation.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.SwapConfirmation[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (item.CostPaymentTuple != null) { - for (int j = 0; j < item.CostPaymentTuple.Count; j++) + for (var j = 0; j < item.CostPaymentTuple.Count; j++) { var listItem = new List(); var attItem = item.CostPaymentTuple[j]; @@ -1085,15 +439,17 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("CostPaymentTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("CostPaymentTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (item.PerformanceCollTuple != null) { - for (int j = 0; j < item.PerformanceCollTuple.Count; j++) + for (var j = 0; j < item.PerformanceCollTuple.Count; j++) { var listItem = new List(); var attItem = item.PerformanceCollTuple[j]; @@ -1103,16 +459,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("PerformanceCollTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("PerformanceCollTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("SwapConfirmation", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("SwapConfirmation", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -1136,20 +497,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } return true; } - - private bool GetPaySide(bool IsPaySide, string clearingAgency) - { - if (PS.Config.Company == Configuration.CompanyEnum.中金) - { - return clearingAgency == ClearingAgencyMap["甲方"]; - } - return IsPaySide; - } } } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs index 81196560..07b56618 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapEquityPaymentService.cs @@ -1,6 +1,9 @@ -using Qdp.Foundation.Implementations; +using MoreLinq; +using Qdp.Foundation.Implementations; +using System.Collections.ObjectModel; using System.Data; using YLErp.BLL; +using YLErp.Commons; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; using YLErp.Modules.SuperviseReportModule.SAC.Common; @@ -22,339 +25,40 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1016; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_SwapEquityPayment; - List noteList = new List(); + + readonly List noteList = new(); + IEnumerable SACReportNotesCache = null; protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - var cacheKey = $"{BusiDataType}"; - List dataList = new List(); + var model = new BodyModel(); + SACReportNotesCache = base.InitReportNotes(ReportType); + var dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { dataList = GetSwapEquityPaymentModel(); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var nextDate = _reqInfo.ReportDate.AddDays(1); - var nextDataDate = _reqInfo.DataDate.AddDays(1); - using (var db = new YLContext()) - { - var actions = new List() { "系统操作-平仓费", "系统操作-行权费", "系统操作-期权费" }; - var codeList = ReportStatus.GetCacheInfo(cacheKey); - var query = (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on tc.TradeId equals tr.TradeId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - join ts in db.trade_swap - on t.id equals ts.TradeId - where - ((_operationType == OptFlagsEnum.A && tc.ValueDate >= _reqInfo.DataDate && t.TradeDate < nextDataDate)//新增时使用交易日期判断 - || (_operationType != OptFlagsEnum.A && tc.OptDate >= _reqInfo.ReportDate && tc.OptDate < nextDate))//补正和废止时使用操作日期判断 - && (_operationType == OptFlagsEnum.D || (t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid)) - && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换" - && actions.Contains(tc.Action) - select new - { - ValueDate = tc.HappenedDate ?? tc.ValueDate, - isSettle = tc.Action != "系统操作-期权费", - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - ts.IsGetFloatingProfit, - ts.IsPayFloatingProfit, - ts.GetVarietyId, - ts.PayVarietyId, - ts.GetUnderlyingCode, - ts.PayUnderlyingCode, - ts.GetLongShort, - ts.PayLongShort, - ts.GetSpotPrice, - ts.PaySpotPrice, - ts.GetTradePrice, - ts.PayTradePrice, - ts.GetSwapTimeAndRate, - ts.PaySwapTimeAndRate, - ts.GetFixedProfit, - ts.PayFixedProfit, - ts.GetMarginRate, - ts.PayMarginRate, - ts.GetTradeAmount, - ts.PayTradeAmount, - tr.ContractCode, - td.Paths, - t.QuoteCurrency, - t.SettlementCurrency, - ts.GetUnAnnualRate, - ts.GetSingleFee, - ts.PayUnAnnualRate, - ts.PaySingleFee, - ts.SwapType, - tc.Notional, - tc.UnwindNotional, - tc.FinalPrice, - }).OrderBy(O => O.OptDate).ToArray().Where(O => !codeList.Contains(O.id + "")).ToArray(); - - List ids = query.Select(O => O.id).ToList(); - List delIds = new List(); - if (_operationType == OptFlagsEnum.D) - { - delIds = DbContext.TradeAuditLog.Where(O => ids.Contains(O.TradeId) && O.OptDate >= _reqInfo.ReportDate && O.OptDate < nextDate && O.OptType == "删除交易").Select(O => O.TradeId).ToList(); - } - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - Dictionary reportDescDic = DbContext.AppConfig.Where(O => O.PGroup == ConsAppConfig.ReportDescSwap).ToDictionary(K => K.PName, V => V.PValue); - foreach (var item in query) - { - var cacheValue = item.id.ToString() + item.isSettle; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - //如果存在重复数据,则始终用较新的数据 - SwapEquityPaymentModel info = new SwapEquityPaymentModel(); - - info.ConfirmationNo = item.ContractCode; - var currentDealCodes = ReportStatus.GetCacheInfo(DataFlagsEnum.A1005.ToString());//取出这一次报送交易要素的交易编号 - var currentSettleCodes = ReportStatus.GetCacheInfo(DataFlagsEnum.A1006.ToString()).Select(O => O.Split('_')[0]);//取出这一次报送交易要素的交易编号 - if ((!item.isSettle && !currentDealCodes.Contains(item.id.ToString())) || (item.isSettle && !currentSettleCodes.Contains(item.id.ToString()))) - { - continue;//跳过交易要素还没报送的确认书附件; - } - if (item.isSettle) - { - var tempDate = item.ValueDate; - var count = db.trade_cash.Where(O => O.TradeId == item.id && O.ValueDate < tempDate && (O.Action == "系统操作-行权费" || O.Action == "系统操作-平仓费")).Select(O => O.ValueDate).ToHashSet().Count; - count += db.ExtensionTime.Where(O => O.TradeId == item.id && O.OptDate < tempDate).Select(O => O.OptDate).ToArray().Select(O => O.GetValueOrDefault().Date).ToHashSet().Count; - info.DurationEventNO = count.ToString("0000"); - } - List notes = base.GetReportNotes(formatInfoTag(info)); - SACReportNotes note = notes.FirstOrDefault(O => O.InfoCache.Contains(item.ValueDate.ToString("yyyy-MM-dd")) && O.InfoCache.Contains(item.isSettle.ToString())); - if (note == null && _operationType == OptFlagsEnum.A) - { - info.OperationType = OptFlagsEnum.A; - note = new SACReportNotes() - { - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - if (!note.changeStatus) - { - continue;//交易没有被修改过,跳过 - } - info.OperationType = OptFlagsEnum.U; - note.IsValid = true; - break; - case OptFlagsEnum.D: - if (!delIds.Contains(item.id)) - { - continue;//交易没有被删除,跳过 - } - info.OperationType = OptFlagsEnum.D; - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - if (info.OperationType != _operationType) - { - continue; - } - if (info.OperationType != OptFlagsEnum.D && (!item.tradeValid || !item.tradecashValid || !item.tradeContractRValid)) - {//非废止报送中,应跳过所有存在无效数据的数据 - continue; - } - if (metaDic.ContainsKey(item.id)) - { - var metaInfo = metaDic[item.id]; - var tradingPlace = metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) ? TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] : ""; - if (tradingPlace == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId;//确认书编号; - } - var swapEquityPayment = new SwapEquityPaymentTupleModel(); - var longShort = item.IsPayFloatingProfit ? item.PayLongShort : item.GetLongShort; - if (item.SwapType == "普通") - { - swapEquityPayment.PaymentMethod = ConsReport.PaymentMethodMap["权益收益(" + longShort + ")"]; - } - else - { - swapEquityPayment.PaymentMethod = ConsReport.SwapTypeMap["权益收益" + item.SwapType]; - } - swapEquityPayment.Payer = item.IsPayFloatingProfit ? ConsReport.PayerMap["甲方"] : ConsReport.PayerMap["乙方"]; - - var customizedResultsGet = QdpHelper.ParseAutocallCustomizedInfo(item.GetSwapTimeAndRate); - var getSwapRates = customizedResultsGet.Item2.Distinct(); - var customizedResultsPay = QdpHelper.ParseAutocallCustomizedInfo(item.PaySwapTimeAndRate); - var paySwapRates = customizedResultsPay.Item2.Distinct(); - if (item.IsGetFloatingProfit) - { - var getSwapDates = customizedResultsGet.Item1.Distinct(); - if (getSwapDates.Count() == 1) - { - Date date = getSwapDates.First(); - swapEquityPayment.PaymentFreq = date == new Date(item.TradeDate.Value) ? PaymentFreqMap["期初支付"] : PaymentFreqMap["期末支付"]; - } - else - { - swapEquityPayment.PaymentFreq = PaymentFreqMap["期间多次支付"]; - } - swapEquityPayment.InterestRate = (getSwapRates.FirstOrDefault() * 100).ToString(); - } - else - { - var paySwapDates = customizedResultsPay.Item1.Distinct(); - if (paySwapDates.Count() == 1) - { - Date date = paySwapDates.First(); - swapEquityPayment.PaymentFreq = date == new Date(item.TradeDate.Value) ? PaymentFreqMap["期初支付"] : PaymentFreqMap["期末支付"]; - } - else - { - swapEquityPayment.PaymentFreq = PaymentFreqMap["期间多次支付"]; - } - swapEquityPayment.InterestRate = (paySwapRates.FirstOrDefault() * 100).ToString(); - } - swapEquityPayment.OpenandClosingDate = item.ValueDate.ToString("yyyy-MM-dd"); - var codeInfo = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode); - swapEquityPayment.UndrlygAssetTradgPlc = string.IsNullOrWhiteSpace(codeInfo.MarketName) ? "其他" : codeInfo.MarketName; - - if (SwapUndrlygAssetDtldTypeMap.TryGetValue(ConsGlobal.InstrumentType.GetDesc(codeInfo.UnderlyingInstrumentType), out var AssetDtldType)) - { - swapEquityPayment.UndrlygAssetDtldType = AssetDtldType; - } - else - { - swapEquityPayment.UndrlygAssetDtldType = UndrlygAssetDtldTypeMap["其他标的"]; - } - var rate = new EodModule.EodCurrencyRateService(UserInfo).GetCurrencyRate(item.QuoteCurrency, "CNY", item.ValueDate); - var notional = item.isSettle ? (item.UnwindNotional ?? 0) : item.Notional; - var price = (item.isSettle ? item.FinalPrice : item.SpotPrice) ?? 0; - swapEquityPayment.UndrlygAssetCode = codeInfo.UnderlyingCode; - swapEquityPayment.UndrlygAssetName = codeInfo.UnderlyingName; - swapEquityPayment.UndrlygAssetAmt = (notional / codeInfo.CountRatio / codeInfo.ContractSize).ToString("0.000000"); - swapEquityPayment.ContractMultiplier = codeInfo.ContractSize.ToString("0"); - swapEquityPayment.UndrlygAssetPrice = (price * rate).ToString("0.0000"); - var notionalAmt = (price * notional / codeInfo.CountRatio * rate); - if (item.isSettle) - { - var list = ReportStatus.GetCacheInfo($"{DataFlagsEnum.A1006.ToString()}_{info.ConfirmationNo}_{info.DurationEventNO}"); - if (list.Count > 0 && double.TryParse(list[0], out var temp)) - { - notionalAmt = temp; - } - } - else - { - var list = ReportStatus.GetCacheInfo($"{DataFlagsEnum.A1005.ToString()}_{info.ConfirmationNo}"); - if (list.Count > 0 && double.TryParse(list[0], out var temp)) - { - notionalAmt = temp; - } - } - if (longShort == "多头") - { - swapEquityPayment.UndrlygAssetPosition = UndrlygAssetPositionMap[item.isSettle ? "平多仓" : "开多仓"]; - swapEquityPayment.LNotinalPrincipleAmt = notionalAmt.ToString("0.0000"); - } - else - { - swapEquityPayment.UndrlygAssetPosition = UndrlygAssetPositionMap[item.isSettle ? "平空仓" : "开空仓"]; - swapEquityPayment.SNotinalPrincipleAmt = (-notionalAmt).ToString("0.0000"); - } - info.SwapEquityPaymentTuple = new List(); - info.SwapEquityPaymentTuple.Add(swapEquityPayment); - - info.ExceID = base.formatExceID(); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.InfoCache = $"{{\"DueDate\":\"{swapEquityPayment.OpenandClosingDate}\",\"OptType\":\"{(item.isSettle)}\",\"Tag\":\"{info.ConfirmationNo}\",\"DurationEventNO\":\"{info.DurationEventNO}\",\"Source\":\"System\"}}"; - note.ExceId = info.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.DataId = item.tcId.ToString(); - note.BizId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView) - { - dataList.AddRange(GetSwapEquityPaymentModelFromView()); - } - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.SwapEquityPayment = dataList; @@ -363,7 +67,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(SwapEquityPaymentModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 if (note == null) { note = new SACReportNotes() @@ -392,7 +96,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -412,12 +116,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private List GetSwapEquityPaymentModel() { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("收益互换交易权益端支付")) { - var cacheKey = $"{BusiDataType}"; - DataTable dt = _excelDataSource.Tables["收益互换交易权益端支付"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["收益互换交易权益端支付"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -427,12 +130,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][1]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -442,11 +151,12 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - SwapEquityPaymentModel model = new SwapEquityPaymentModel(); - - model.ConfirmationNo = GetDataSetValue(dt, i, 0); - model.OperationType = optType; - model.DurationEventNO = GetDataSetValue(dt, i, 2); + var model = new SwapEquityPaymentModel + { + ConfirmationNo = GetDataSetValue(dt, i, 0), + OperationType = optType, + DurationEventNO = GetDataSetValue(dt, i, 2) + }; if (string.IsNullOrWhiteSpace(model.DurationEventNO)) { model.DurationEventNO = null; @@ -455,11 +165,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service model.Blank2 = GetDataSetValue(dt, i, 4); var cacheValue = formatInfoTag(model); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } - List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); + List notes = base.GetReportNotes(ReportType, formatInfoTag(model), dataSource: SACReportNotesCache); var note = notes.LastOrDefault(); if (note == null && _operationType == OptFlagsEnum.A) { @@ -497,114 +207,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.BizID = note.BizId; } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - note.id = 0; - note.ExceId = model.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(model, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - return result; - } - - private List GetSwapEquityPaymentModelFromView() - { - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("互换交易权益端支付")) - { - var cacheKey = $"{BusiDataType}"; - DataTable dt = _viewDataSource.Tables["互换交易权益端支付"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - var optType = OptFlagsEnum.NONE; - switch (GetDataSetValue(dt, i, "OPERATIONTYPE")) - { - case "A": - optType = OptFlagsEnum.A; - break; - case "U": - optType = OptFlagsEnum.U; - break; - case "D": - optType = OptFlagsEnum.D; - break; - } - if (optType != _operationType) - { - continue; - } - - SwapEquityPaymentModel model = new SwapEquityPaymentModel(); - model.IgnoreCheck = true; - model.ConfirmationNo = GetDataSetValue(dt, i, "CONFIRMATIONNO"); - model.OperationType = optType; - model.DurationEventNO = GetDataSetValue(dt, i, "DURATIONEVENTNO"); - if (string.IsNullOrWhiteSpace(model.DurationEventNO)) - { - model.DurationEventNO = null; - } - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); - - var cacheValue = formatInfoTag(model); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); - var note = notes.LastOrDefault(); - if (note == null && _operationType == OptFlagsEnum.A) - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"KingstarView\"}}", - IsValid = true, - }; - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - } - - model.SwapEquityPaymentTuple = GetSwapEquityPaymentTupleFromView(model.ConfirmationNo); - - if (model.OperationType != OptFlagsEnum.A) - { - model.BizID = note.BizId; - } - model.ExceID = base.formatExceID(); - result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -632,30 +237,31 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service /// private List GetSwapEquityPaymentTuple(string confirmationNo) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("权益端支付明细")) { - DataTable dt = _excelDataSource.Tables["权益端支付明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["权益端支付明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != confirmationNo) + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; } - SwapEquityPaymentTupleModel model = new SwapEquityPaymentTupleModel(); - - model.UndrlygAssetCode = GetDataSetValue(dt, i, 0); - model.PaymentMethod = ConsReport.PaymentMethodMap[GetDataSetValue(dt, i, 1)]; - model.Payer = ConsReport.PayerMap[GetDataSetValue(dt, i, 2)]; - model.PaymentFreq = ConsReport.PaymentFreqMap[GetDataSetValue(dt, i, 3)]; - model.OpenandClosingDate = GetDataSetValue(dt, i, 4); - model.UndrlygAssetDtldType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 5)]; + var model = new SwapEquityPaymentTupleModel + { + UndrlygAssetCode = GetDataSetValue(dt, i, 0), + PaymentMethod = ConsReport.PaymentMethodMap[GetDataSetValue(dt, i, 1)], + Payer = ConsReport.PayerMap[GetDataSetValue(dt, i, 2)], + PaymentFreq = ConsReport.PaymentFreqMap[GetDataSetValue(dt, i, 3)], + OpenandClosingDate = GetDataSetValue(dt, i, 4), + UndrlygAssetDtldType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 5)] + }; model.UndrlygAssetCode = GetDataSetValue(dt, i, 6); model.UndrlygAssetName = GetDataSetValue(dt, i, 7); model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 8); @@ -675,54 +281,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - /// - /// 获取权益端支付明细 - /// - /// - /// - private List GetSwapEquityPaymentTupleFromView(string confirmationNo) - { - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("权益端支付")) - { - DataTable dt = _viewDataSource.Tables["权益端支付"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - - if (GetDataSetValue(dt, i, "CONFIRMATIONNO") != confirmationNo) - { - continue; - } - - SwapEquityPaymentTupleModel model = new SwapEquityPaymentTupleModel(); - model.UndrlygAssetCode = GetDataSetValue(dt, i, "UNDRLYGASSETCODE"); - model.PaymentMethod = GetDataSetValue(dt, i, "PAYMENTMETHOD"); - model.Payer = GetDataSetValue(dt, i, "PAYER"); - model.PaymentFreq = GetDataSetValue(dt, i, "PAYMENTFREQ"); - model.OpenandClosingDate = GetDataSetValue(dt, i, "OPENANDCLOSINGDATE"); - model.UndrlygAssetDtldType = GetDataSetValue(dt, i, "UNDRLYGASSETDTLDTYPE"); - model.UndrlygAssetCode = GetDataSetValue(dt, i, "UNDRLYGASSETCODE"); - model.UndrlygAssetName = GetDataSetValue(dt, i, "UNDRLYGASSETNAME"); - model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, "UNDRLYGASSETTRADEPLC"); - model.UndrlygAssetPrice = GetDataSetValue(dt, i, "UNDRLYGASSETPRICE"); - model.UndrlygAssetPosition = GetDataSetValue(dt, i, "UNDRLYGASSETPOSITION"); - model.UndrlygAssetAmt = GetDataSetValue(dt, i, "UNDRLYGASSETAMT"); - model.ContractMultiplier = GetDataSetValue(dt, i, "CONTRACTMULTIPLIER"); - model.LNotinalPrincipleAmt = GetDataSetValue(dt, i, "LNOTINALPRINCIPLEAMT"); - model.SNotinalPrincipleAmt = GetDataSetValue(dt, i, "SNOTINALPRINCIPLEAMT"); - model.InterestRate = GetDataSetValue(dt, i, "INTERESTRATE"); - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); - - result.Add(model); - } - } - return result; - } - private string formatInfoTag(SwapEquityPaymentModel model, bool suffixType = false) { - string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_权益端支付_{model.DurationEventNO}_"; + var result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_成交_权益端支付_{model.DurationEventNO}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -730,25 +291,41 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 6) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.SwapEquityPayment != null) { - CheckHelper helper = new CheckHelper(); - CheckHelper tupleHelper = new CheckHelper(); - for (int i = 0; i < model.SwapEquityPayment.Count; i++) + var helper = new CheckHelper(); + var tupleHelper = new CheckHelper(); + for (var i = 0; i < model.SwapEquityPayment.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.SwapEquityPayment[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (item.SwapEquityPaymentTuple != null) { - for (int j = 0; j < item.SwapEquityPaymentTuple.Count; j++) + for (var j = 0; j < item.SwapEquityPaymentTuple.Count; j++) { var listItem = new List(); var attItem = item.SwapEquityPaymentTuple[j]; @@ -758,16 +335,21 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (listItem.Count > 0) { - var temp = new SacInfo("SwapEquityPaymentTuple", j); - temp.SubMaps = new List(listItem); + var temp = new SacInfo("SwapEquityPaymentTuple", j) + { + SubMaps = new List(listItem) + }; listRoot.Add(temp); } } } if (listRoot.Count > 0) { - var errMsg = new SacInfo("SwapEquityPayment", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("SwapEquityPayment", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -791,7 +373,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs index cb647262..61371ac3 100644 --- a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportSwapTerminationService.cs @@ -1,13 +1,19 @@ -using System.Data; +using Microsoft.Office.Interop.Excel; +using NPOI.SS.UserModel; +using System.Data; +using System.Net; using System.Text.RegularExpressions; using YieldChain.Helpers; using YLErp.BLL; +using YLErp.Commons; +using YLErp.DBModels; using YLErp.DBModels.Consts; using YLErp.DBModels.Enums; +using YLErp.Models; using YLErp.Modules.EodModule; using YLErp.Modules.SuperviseReportModule.SAC.Common; using YLErp.Modules.SuperviseReportModule.SAC.Model; -using static alglib; +using static YLErp.ConsGlobal; using static YLErp.DBModels.Consts.ConsReport; namespace YLErp.Modules.SuperviseReportModule.SAC.Service @@ -24,55 +30,42 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1006; - private List _validOperationType = null; + private List? _validOperationType = null; public override List ValidOperationType { get { - if (_validOperationType == null) - { - _validOperationType = new List() { + _validOperationType ??= new List() { OptFlagsEnum.A, OptFlagsEnum.U, OptFlagsEnum.D, }; - } return _validOperationType; } } protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_SwapDurationManagement; - List noteList = new List(); + + readonly List noteList = new(); + IEnumerable SACReportNotesCache = null; + IEnumerable SACReportNotesCache_confirmation = null; protected override BodyModel GenerateBody(out bool noData, out List fileList) { fileList = new List(); - BodyModel model = new BodyModel(); - List dataList = new List(); - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.Template) == SAC_ReportDataSourceEnum.Template) + var model = new BodyModel(); + SACReportNotesCache = base.InitReportNotes(ReportType); + SACReportNotesCache_confirmation = base.InitReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation); + var dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) { - dataList = GetSwapDurationManagementModel(out fileList); + dataList = GetSwapDurationManagementModel(ref fileList); } - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.System) == SAC_ReportDataSourceEnum.System) - { - var cacheKey = $"{BusiDataType}"; - var nextDate = _reqInfo.ReportDate.AddDays(1); - using (var db = new YLContext()) - { - dataList.AddRange(GetOptionTerminationExtensionTimeFromDb(db, cacheKey, nextDate)); - - dataList.AddRange(GetOptionTerminationSettlementFromDb(db, cacheKey, nextDate)); - } - } - - if ((PS.Config.ErpElement.SAC_ReportDataSource & SAC_ReportDataSourceEnum.KingstarView) == SAC_ReportDataSourceEnum.KingstarView) - { - dataList.AddRange(GetSwapDurationManagementModelFromView(out fileList)); - } - var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); if (subsystemDataList != null && subsystemDataList.Count > 0) + { dataList.AddRange(subsystemDataList); + } noData = dataList.Count == 0; model.SwapDurationManagement = dataList; @@ -81,9 +74,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service public bool AddSubsystemNote(SwapDurationManagementModel model, List fileList, string tag) { - SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 - var isExtensionTime = model.DurationOperationType == ConsReport.OperationTypeMap["展期"]; - DateTime date = DateTime.MinValue; + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true), dataSource: SACReportNotesCache).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + var isExtensionTime = model.DurationOperationType == ConsReport.SwapOperationTypeMap["展期"]; + var date = DateTime.MinValue; if (isExtensionTime) { DateTime.TryParse(model.RenewalDate, out date); @@ -96,8 +89,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { if (isExtensionTime) { - string oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); + var oldDateStr = ""; + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { @@ -128,8 +121,8 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service case OptFlagsEnum.U: if (isExtensionTime) { - string oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); + var oldDateStr = ""; + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { @@ -158,7 +151,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } var extensionTimeInfo = isExtensionTime ? "-" : ""; - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -176,436 +169,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return true; } - private List GetOptionTerminationExtensionTimeFromDb(YLContext db, string cacheKey, DateTime nextDate) - { - List dataList = new List(); - var extensionTimeList = (from et in db.ExtensionTime - join t in db.trade - on et.TradeId equals t.id - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - join ts in db.trade_swap - on t.id equals ts.TradeId - where - et.OptDate >= _reqInfo.ReportDate && - et.OptDate < nextDate && - t.TradeType == "收益互换" && - tr.IsValid - select new - { - et.id, - et.TradeId, - et.OldMaturityDate, - et.NewMaturityDate, - et.IsValid, - et.OptDate, - tr.ContractCode, - t.StockEqvNotional, - ts.GetMarginRate, - ts.PayMarginRate - }).ToArray(); - - List ids = extensionTimeList.Select(O => O.TradeId).ToList(); - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - foreach (var item in extensionTimeList) - { - var cacheValue = item.id.ToString(); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - if (metaDic.ContainsKey(item.TradeId)) - { - var metaInfo = metaDic[item.TradeId]; - if (metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) && TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - var info = new SwapDurationManagementModel(); - - //info.TradeId = item.TradeId.ToString(); - var tempDate = item.OptDate.GetValueOrDefault().Date; - var count = db.trade_cash.Where(O => O.TradeId == item.TradeId && O.ValueDate < tempDate && (O.Action == "系统操作-行权费" || O.Action == "系统操作-平仓费")).Select(O => O.ValueDate).ToHashSet().Count; - count += db.ExtensionTime.Where(O => O.TradeId == item.TradeId && O.OptDate < tempDate).Select(O => O.OptDate).ToArray().Select(O => O.GetValueOrDefault().Date).ToHashSet().Count; - info.DurationEventNO = count.ToString("0000"); - info.ConfirmationNo = item.ContractCode; - info.DurationOperationDate = item.OptDate?.ToString("yyyy-MM-dd"); - List notes = base.GetReportNotes(ReportType, $"_{info.ConfirmationNo.Replace("_", "-")}_", true); - var note = notes.FirstOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(info, extensionTimeInfo: item.id.ToString()))); - if (!item.IsValid) - {//当前信息是无效的,报送过就是废止,否则就不需要报 - if (note != null) - { - info.OperationType = OptFlagsEnum.D; - } - else - { - continue; - } - } - else - {//当前信息是有效的,报送过,就是修改,否则就是新增 - if (note == null) - { - info.OperationType = OptFlagsEnum.A; - } - else - { - if (!note.changeStatus) - { - continue; - } - info.OperationType = OptFlagsEnum.U; - } - } - if (info.OperationType != _operationType) - { - continue; - } - switch (info.OperationType) - { - case OptFlagsEnum.A: - note = new SACReportNotes() - { - IsValid = true, - }; - break; - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId; - } - var infoCache = JsonHelper.Deserialize>(note?.InfoCache) ?? new Dictionary(); - var oldMaturityDate = infoCache.TryGetValue("NewMaturityDate", out var date) ? DateTime.Parse(date) : item.OldMaturityDate; - var newMaturityDate = item.NewMaturityDate; - if (info.OperationType == OptFlagsEnum.D) - { - oldMaturityDate = infoCache.TryGetValue("OldMaturityDate", out date) ? DateTime.Parse(date) : item.OldMaturityDate; - newMaturityDate = infoCache.TryGetValue("NewMaturityDate", out date) ? DateTime.Parse(date) : item.NewMaturityDate; - } - else - { - if (newMaturityDate <= oldMaturityDate) - { - throw new ServiceException($"确认书编号:{item.ContractCode}\r\n新展期日:{newMaturityDate.ToString("yyyy-MM-dd")}\r\n原到期日:{oldMaturityDate.ToString("yyyy-MM-dd")}\r\n新展期日应大于原到期日"); - } - } - //info.ExpirationDate = item.OldMaturityDate.ToString("yyyy-MM-dd"); - info.DurationOperationType = OperationTypeMap["展期"]; - info.RenewalDate = newMaturityDate.ToString("yyyy-MM-dd"); - info.Balance = Math.Max(item.StockEqvNotional, 0).ToString("0.00"); - info.MarginRatio = ((item.GetMarginRate ?? item.PayMarginRate) * 100)?.ToString("0.00"); - info.ExceID = base.formatExceID(); - - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - dataList.Add(info); - note.id = 0; - note.ExceId = info.ExceID; - note.InfoCache = $"{{\"Tag\":\"{info.ConfirmationNo}\",\"OldMaturityDate\":\"{oldMaturityDate.ToString("yyyy-MM-dd")}\",\"NewMaturityDate\":\"{newMaturityDate.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{info.DurationEventNO}\",\"Source\":\"System\"}}"; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true, item.id.ToString()); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - return dataList; - } - - private List GetOptionTerminationSettlementFromDb(YLContext db, string cacheKey, DateTime nextDate) - { - List dataList = new List(); - var actions = new List() { "系统操作-平仓费", "系统操作-行权费"/*, "系统操作-互换"*/ }; - //当天有回退记录的资金记录 - var query = (from t in db.trade - join log in db.TradeAuditLog on t.id equals log.TradeId - join tc in db.trade_cash on t.id equals tc.TradeId - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - join ts in db.trade_swap - on t.id equals ts.TradeId - where log.OptDate >= _reqInfo.ReportDate && log.OptDate < nextDate && log.OptType == "交易回退" && - (actions.Contains(tc.Action) || (tc.Action == "系统操作-互换" && tc.ExerciseWay == "到期行权")) && /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换" && tr.IsValid - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - tc.ValueDate, - tc.Notional, - tc.UnwindNotional, - tc.Amount, - t.OriginalNotional, - tr.ContractCode, - t.QuoteCurrency, - t.SettlementCurrency, - ts.SwapType, - ts.IsPayFloatingProfit, - ts.GetLongShort, - ts.PayLongShort, - ts.GetMarginRate, - ts.PayMarginRate, - }).Union//当天有了结的资金记录 - (from t in db.trade - join tc in db.trade_cash - on t.id equals tc.TradeId - join tr in db.trade_contract_r.Where(O => O.Type == "交易确认书") - on t.id equals tr.TradeId - join td in db.trade_contract_document - on tr.ContractCode equals td.Code - join ts in db.trade_swap - on t.id equals ts.TradeId - where tc.ValueDate == _reqInfo.DataDate && - t.ValidState != "InValid" && tc.ValidState != "InValid" && !tc.IsDeleted && tr.IsValid && - /*t.UnderlyingInstrumentType == "Stock" &&*/ t.TradeType == "收益互换" && - (actions.Contains(tc.Action) || (tc.Action == "系统操作-互换" && tc.ExerciseWay == "到期行权")) - select new - { - tcId = tc.id, - tc.OptDate, - tradeValid = t.ValidState != "InValid", - tradecashValid = tc.ValidState != "InValid" && !tc.IsDeleted, - tradeContractRValid = tr.IsValid, - t.id, - t.ClientId, - t.TradeDate, - t.ExerciseDate, - t.SettlementDate, - t.ExerciseMode, - t.BuySell, - TradeType = t.StructureType ?? t.TradeType, - t.OptionType, - t.OriginalStockEqvNotional, - t.StockEqvNotionalReal, - t.IsMoneynessOption, - t.SpotPrice, - t.Strike, - t.MarginTemplateName, - t.MarginType, - t.InitialMargin, - t.UnderlyingCode, - t.AnnualizeFactor, - tc.ValueDate, - tc.Notional, - tc.UnwindNotional, - tc.Amount, - t.OriginalNotional, - tr.ContractCode, - t.QuoteCurrency, - t.SettlementCurrency, - ts.SwapType, - ts.IsPayFloatingProfit, - ts.GetLongShort, - ts.PayLongShort, - ts.GetMarginRate, - ts.PayMarginRate, - }).ToArray().GroupBy(O => new { O.id, O.ValueDate }).ToDictionary(K => K.Key, V => V.ToList()); - List ids = query.Keys.Select(O => O.id).ToList(); - Dictionary> metaDic = DbContext.TradeMeta.Where(O => ids.Contains(O.TradeId)).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.ToDictionary(K1 => K1.MetaKey, V1 => V1.MetaValue)); - foreach (var item in query.ToArray()) - { - var cacheValue = item.Key.id.ToString() + item.Key.ValueDate.ToString("_yyyy-MM-dd"); - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - if (metaDic.ContainsKey(item.Key.id)) - { - var metaInfo = metaDic[item.Key.id]; - if (metaInfo.ContainsKey(ConsTradeMetaKey.TradingPlace) && TradingPlaceMap[metaInfo[ConsTradeMetaKey.TradingPlace]] == "1")//跳过交易场所为报价系统的交易; - { - continue; - } - } - var info = new SwapDurationManagementModel(); - - //info.TradeId = item.Key.id.ToString(); - var validItem = item.Value.FirstOrDefault(O => O.tradecashValid); - var invalidItem = item.Value.FirstOrDefault(O => !O.tradecashValid); - var obj = invalidItem ?? validItem; - var tempDate = obj.ValueDate; - var tcQuery = db.trade_cash.Where(O => O.TradeId == obj.id && O.ValueDate < tempDate && actions.Contains(O.Action)); - var count = tcQuery.Select(O => O.ValueDate).ToHashSet().Count; - count += db.ExtensionTime.Where(O => O.TradeId == obj.id && O.OptDate < tempDate).Select(O => O.OptDate).ToArray().Select(O => O.GetValueOrDefault().Date).ToHashSet().Count; - info.DurationEventNO = count.ToString("0000"); - info.DurationOperationDate = obj.ValueDate.ToString("yyyy-MM-dd"); - info.ConfirmationNo = obj.ContractCode; - List notes = base.GetReportNotes(ReportType, $"_{info.ConfirmationNo.Replace("_", "-")}_", true); - var note = notes.FirstOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(info)) && O.InfoCache.Contains(info.DurationOperationDate)); - if (validItem == null && invalidItem != null) - {//有效资金记录不存在,无效资金记录存在时,当天报送过就是废止,否则就不需要报 - obj = invalidItem; - if (note != null) - { - info.OperationType = OptFlagsEnum.D; - } - else - { - continue; - } - } - else - {//有效资金记录存在时,当天报送过,就是修改,否则就是新增 - obj = validItem; - if (note == null) - { - info.OperationType = OptFlagsEnum.A; - } - else - { - if (!note.changeStatus) - { - continue; - } - info.OperationType = OptFlagsEnum.U; - } - } - if (info.OperationType != _operationType) - { - continue; - } - switch (info.OperationType) - { - case OptFlagsEnum.A: - note = new SACReportNotes() - { - IsValid = true, - }; - break; - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - } - if (info.OperationType != OptFlagsEnum.A) - { - info.BizID = note.BizId; - } - info.DurationOperationType = OperationTypeMap["终止"]; - if (obj.SwapType == "普通") - { - var longShort = obj.IsPayFloatingProfit ? obj.PayLongShort : obj.GetLongShort; - info.SwapType = ConsReport.SwapTypeMap["客户" + longShort]; - } - else - { - info.SwapType = ConsReport.SwapTypeMap[obj.SwapType]; - } - var quoteRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(obj.QuoteCurrency, "CNY", obj.ValueDate); - var settlementRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(obj.SettlementCurrency, "CNY", obj.ValueDate); - var currentStockEqvNotional = Math.Round(Math.Min((obj.UnwindNotional / obj.OriginalNotional * obj.OriginalStockEqvNotional) ?? 0, obj.OriginalStockEqvNotional ?? 0) * quoteRate, 2); - var latestStockEqvNotional = Math.Round(Math.Min((obj.Notional / obj.OriginalNotional * obj.OriginalStockEqvNotional) ?? 0, obj.OriginalStockEqvNotional ?? 0) * quoteRate, 2); - var isComplete = Math.Abs(obj.Notional - (obj.UnwindNotional ?? 0)) < 1e-4; - if (isComplete) - { - var tcArr = tcQuery.Where(O => O.ValidState != "InValid" && O.IsDeleted == false).ToArray(); - var originalStockEqvNotional = obj.OriginalStockEqvNotional ?? 0; - currentStockEqvNotional = originalStockEqvNotional - tcArr.Sum(O => Math.Round(Math.Min((O.UnwindNotional / obj.OriginalNotional * originalStockEqvNotional) ?? 0, originalStockEqvNotional) * quoteRate, 2)); - latestStockEqvNotional = currentStockEqvNotional; - } - //info.TerminationAmount = currentStockEqvNotional.ToString("0.00"); - info.ChangeAmount = (-currentStockEqvNotional).ToString("0.00"); - info.Balance = Math.Max((latestStockEqvNotional - currentStockEqvNotional), 0).ToString("0.00"); - info.AmountPaidThisTime = (obj.Amount * settlementRate * -1).ToString(); - info.MarginRatio = ((obj.GetMarginRate ?? obj.PayMarginRate) * 100)?.ToString("0.00"); - if (double.TryParse(info.Balance, out var temp) && temp > 0) - { - var currentPosition = new CurrentPositionDetailModel(); - currentPosition.UndrlygAssetCode = obj.UnderlyingCode; - var codeInfo = DataCacheProvider.GetUnderlyingDataSource().GetData(obj.UnderlyingCode); - currentPosition.UndrlygAssetTradgPlc = string.IsNullOrWhiteSpace(codeInfo.MarketName) ? "其他" : codeInfo.MarketName; - - if (SwapUndrlygAssetDtldTypeMap.TryGetValue(ConsGlobal.InstrumentType.GetDesc(codeInfo.UnderlyingInstrumentType), out var AssetDtldType)) - { - currentPosition.UndrlygAssetDtldType = AssetDtldType; - } - else - { - currentPosition.UndrlygAssetDtldType = UndrlygAssetDtldTypeMap["其他标的"]; - } - var notional = obj.Notional - (obj.UnwindNotional ?? 0); - currentPosition.UndrlygAssetName = codeInfo.UnderlyingName; - currentPosition.InvestorPosition = ConsReport.SwapTypeMap["客户" + (obj.IsPayFloatingProfit ? obj.PayLongShort : obj.GetLongShort)]; - currentPosition.UndrlygAssetAmt = (notional / codeInfo.CountRatio / codeInfo.ContractSize).ToString("0.000000"); - currentPosition.ContractMultiplier = codeInfo.ContractSize.ToString("0"); - currentPosition.UndrlygAssetPrice = (obj.SpotPrice * quoteRate)?.ToString("0.0000"); - currentPosition.NotinalPrincipleAmt = Math.Max((latestStockEqvNotional - currentStockEqvNotional), 0).ToString("0.0000"); - info.CurrentPositionDetails = new List() { currentPosition }; - } - info.ExceID = base.formatExceID(); - - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - ReportStatus.AddCacheInfo($"{cacheKey}_{info.ConfirmationNo}_{info.DurationEventNO}", currentStockEqvNotional.ToString("0.00")); - dataList.Add(info); - note.id = 0; - note.ExceId = info.ExceID; - note.InfoCache = $"{{\"Tag\":\"{info.ConfirmationNo}\",\"ValueDate\":\"{info.DurationOperationDate}\",\"DurationEventNO\":\"{info.DurationEventNO}\",\"Source\":\"System\"}}"; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(info, true); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - return dataList; - } - - private List GetSwapDurationManagementModel(out List fileList) + private List GetSwapDurationManagementModel(ref List fileList) { fileList = new List(); - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("互换交易存续期明细")) { - string sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); - var cacheKey = $"{BusiDataType}"; - DataTable dt = _excelDataSource.Tables["互换交易存续期明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var sourcePath = Path.Combine(_excelDataSourceRootPath, "附件"); + var dt = _excelDataSource.Tables["互换交易存续期明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { @@ -615,12 +187,18 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service var optType = OptFlagsEnum.NONE; switch (dt.Rows[i][1]?.ToString()) { + case "0": + case "A": case "首次": optType = OptFlagsEnum.A; break; + case "1": + case "U": case "变更": optType = OptFlagsEnum.U; break; + case "2": + case "D": case "废止": optType = OptFlagsEnum.D; break; @@ -630,27 +208,28 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service continue; } - SwapDurationManagementModel model = new SwapDurationManagementModel(); + var model = new SwapDurationManagementModel + { + ConfirmationNo = GetDataSetValue(dt, i, 0), + OperationType = optType, + SwapType = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 2)], + DurationEventNO = GetDataSetValue(dt, i, 3), + DurationOperationType = ConsReport.SwapOperationTypeMap[GetDataSetValue(dt, i, 4)], + DurationOperationDate = GetDataSetValue(dt, i, 5), + RenewalDate = GetDataSetValue(dt, i, 6), + DefaultingParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 7)], + DefaultEvent = GetDataSetValue(dt, i, 8), + ChangeAmount = GetDataSetValue(dt, i, 9), + Balance = GetDataSetValue(dt, i, 10), + AmountPaidThisTime = GetDataSetValue(dt, i, 11), + MarginRatio = GetDataSetValue(dt, i, 12), + SwapDurationManagementAtt = GetDataSetValue(dt, i, 13), + Blank1 = GetDataSetValue(dt, i, 14), + Blank2 = GetDataSetValue(dt, i, 15) + }; - model.ConfirmationNo = GetDataSetValue(dt, i, 0); - model.OperationType = optType; - model.SwapType = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 2)]; - model.DurationEventNO = GetDataSetValue(dt, i, 3); - model.DurationOperationType = ConsReport.OperationTypeMap[GetDataSetValue(dt, i, 4)]; - model.DurationOperationDate = GetDataSetValue(dt, i, 5); - model.RenewalDate = GetDataSetValue(dt, i, 6); - model.DefaultingParty = ConsReport.FillPartyMap[GetDataSetValue(dt, i, 7)]; - model.DefaultEvent = GetDataSetValue(dt, i, 8); - model.ChangeAmount = GetDataSetValue(dt, i, 9); - model.Balance = GetDataSetValue(dt, i, 10); - model.AmountPaidThisTime = GetDataSetValue(dt, i, 11); - model.MarginRatio = GetDataSetValue(dt, i, 12); - model.SwapDurationManagementAtt = GetDataSetValue(dt, i, 13); - model.Blank1 = GetDataSetValue(dt, i, 14); - model.Blank2 = GetDataSetValue(dt, i, 15); - - var isExtensionTime = model.DurationOperationType == ConsReport.OperationTypeMap["展期"]; - DateTime date = DateTime.MinValue; + var isExtensionTime = model.DurationOperationType == ConsReport.SwapOperationTypeMap["展期"]; + var date = DateTime.MinValue; if (isExtensionTime) { DateTime.TryParse(model.RenewalDate, out date); @@ -660,7 +239,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service DateTime.TryParse(model.DurationOperationDate, out date); } var cacheValue = $"{model.ConfirmationNo}_{model.DurationEventNO}_"; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) { continue; } @@ -674,15 +253,15 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service fileList.Add(path); } var extensionTimeInfo = isExtensionTime ? "-" : ""; - List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_", true); + List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_", true, SACReportNotesCache); //永远查找现有成功报送了结的新增记录,而不是修改; var note = notes.LastOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); if (note == null && _operationType == OptFlagsEnum.A) { if (isExtensionTime) { - string oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); + var oldDateStr = ""; + var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A", dataSource: SACReportNotesCache_confirmation).FirstOrDefault(); oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; if (DateTime.TryParse(oldDateStr, out var oldDate)) { @@ -732,167 +311,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service { model.BizID = note.BizId; } - model.ExceID = base.formatExceID(); + model.ExceID = base.formatExceID(SACReportNotesCache); result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); - note.id = 0; - note.ExceId = model.ExceID; - note.CreateTime = DateTime.Now; - note.FileTag = FileTag; - note.ReportType = ReportType; - note.ReportDate = _reqInfo.ReportDate; - note.InfoTag = formatInfoTag(model, true, extensionTimeInfo); - note.OptTime = note.CreateTime; - note.RetCode = ""; - note.RetMsg = ""; - note.ReportResponse = false; - note.BizId = ""; - note.DataId = ""; - note.changeStatus = false; - noteList.Add(note); - } - } - return result; - } - - private List GetSwapDurationManagementModelFromView(out List fileList) - { - fileList = new List(); - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("互换交易存续期管理")) - { - var ftpHelper = new FtpHelper(PS.Config.ErpElement.KingstarView_RemotePath, PS.Config.ErpElement.KingstarView_RemoteUser, PS.Config.ErpElement.KingstarView_RemotePassword, PS.Config.ErpElement.KingstarView_FtpUsePassive, 3000, PS.Config.ErpElement.KingstarView_EnableSsl); - var cacheKey = $"{BusiDataType}"; - DataTable dt = _viewDataSource.Tables["互换交易存续期管理"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - - var optType = OptFlagsEnum.NONE; - switch (GetDataSetValue(dt, i, "OPERATIONTYPE")) - { - case "A": - optType = OptFlagsEnum.A; - break; - case "U": - optType = OptFlagsEnum.U; - break; - case "D": - optType = OptFlagsEnum.D; - break; - } - if (optType != _operationType) - { - continue; - } - - SwapDurationManagementModel model = new SwapDurationManagementModel(); - model.IgnoreCheck = true; - model.ConfirmationNo = GetDataSetValue(dt, i, "CONFIRMATIONNO"); - model.OperationType = optType; - - model.DurationEventNO = GetDataSetValue(dt, i, "DURATIONEVENTNO"); - model.DurationOperationType = GetDataSetValue(dt, i, "DURATIONOPERATIONTYPE"); - model.DurationOperationDate = GetDataSetValue(dt, i, "DURATIONOPERATIONDATE"); - model.RenewalDate = GetDataSetValue(dt, i, "RENEWALDATE"); - model.DefaultingParty = GetDataSetValue(dt, i, "DEFAULTINGPARTY"); - model.DefaultEvent = GetDataSetValue(dt, i, "DEFAULTEVENT"); - model.ChangeAmount = GetDataSetValue(dt, i, "CHANGEAMOUNT"); - model.Balance = GetDataSetValue(dt, i, "BALANCE"); - model.AmountPaidThisTime = GetDataSetValue(dt, i, "AMOUNTPAIDTHISTIME"); - model.MarginRatio = GetDataSetValue(dt, i, "MARGINRATIO"); - model.SwapDurationManagementAtt = GetDataSetValue(dt, i, "SWAPDURATIONMANAGEMENTATT"); - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); - - var isExtensionTime = model.DurationOperationType == ConsReport.OperationTypeMap["展期"]; - DateTime date = DateTime.MinValue; - if (isExtensionTime) - { - DateTime.TryParse(model.RenewalDate, out date); - } - else - { - DateTime.TryParse(model.DurationOperationDate, out date); - } - var cacheValue = $"{model.ConfirmationNo}_{model.DurationEventNO}_"; - if (ReportStatus.CheckCacheInfo(cacheKey, cacheValue)) - { - continue; - } - if (!string.IsNullOrWhiteSpace(model.SwapDurationManagementAtt)) - { - var downloadRet = ftpHelper.DownloadFile(CreateViewAttDownloadPath(model.SwapDurationManagementAtt), ViewLocalAttFileDir + @"\kingstar\", out string message); - LogFactory.GetLogger("ftpHelper.DownloadFile").Info($"下载结果:{ViewLocalAttFileDir},{model.SwapDurationManagementAtt},{downloadRet}"); - var path = downloadRet; - if (!ReportStatus.CheckFileLength(path)) - { - break; - } - fileList.Add(path); - model.SwapDurationManagementAtt = Path.GetFileName(path); - } - var extensionTimeInfo = isExtensionTime ? "-" : ""; - List notes = base.GetReportNotes(ReportType, $"_{model.ConfirmationNo.Replace("_", "-")}_", true); - //永远查找现有成功报送了结的新增记录,而不是修改; - var note = notes.LastOrDefault(O => O.IsValid && O.InfoTag.Contains(formatInfoTag(model, extensionTimeInfo: extensionTimeInfo)) && O.InfoCache.Contains(date.ToString("yyyy-MM-dd"))); - if (note == null && _operationType == OptFlagsEnum.A) - { - if (isExtensionTime) - { - string oldDateStr = ""; - var oldData = base.GetReportNotes(SuperviseReportTypeEnum.SAC_OptionConfirmation, $"A1005_{model.ConfirmationNo.Replace("_", "-")}_成交_A").FirstOrDefault(); - oldDateStr = Regex.Match(oldData?.InfoCache ?? "", "(?<=DueDate\":\")[^\"]+(?=\")").Value; - if (DateTime.TryParse(oldDateStr, out var oldDate)) - { - oldDateStr = $",\"OldMaturityDate\":\"{oldDate.ToString("yyyy-MM-dd")}\""; - } - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\"{oldDateStr},\"NewMaturityDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"KingstarView\"}}", - IsValid = true, - }; - } - else - { - note = new SACReportNotes() - { - InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValueDate\":\"{date.ToString("yyyy-MM-dd")}\",\"DurationEventNO\":\"{model.DurationEventNO}\",\"Source\":\"KingstarView\"}}", - IsValid = true, - }; - } - } - else - { - if (note == null) - { - continue; - } - switch (_operationType) - { - case OptFlagsEnum.A: - continue;//新增数据已报送,跳过 - case OptFlagsEnum.U: - note.IsValid = true; - break; - case OptFlagsEnum.D: - note.IsValid = false; - break; - case OptFlagsEnum.NONE: - default: - throw new ServiceException("未知操作类型"); - } - note.InfoCache = Regex.Replace(note.InfoCache, "(?<=NewMaturityDate\":\")[^\"]+ (?= \")", date.ToString("yyyy-MM-dd")); - } - - model.CurrentPositionDetails = GetCurrentPositionDetailsModelFromView(model.ConfirmationNo); - - if (model.OperationType != OptFlagsEnum.A) - { - model.BizID = note.BizId; - } - model.ExceID = base.formatExceID(); - result.Add(model); - ReportStatus.AddCacheInfo(cacheKey, cacheValue); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); note.id = 0; note.ExceId = model.ExceID; note.CreateTime = DateTime.Now; @@ -915,35 +336,36 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service private List GetCurrentPositionDetailsModel(string confirmationNo) { - List result = new List(); + var result = new List(); if (_excelDataSource != null && _excelDataSource.Tables.Contains("合约持仓明细")) { - DataTable dt = _excelDataSource.Tables["合约持仓明细"]; - for (int i = 1; i < dt.Rows.Count; i++) + var dt = _excelDataSource.Tables["合约持仓明细"]; + for (var i = 1; i < dt.Rows.Count; i++) { if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) { //第一列空白说明数据结束了; break; } - if (dt.Rows[i][0]?.ToString() != confirmationNo) + if (dt.Rows[i][0]?.ToString().Trim() != confirmationNo) { continue; } - CurrentPositionDetailModel model = new CurrentPositionDetailModel(); - - model.UndrlygAssetCode = GetDataSetValue(dt, i, 1); - model.UndrlygAssetDtldType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 2)]; - model.UndrlygAssetName = GetDataSetValue(dt, i, 3); - model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 4); - model.UndrlygAssetPrice = GetDataSetValue(dt, i, 5); - model.InvestorPosition = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 6)]; - model.UndrlygAssetAmt = GetDataSetValue(dt, i, 7); - model.ContractMultiplier = GetDataSetValue(dt, i, 8); - model.NotinalPrincipleAmt = GetDataSetValue(dt, i, 9); - model.Blank1 = GetDataSetValue(dt, i, 10); - model.Blank2 = GetDataSetValue(dt, i, 11); + var model = new CurrentPositionDetailModel + { + UndrlygAssetCode = GetDataSetValue(dt, i, 1), + UndrlygAssetDtldType = ConsReport.SwapUndrlygAssetDtldTypeMap[GetDataSetValue(dt, i, 2)], + UndrlygAssetName = GetDataSetValue(dt, i, 3), + UndrlygAssetTradgPlc = GetDataSetValue(dt, i, 4), + UndrlygAssetPrice = GetDataSetValue(dt, i, 5), + InvestorPosition = ConsReport.SwapTypeMap[GetDataSetValue(dt, i, 6)], + UndrlygAssetAmt = GetDataSetValue(dt, i, 7), + ContractMultiplier = GetDataSetValue(dt, i, 8), + NotinalPrincipleAmt = GetDataSetValue(dt, i, 9), + Blank1 = GetDataSetValue(dt, i, 10), + Blank2 = GetDataSetValue(dt, i, 11) + }; result.Add(model); } @@ -951,42 +373,9 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } - private List GetCurrentPositionDetailsModelFromView(string confirmationNo) - { - List result = new List(); - if (_viewDataSource != null && _viewDataSource.Tables.Contains("合约持仓明细")) - { - DataTable dt = _viewDataSource.Tables["合约持仓明细"]; - for (int i = 0; i < dt.Rows.Count; i++) - { - if (GetDataSetValue(dt, i, "CONFIRMATIONNO") != confirmationNo) - { - continue; - } - - CurrentPositionDetailModel model = new CurrentPositionDetailModel(); - model.UndrlygAssetCode = GetDataSetValue(dt, i, "UNDRLYGASSETCODE"); - model.UndrlygAssetDtldType = GetDataSetValue(dt, i, "UNDRLYGASSETDTLDTYPE"); - model.UndrlygAssetName = GetDataSetValue(dt, i, "UNDRLYGASSETNAME"); - model.UndrlygAssetTradgPlc = GetDataSetValue(dt, i, "UNDRLYGASSETTRADEPLACE"); - model.UndrlygAssetPrice = GetDataSetValue(dt, i, "UNDRLYGASSETPRICE"); - model.InvestorPosition = GetDataSetValue(dt, i, "INVESTORPOSITION"); - model.UndrlygAssetAmt = GetDataSetValue(dt, i, "UNDRLYGASSETAMT"); - model.ContractMultiplier = GetDataSetValue(dt, i, "CONTRACTMULTIPLIER"); - model.NotinalPrincipleAmt = GetDataSetValue(dt, i, "NOTINALPRINCIPLEAMT"); - model.Blank1 = GetDataSetValue(dt, i, "BLANK1"); - model.Blank2 = GetDataSetValue(dt, i, "BLANK2"); - - result.Add(model); - } - } - return result; - } - - private string formatInfoTag(SwapDurationManagementModel model, bool suffixType = false, string extensionTimeInfo = "") { - string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : ($"_{extensionTimeInfo}_展期"))}_{model.DurationEventNO}_"; + var result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{(string.IsNullOrWhiteSpace(extensionTimeInfo) ? "了结" : $"_{extensionTimeInfo}_展期")}_{model.DurationEventNO}_"; if (suffixType) { result = $"{result}{_operationType}"; @@ -994,27 +383,43 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service return result; } + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 5 && arr.Length != 6) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) { - List result = new List(); + var result = new List(); if (model?.SwapDurationManagement != null) { - CheckHelper helper = new CheckHelper(); - CheckHelper positionhelper = new CheckHelper(); - for (int i = 0; i < model.SwapDurationManagement.Count; i++) + var helper = new CheckHelper(); + var positionhelper = new CheckHelper(); + for (var i = 0; i < model.SwapDurationManagement.Count; i++) { - List listRoot = new List(); + var listRoot = new List(); var item = model.SwapDurationManagement[i]; - if (item.IgnoreCheck) continue; + if (item.IgnoreCheck) + { + continue; + } + helper.ExecuteCheck(item, (name, value, msg) => { listRoot.Add(new SacInfo(name, value, msg)); }); if (item.CurrentPositionDetails != null) { - for (int j = 0; j < item.CurrentPositionDetails.Count; j++) + for (var j = 0; j < item.CurrentPositionDetails.Count; j++) { - List attList = new List(); + var attList = new List(); var attItem = item.CurrentPositionDetails[j]; positionhelper.ExecuteCheck(attItem, (name, value, msg) => { @@ -1022,8 +427,10 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }); if (attList.Count > 0) { - var temp = new SacInfo("CurrentPositionDetails", j); - temp.SubMaps = new List(attList); + var temp = new SacInfo("CurrentPositionDetails", j) + { + SubMaps = new List(attList) + }; listRoot.Add(temp); } @@ -1031,8 +438,11 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service } if (listRoot.Count > 0) { - var errMsg = new SacInfo("SwapDurationManagement", i); - errMsg.SubMaps = new List(listRoot); + var errMsg = new SacInfo("SwapDurationManagement", i) + { + FieldValue = item.ConfirmationNo, + SubMaps = new List(listRoot) + }; result.Add(errMsg); } } @@ -1056,7 +466,7 @@ namespace YLErp.Modules.SuperviseReportModule.SAC.Service }; } - for (int i = 0; i < noteList.Count; i++) + for (var i = 0; i < noteList.Count; i++) { base.SaveReportNotes(noteList[i]); } diff --git a/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportValuationInformationService.cs b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportValuationInformationService.cs new file mode 100644 index 00000000..298fff9a --- /dev/null +++ b/YLErpDAL/Modules/SuperviseReportModule/SAC/Service/ReportValuationInformationService.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static YLErp.DBModels.Consts.ConsReport; +using YLErp.BLL; +using YLErp.DBModels.Consts; +using YLErp.DBModels.Enums; +using YLErp.DBModels; +using YLErp.Modules.SuperviseReportModule.SAC.Common; +using YLErp.Modules.SuperviseReportModule.SAC.Model; +using System.Data; +using System.IO; +using static iTextSharp.text.pdf.AcroFields; +using YLErp.DBModels.Helpers; +using YLErp.Modules.EodModule; +using System.Collections.ObjectModel; +using YLErp.Helpers; +using YLErp.Modules.PricingModule.Models; +using YLErp.Modules.CalculationModule; +using YLErp.BLL.Calculation; +using YLErp.Enums; +using YLErp.Modules.DataProviderModule; +using YLErp.QdpModule; +using Qdp.Pricing.Base.Utilities; +using YLErp.Enums; +using YLErp.Configuration; +using Qdp.Foundation.Implementations; +using YLErp.Modules.VolatilityModule; +using MoreLinq; + +namespace YLErp.Modules.SuperviseReportModule.SAC.Service +{ + class ReportValuationInformationService : ReportBaseService + { + public ReportValuationInformationService(OptUserInfo optUser) : base(optUser) + { + } + + protected override string _excelDataSourcePath => "交易相关\\"; + + protected override string _excelDataSourceFileName => "import_ValuationInformation_template.xlsx"; + + protected override DataFlagsEnum BusiDataType => DataFlagsEnum.A1018; + + private List _validOperationType = null; + public override List ValidOperationType + { + get + { + if (_validOperationType == null) + { + _validOperationType = new List() { + OptFlagsEnum.A, + OptFlagsEnum.U, + OptFlagsEnum.D, + }; + } + return _validOperationType; + } + } + + protected override SuperviseReportTypeEnum ReportType => SuperviseReportTypeEnum.SAC_ValuationInformation; + List noteList = new List(); + + protected override BodyModel GenerateBody(out bool noData, out List fileList) + { + fileList = new List(); + BodyModel model = new BodyModel(); + List dataList = new List(); + if (_reqInfo.DataSource.HasFlag(SAC_ReportDataSourceEnum.Template)) + { + dataList = GetValuationInformationModelFromExcel(ref fileList); + } + ReadOnlyCollection useDel = null; + if (_operationType == OptFlagsEnum.D && (useDel = ReportStatus.GetCacheInfo($"{DataFlagsEnum.A1018}_D")).Count > 0) + { + dataList.AddRange(GetValuationInformationModelFromCache(useDel)); + } + var subsystemDataList = loadSubsystemDataSource(fileList, AddSubsystemNote); + if (subsystemDataList != null && subsystemDataList.Count > 0) + dataList.AddRange(subsystemDataList); + + noData = dataList.Count == 0; + model.ValuationInformation = dataList; + return model; + } + + private List GetValuationInformationModelFromCache(IEnumerable useDel) + { + List result = new List(); + foreach (var item in useDel) + { + var notes = base.GetReportNotes(formatInfoTag(item)); + foreach (var note in notes) + { + var info = new ValuationInformationModel(); + var reportCacheDic = JsonHelper.ToObject>(note.InfoCache) ?? new Dictionary(); + info.ValuationDate = reportCacheDic.ContainsKey("ValuationDate") ? reportCacheDic["ValuationDate"] : ""; + if (info.ValuationDate.IsNullOrWhiteSpace()) + { + continue; + } + info.ConfirmationNo = item; + var cacheValue = $"{info.ConfirmationNo}_{info.ValuationDate}"; + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) + { + continue; + } + info.BizID = note.BizId; + info.OperationType = OptFlagsEnum.D; + info.Balance = "0.00"; + info.MarginRatio = "0.00"; + info.OptionValuation = "0.00"; + info.Delta = "0.00"; + info.Gamma = "0.00"; + info.Vega = "0.00"; + info.Theta = "0.00"; + info.Rho = "0.00"; + info.RhoQ = "0.00"; + info.DeltaCash = "0.00"; + info.GammaCash = "0.00"; + info.VegaCash = "0.00"; + info.ThetaCash = "0.00"; + info.RhoCash = "0.00"; + info.RhoQCash = "0.00"; + info.Blank1 = "0.00"; + info.Blank2 = "0.00"; + + var exceId_TY = $"{info.ConfirmationNo}_{info.ValuationDate}"; + info.ExceID = base.formatExceID(); + result.Add(info); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); + note.id = 0; + note.InfoCache = $"{{\"Tag\":\"{info.ConfirmationNo}\",\"ValuationDate\":\"{info.ValuationDate}\",\"ExceId_TY\":\"{exceId_TY}\"}}"; + note.ExceId = info.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(info, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.DataId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + return result; + } + + public bool AddSubsystemNote(ValuationInformationModel model, List fileList, string tag) + { + SACReportNotes note = base.GetReportNotes(ReportType, formatInfoTag(model, true)).FirstOrDefault();//参数true要加,要不A和D会查到同一条记录,在D时候,就会和A相同的数据 + if (note == null) + { + note = new SACReportNotes() + { + InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}", + IsValid = true, + }; + } + else + { + switch (model.OperationType) + { + case OptFlagsEnum.A: + return false;//新增数据已报送,跳过 + case OptFlagsEnum.U: + //多次U的时候,每次用最新的tag来赋值SubFileTag + note.InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"Source\":\"Subsystem\",\"SubFileTag\":\"{tag}\",\"ExceID\":\"{model.ExceID}\"}}"; + note.IsValid = true; + break; + case OptFlagsEnum.D: + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + model.ExceID = base.formatExceID(); + note.id = 0; + note.ExceId = model.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(model, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.changeStatus = false; + noteList.Add(note); + return true; + } + + private List GetValuationInformationModelFromExcel(ref List fileList) + { + List result = new List(); + if (_excelDataSource != null && _excelDataSource.Tables.Contains("每日估值信息")) + { + DataTable dt = _excelDataSource.Tables["每日估值信息"]; + for (int i = 1; i < dt.Rows.Count; i++) + { + if (string.IsNullOrWhiteSpace(dt.Rows[i][0]?.ToString())) + { + //第一列空白说明数据结束了; + break; + } + var optType = OptFlagsEnum.NONE; + switch (dt.Rows[i][1]?.ToString()) + { + case "0": + case "A": + case "首次": + optType = OptFlagsEnum.A; + break; + case "1": + case "U": + case "变更": + optType = OptFlagsEnum.U; + break; + case "2": + case "D": + case "废止": + optType = OptFlagsEnum.D; + break; + } + if (optType != _operationType) + { + continue; + } + + ValuationInformationModel model = new ValuationInformationModel(); + + model.ConfirmationNo = GetDataSetValue(dt, i, 0); + model.OperationType = _operationType; + DateTime.TryParse(GetDataSetValue(dt, i, 2), out DateTime date); + model.ValuationDate = date == DateTime.MinValue ? null : date.ToString("yyyy-MM-dd"); + var cacheValue = $"{model.ConfirmationNo}_{model.ValuationDate}"; + if (ReportStatus.CheckCacheInfo(CacheKey, cacheValue)) + { + continue; + } + + List notes = base.GetReportNotes(ReportType, formatInfoTag(model)); + var note = notes.LastOrDefault(O => O.InfoCache.Contains(model.ConfirmationNo)); + if (note == null && _operationType == OptFlagsEnum.A) + { + note = new SACReportNotes() + { + InfoCache = $"{{\"Tag\":\"{model.ConfirmationNo}\",\"ValuationDate\":\"{model.ValuationDate}\",\"Source\":\"Template\"}}", + IsValid = true, + }; + } + else + { + if (note == null) + { + continue; + } + switch (_operationType) + { + case OptFlagsEnum.A: + continue;//新增数据已报送,跳过 + case OptFlagsEnum.U: + note.IsValid = true; + break; + case OptFlagsEnum.D: + note.IsValid = false; + break; + case OptFlagsEnum.NONE: + default: + throw new ServiceException("未知操作类型"); + } + } + + if (_operationType != OptFlagsEnum.A) + { + model.BizID = note.BizId; + } + model.Balance = GetDataSetValueToDoubleOrNull(dt, i, 3)?.ToString("0.00"); + model.MarginRatio = GetDataSetValue(dt, i, 4); + model.OptionValuation = GetDataSetValueToDoubleOrNull(dt, i, 5)?.ToString("0.00"); + model.Delta = GetDataSetValue(dt, i, 6); + model.Gamma = GetDataSetValue(dt, i, 7); + model.Vega = GetDataSetValue(dt, i, 8); + model.Theta = GetDataSetValue(dt, i, 9); + model.Rho = GetDataSetValue(dt, i, 10); + model.RhoQ = GetDataSetValue(dt, i, 11); + model.DeltaCash = GetDataSetValue(dt, i, 12); + model.GammaCash = GetDataSetValue(dt, i, 13); + model.VegaCash = GetDataSetValue(dt, i, 14); + model.ThetaCash = GetDataSetValue(dt, i, 15); + model.RhoCash = GetDataSetValue(dt, i, 16); + model.RhoQCash = GetDataSetValue(dt, i, 17); + model.Blank1 = GetDataSetValue(dt, i, 18); ; + model.Blank2 = GetDataSetValue(dt, i, 19); + + model.ExceID = base.formatExceID(); + result.Add(model); + ReportStatus.AddCacheInfo(CacheKey, cacheValue); + note.id = 0; + note.ExceId = model.ExceID; + note.CreateTime = DateTime.Now; + note.FileTag = FileTag; + note.ReportType = ReportType; + note.ReportDate = _reqInfo.ReportDate; + note.InfoTag = formatInfoTag(model, true); + note.OptTime = note.CreateTime; + note.RetCode = ""; + note.RetMsg = ""; + note.ReportResponse = false; + note.BizId = ""; + note.DataId = ""; + note.changeStatus = false; + noteList.Add(note); + } + } + return result; + } + + private string formatInfoTag(ValuationInformationModel model, bool suffixType = false) + { + string result = $"{BusiDataType}_{model.ConfirmationNo.Replace("_", "-")}_{model.ValuationDate}_"; + if (suffixType) + { + result = $"{result}{_operationType}"; + } + return result; + } + + private string formatInfoTag(string confirmationNo) + { + string result = $"{BusiDataType}_{confirmationNo.Replace("_", "-")}_"; + return result; + } + + protected override string _changeCodeOfInfoTag(string infoTag, string newCode, out string originalCode) + { + var arr = infoTag.Split('_'); + if (arr.Length != 4) + { + throw new ServiceException($"InfoTag信息不匹配:{infoTag}"); + } + originalCode = arr[1]; + arr[1] = newCode.Replace("_", "-"); + return string.Join("_", arr); + } + + protected override List CheckBodyValue(BodyModel model, out bool checkStatus) + { + List result = new List(); + if (model?.ValuationInformation != null) + { + CheckHelper helper = new CheckHelper(); + for (int i = 0; i < model.ValuationInformation.Count; i++) + { + List listRoot = new List(); + var item = model.ValuationInformation[i]; + helper.ExecuteCheck(item, (name, value, msg) => + { + listRoot.Add(new SacInfo(name, value, msg)); + }); + if (listRoot.Count > 0) + { + var errMsg = new SacInfo("ValuationInformation", i); + errMsg.FieldValue = item.ConfirmationNo; + errMsg.SubMaps = new List(listRoot); + result.Add(errMsg); + } + } + } + checkStatus = result.Count > 0; + return result; + } + + public override bool BeforeOfGenerated(out string errMsg) + { + errMsg = ""; + for (int i = 0; i < noteList.Count; i++) + { + base.SaveReportNotes(noteList[i]); + } + return true; + } + + private enum clacTargetEnum + { + /// + /// 波动率变动 + /// + vol, + /// + /// 无风险利率变动 + /// + r, + /// + /// 分红率变动 + /// + q + } + + /// + /// 计算参数 + /// + private class calcParam + { + /// + /// 计算指标 + /// + public clacTargetEnum Target { get; set; } + /// + /// 交易列表 + /// + public IEnumerable TradeList { get; set; } + /// + /// 估值日期 + /// + public DateTime Date { get; set; } + /// + /// 偏移值 + /// 每次只变动一个参数,所以只需要一个 + /// + public double Offset { get; set; } + /// + /// 波动率变动 + /// + public Dictionary UpVolForTrade { get; set; } + /// + /// 无风险利率或分红率变动 + /// + public Action UpParamOverride { get; set; } + /// + /// 波动率变动 + /// + public Dictionary DownVolForTrade { get; set; } + /// + /// 无风险利率或分红率变动 + /// + public Action DownParamOverride { get; set; } + /// + /// PV差 + /// + public Dictionary PvDiff { get; set; } + + /// + /// + /// + /// + /// + /// + /// + public calcParam( + clacTargetEnum target, + IEnumerable tradeList, + DateTime date, + double offset, + Dictionary upVolForTrade, + Dictionary downVolForTrade, + Action upParamOverride, + Action downParamOverride) + { + this.Target = target; + this.TradeList = tradeList; + this.Date = date; + this.Offset = offset; + this.UpVolForTrade = upVolForTrade; + this.DownVolForTrade = downVolForTrade; + this.UpParamOverride = upParamOverride; + this.DownParamOverride = downParamOverride; + } + } + } +} + diff --git a/YLErpWeb/App_Data/FunctionRight.xml b/YLErpWeb/App_Data/FunctionRight.xml index d73456b4..61c05dfc 100644 --- a/YLErpWeb/App_Data/FunctionRight.xml +++ b/YLErpWeb/App_Data/FunctionRight.xml @@ -73,6 +73,9 @@ + + + diff --git a/YLErpWeb/App_Data/Menus.txt b/YLErpWeb/App_Data/Menus.txt index 20ed8103..8dec75aa 100644 --- a/YLErpWeb/App_Data/Menus.txt +++ b/YLErpWeb/App_Data/Menus.txt @@ -27,6 +27,11 @@ {Name:"每日估值报告",Rights:["结算管理-每日估值报告"],Url:"clientbalance/TradeMarketReport"}, ] }, +{Name:"监管报告",Rights:["监管报告"],Icon:"menu-icon iconteleven" +,SubItems:[ + {Name:"证券业报送",Rights:["监管报告-证券业报送"],Url:"supervise_report/supervise_sac_report"} + ] +}, {Name:"客户管理",Rights:["客户管理"],Icon:"menu-icon iconeight" ,SubItems:[ {Name:"开户管理",Rights:["客户管理-开户管理"],Url:"AccountOpeningProcess/clientList"}, diff --git a/YLErpWeb/App_Docs/导入模板/Report.zip b/YLErpWeb/App_Docs/导入模板/Report.zip index d18bedbe14d55047385d174ed01375f4d46e2ec3..e65164eb0fd74c0a45f24a9f510126ad2adaed1e 100644 GIT binary patch delta 230774 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

D3I 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 JzvdFa{{w1+F}?r* delta 190527 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

+ /// 是否上传过模板 + /// + /// + public JsonResult IsUploadFile(DateTime ReportDate) + { + var tempFilesService = new TempFilesService(CurUser); + + var path = tempFilesService.QueryTempFile(ReportDate, "报送模板").Select(O => O.filePath).FirstOrDefault(); + + return Json(!string.IsNullOrWhiteSpace(path)); + } + + public ActionResult DownloadReportFile(string path) + { + var result = OtcAppContext.MapPath(path); + var bytes = System.IO.File.ReadAllBytes(result); + return File(bytes, "application/zip", $"报送文件{DateTime.Now:yyyyMMddHHmmss}.zip"); + } } } \ No newline at end of file diff --git a/YLErpWeb/Views/supervise_report/supervise_SAC_Report.cshtml b/YLErpWeb/Views/supervise_report/supervise_SAC_Report.cshtml index b056f120..01e9d0e7 100644 --- a/YLErpWeb/Views/supervise_report/supervise_SAC_Report.cshtml +++ b/YLErpWeb/Views/supervise_report/supervise_SAC_Report.cshtml @@ -1,7 +1,6 @@ - -@{ +@{ ViewBag.Title = "证券业监管报告"; - ViewBag.Menu = "监管报告-证券业报告"; + ViewBag.Menu = "监管报告-证券业报送"; Layout = "~/Views/Shared/_MainLayout.cshtml"; var valueDate = ViewBag.valueDate; var dataSourceMode = PS.Config.ErpElement.SAC_ReportDataSource; @@ -23,8 +22,9 @@ const page = { sysdate: '@valueDate', maxRequestLength: @maxRequestLength, + dataSourceMode: @((int)PS.Config.ErpElement.SAC_ReportDataSource), g_grid: {}, - uploadColumns :[ + uploadColumns: [ { name: 'id', label: 'id', index: 'id', align: 'center', hidden: true }, { @@ -56,7 +56,7 @@ return html; } }], - reportList :[ + reportList: [ { name: 'id', label: 'id', index: 'id', align: 'center', hidden: true }, { @@ -86,9 +86,9 @@ var html = ""; switch (cellValue) { case 0: - html = "" + html = "" .template(cellValue, "确认发送"); - html += "" + html += "" .template(cellValue, "删除"); break; case 1: @@ -121,10 +121,11 @@ ReportDescOption: [], ReportDescSwap: [] }, - isZhongjin : '@(PS.Config.Company == CompanyEnum.中金 )' == 'True' + isZhongjin : false } $(function () { + $("#editCode").hide(); initPage(); }); @@ -182,6 +183,13 @@ a[readonly] i { color: darkgrey; } + + .my-skin .layui-layer-btn a { + background-color: red; + border: 1px solid red; + color: #fff; + } + @@ -193,14 +201,11 @@ 报送说明
+ @MyControls.Btn("修改编号", "Upload('修改编号','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','/App_Docs/导入模板/修改约定编号导入模板.xlsx')", id: "editCode") @MyControls.Btn("手工上传", "Upload('报送模板','application/zip','/App_Docs/导入模板/Report.zip')") @MyControls.Btn("附加信息", "showWindow($('#extendInfo'),'收益计算说明',saveReportDesc)") @MyControls.Btn("查看附件", "jqGridInit('查看附件')") @MyControls.Btn("生成报告", "generateReportFile()") - @if (PS.Config.Company == CompanyEnum.中金) - { - @MyControls.Btn("批量导出", "showModal()") - } @MyControls.Btn("查看/发送", "jqGridInit('查看/发送报告')")
@@ -218,21 +223,6 @@ 接收方代码 - @if ((dataSourceMode & ConsReport.SAC_ReportDataSourceEnum.System) == ConsReport.SAC_ReportDataSourceEnum.System) - { - - - - } @Html.MyAceDropdownInput2("sacReport", "SAC报告月份", monthList, false) @Html.MyAceDropdownInput2("nafmiiReport", "NAFMII报告月份", monthList, false) @Html.MyAceDropdownInput2("isdaReport", "ISDA报告月份", monthList, false) @@ -241,9 +231,9 @@ @*
- 撤销重大事项报告报送日 - -
*@ + 撤销重大事项报告报送日 + + *@
重大事项说明 @@ -253,9 +243,9 @@
@*
- 撤销其他事项报送日 - -
*@ + 撤销其他事项报送日 + + *@
其他事项说明 @@ -269,14 +259,14 @@
@await Html.PartialAsync("/Views/Common/_importFiles.cshtml", new ImportFileModel() +{ + Accept = "application/pdf", + Buttons = new Dictionary() { - Accept = "application/pdf", - Buttons = new Dictionary() - { - ["上传"] = new BtnReq() { OnClick = "uploadOuterData()" }, - }, - NotesHtml = "" - }) + ["上传"] = new BtnReq() { OnClick = "uploadOuterData()" }, + }, + NotesHtml = "" +}) + diff --git a/YLErpWeb/wwwroot/Scripts/app/superviseReport/sacReport.js b/YLErpWeb/wwwroot/Scripts/app/superviseReport/sacReport.js index 850753c0..90c5079d 100644 --- a/YLErpWeb/wwwroot/Scripts/app/superviseReport/sacReport.js +++ b/YLErpWeb/wwwroot/Scripts/app/superviseReport/sacReport.js @@ -1,7 +1,7 @@ function initPage() { initTree(); $("#notes").append('
' + $("#periodicReportQuarter").parent().html().replace(/periodicReportQuarter/g, 'fileDate') + '
'); - $("#notes").append('
注意:重大事项,其他事项和季度报告的相关文件不包含在模板文件中,请到相应功能点上传.
单个文件不应超过30MB,周期内有效文件总大小,不应超过200MB,若超过限制,请考虑分批报送或精简文件
'); + $("#notes").append('
注意:
'); $("#buttons").prepend('下载模板') //$("#LastMonthCash,#LatestMonthCash,#LatestNetAssets").parent().hide(); //$("#sacReport").parent().hide(); @@ -75,7 +75,7 @@ function exportDetails(id, fileTag) { window.open("/supervise_report/exportDetailsForZhongJin?encryptId=" + id + "&fileTag=" + fileTag); } else { - window.open("/supervise_report/exportDetails?encryptId=" + id + "&fileTag=" + fileTag); + window.open("/supervise_report/ExportDetailsV2?encryptId=" + id + "&fileTag=" + fileTag); } } @@ -83,14 +83,17 @@ function exportDetails(id, fileTag) { function showDetails(id) { var width = "1260px"; var url = "/supervise_report/QueryDetails?encryptId=" + id; + var itemIndex = 0; var colModel = [ { name: 'FileTag', label: '报告标识', index: 'FileTag', width: 340, align: 'left', sortable: false, formatter: (cellValue, options, rowObject) => { var html = ""; if (cellValue.startsWith("{")) { + cellValue = cellValue.replace(/\s/g, ""); var obj = JSON.parse(cellValue); - html = "" + obj.Tag; + html = "【{0}】{1}".template((++itemIndex), obj.Tag); } else { + itemIndex = 0; html = cellValue; } return html; @@ -208,8 +211,6 @@ function DownLoadDoc(res) { window.open(res); } - - function SendReportFile(res) { var opt = { url: "/supervise_report/SendReport", @@ -236,7 +237,7 @@ function testSql() { data: { sqlStr: $("#testsql").val() }, success: function (res) { if (res.Success) { - + main.message(res.Msg); } else { @@ -471,6 +472,7 @@ function initTree() { { id: "confirmation", ckId: "input_confirmation", name: "交易确认书", open: true, children: [ { id: "optionConfirmation", ckId: "input_optionConfirmation", tag: 5, pId: "confirmation", name: "期权交易确认书" }, + { id: "optionConfirmationAtt", ckId: "input_optionConfirmationAtt", tag: 19, pId: "confirmation", name: "场外期权交易确认书附件" }, { id: "swapConfirmation", ckId: "input_swapConfirmation", tag: 6, pId: "confirmation", name: "互换交易确认书" }, { id: "confirmationAtt", ckId: "input_confirmationAtt", tag: 17, pId: "confirmation", name: "互换交易确认书附件" }, ] @@ -482,6 +484,7 @@ function initTree() { { id: "swapTermination", ckId: "input_swapTermination", tag: 8, pId: "termination", name: "互换交易存续期管理" }, ] }, + { id: "valuationInformation", ckId: "input_valuationInformation", tag: 18, name: "场外期权合约估值信息" }, { id: "periodicReport", ckId: "input_periodicReport", name: "定期报告", open: true, children: [ { @@ -538,7 +541,7 @@ function initTree() { $(".bottom_open").addClass("bottom_docu").removeClass("bottom_open"); $(".root_open").addClass("root_docu").removeClass("root_open"); var notes = zTree.getNodes()[0].children - var selectNotes = ["主协议", "主协议关联产品列表", "补充协议", "履约保证书", "交易确认书", "交易存续期管理", "权益端支付"]; + var selectNotes = ["主协议", "主协议关联产品列表", "补充协议", "履约保证书", "交易确认书", "交易存续期管理", "权益端支付", "场外期权合约估值信息"]; _.forEach(notes, (v) => { if ($.inArray(v.name, selectNotes) >= 0) { onClick(null, v, null); @@ -562,7 +565,29 @@ function queryReportInfo() { }); } +//生成报告 function generateReportFile() { + //历史正常逻辑 + if (isExist(getReportType()) && page.dataSourceMode != 2) { + //判断是否手工上传过文件 + $.get("/supervise_report/IsUploadFile?ReportDate=" + $("#DateValueDate").val()).done(function (res) { + if (res && typeof (res) === 'boolean') { + layer.open({ + type: 1, + title: '生成报告', + content: $('#reportTpl').html(), + area: ["350px", "350px"] + }); + } else { + GenerateReport(false); + } + }); + } else { + GenerateReport(false); + } +} + +function GenerateReport(isUploaded) { var postData = { ReportDate: $("#DateValueDate").val(), DataDate: $("#DateDataDate").val(), @@ -572,6 +597,7 @@ function generateReportFile() { LatestMonthCash: $("#LatestMonthCash").val(), LatestNetAssets: $("#LatestNetAssets").val(), ReportTypes: getReportType(), + DataSource: isUploaded ? 2 : page.dataSourceMode }; postData.SACReportDate = $("#sacReport").val(); switch ($("input[name='input_periodicReportSAC']:checked").attr('id')) { @@ -666,7 +692,7 @@ function generateReportFile() { title: "请选择报送方式", shadeClose: false, shade: 0.4, - area: ['300px'], + area: ['366px'], content: html, }); } @@ -691,14 +717,21 @@ function Upload(fileType, accept, templateFile) { $("#modalFileUpload #uploadType").text(fileType) $("#fileDate").val($("#DateValueDate").val()) $("#fileDate").parent().hide(); - $("#tip").hide(); - if (fileType == "季度报告") { - $("#fileDate option:eq(1)").prop('selected', 'selected'); - $("#fileDate").parent().show(); - } else if (fileType == "报送模板") { - $("#tip").show(); + var tip = "单个文件不应超过30MB,周期内有效文件总大小,不应超过200MB,若超过限制,请考虑分批报送或精简文件"; + switch (fileType) { + case "报送模板": + tip = "重大事项,其他事项和季度报告的相关文件不包含在模板文件中,请到相应功能点上传.
" + tip; + break; + case "修改编号": + tip = "修改编号功能仅适用于双方约定编号或产品名的修改,该功能仅修改镒链系统内数据,修改后须另外以补正的方式将修改后的数据报送给协会;
修改数据可能需要废止相关报告,请遵循协会要求,废止成功后再操作."; + break; + case "季度报告": + $("#fileDate option:eq(1)").prop('selected', 'selected'); + $("#fileDate").parent().show(); + break; } + $("#tip").html(tip); if (accept) { $("#uploadfile").prop("accept", accept); } @@ -720,11 +753,17 @@ function uploadOuterData() { main.alert("请选择要上传的文件!"); return; } - var date = '0001-01-01'; - if ($("#fileDate").val()) { - date = $("#fileDate").val(); - } + var url = ""; var fileType = $("#modalFileUpload #uploadType").text(); + if (fileType == "修改编号") { + url = "/supervise_report/UploadFile?fileType=" + fileType; + } else { + var date = '0001-01-01'; + if ($("#fileDate").val()) { + date = $("#fileDate").val(); + } + url = "/supervise_report/UploadSACReportFile?fileType=" + fileType + "&date=" + date; + } var fd = new FormData(); var useSend = true; _.forEach($("#uploadfile")[0].files, (f, i) => { @@ -740,7 +779,7 @@ function uploadOuterData() { return; } main.ajax({ - url: "/supervise_report/UploadSACReportFile?fileType=" + fileType + "&date=" + date, + url: url, type: "POST", processData: false, contentType: false, @@ -799,4 +838,29 @@ function showHtml(title, url, width) { width = '1250px'; } main.open(title, url, { area: [width, '800px'] }); +} + +function generateReportFromFile() { + var val = $('#generateReport option:selected').val(); + if (val == "0") { + GenerateReport(false); + } else { + GenerateReport(true); + } +} +//用jquery写一个方法,判断传入的数组中是否存在0~8和16~19范围的数字 +function isExist(arr) { + var arr = arr; + var arr2 = []; + for (var i = 0; i < arr.length; i++) { + //只有日报和SAC月报才需要展示数据源选项 + if (arr[i] >= 0 && arr[i] <= 9 || arr[i] >= 16 && arr[i] <= 19) { + arr2.push(arr[i]); + } + } + if (arr2.length > 0) { + return true; + } else { + return false; + } } \ No newline at end of file diff --git a/YLerpbase.sln b/YLerpbase.sln index a9b1bc83..5962b956 100644 --- a/YLerpbase.sln +++ b/YLerpbase.sln @@ -92,6 +92,7 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {B454A6FB-CF27-4B00-AEDC-BA1F0ED2F6D1} = {15F732CE-6C51-48F0-BC50-3BEC018460E5} + {5981434D-792E-4528-AFC8-7EB8AFD9F80C} = {15F732CE-6C51-48F0-BC50-3BEC018460E5} {C7E0F300-16D5-438B-97A2-79DC2311D1D5} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE} {FEDA115A-88ED-42FE-A5FF-0AAE229DC4CF} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE} {206EBAE4-AB3E-4F09-9428-DDC3E64CFC42} = {F315B5D3-F4FE-43E5-AF22-AF92978A71BE}

u0b>K1U*JLJmx=J*0^I2C-D3Ie)PHO~YlyTKe*85HPfT93!D2uN)&)HW z20?q^Bjlqzb5H)t4U|`MEG#fETkrikIXKDqF(j}sh!_qga;CMyzW(q&pSI_i^b~)1k8+_eb_D)%%r+Y$wz6sYl4}*rV@E zDR0&$NA9^1>u6ifpvtV4<3v{QlhQklFKfwo zDYs`dG5{P)Nie{}Ej8=}d+QdaBPWmqhcaAK>n-Qr5=}1ctxjlz3mv`;;GXBy8OKXB zN_srlBQl7#Ac+1L{QmgDu>`}2C=e1L-)R?csn(zsc5}e^saV(T4TRd<$bVORSo4(q zM9U!}(D)3#4+{ZYT_q<|`+>5ZAIuJ=B#Ms{RaNC?YY00tlu*4*$0tA-Q7(^?Lt# z_7eW-a9Gz2jG0-@cfR`n)PMB(w9_@*S>2olPmmK@8T6P8uP;n&*5IpbhQ(I9=CLNf zi@%V6zdx~mfxnUeo=8E7e}IfyyvF*`%FA19JMNJQ+>dwYn!6E*Ysaz1U2 z>#7D0U7(ICSCeA|NEoO%h&YWU==7yAnkl5WhD|!S1ubsgDr*4O)bt*^TMNe^$|vA|`)7ZWrtG@NA0lJFSmXvI z=2E9dtkYTmDMxy~Q-v0zy0)T8$JR_i8A_r#L=u}1!Ny;J!UCd1Lcfk+XUwg=P4*e; zYnvsjPTE5ueETwwsej32#um=&(-z0hlVJ2uqdL&CEvf^5=BVQzlS#=pnLW&vBc)YF zt@-73yK{FxCf}-)9f6uYC9|>a9QYsk($LH(-7;KfohF&u*NKMcnst73+I7R7*`8HE zyI$2lDCku^4J5viHG@t%_9 z%xoo+R*jkJjhGm{!BW?S=N*qr2r_#H+40)iZXGK0AWnPfkww)W{tz7(&nu*)t}TcR z2N7h7jfO=u=UkK)PE=B%_w`Q%|LR+i(qON;^-gzTZ=UpR?7g$fQ@R@C=U~)i^kU>> zv`eS&&xzKcZGYeCLGC8I6P5Uo1mn#;Ml1ztG&kl<;qVF#u{~z#{xrf;Qk&h}kx9In zai4nm=*BE2eRnzyZ}I3Y;kmk*QLdNPYMb5pbK<06)M0IAL|bu2Bq!DYl<{!#e1kb8 zqltOuMqDZl&dQ3ZzX$p?0>6%q1!pTHr8I7j1w6oiFSPK zJR5v|G!SC3T7MK}Rm34G2N5HdnfL~mUQ$hCLsrgrTqsp=(0q>ve*(pj@6RLE%!-_tLynjPrN;NMJ+e}1zX4g!L7G0A|i*Qu7E|d|-$q`9py|d-3V{<2y&|qockwZi^ zGf*fxXF_x3*LwHow5cm$QKLN=sT($=57%DdiOIc>ulmQK6~1Pi`rwRB2w7c(o(VIP zN@|n|BVjRzb1;~^uv=9Cvd)&YA21^qOpFXVYk%t!9t0L@9vYb*(vuI6MqWH%1lWLj z51YKee&t^Q6m^|Po{#O~$u!?j-PL$P;fsYcGiJtF?dv7czvq8HI_CHCiiHFTi!w1^ z^=E~0v%dVPoza@^1&=zySY2i*HY)|U%4Z%&5sCjFQKdc)ns_bc1dJ9 zLVvMC97v@WrEiwKKoaZ@_9#RQk&&=Byw?O}Y_BG_9@*%Y$7j4-*-Gnr*H*i0x*l70 z0!kNK4^QTv1dv9#fm)CuE_X>Y$Vk9&yyS{Zj#xXk+63zDJ5n5*=J#X4r|)scys4va zkX}O4yIrY2-Ws9tUHNS9mOo;lZ%9sI{C^b;Y)6^*+XVZPr@kfIx(TPfOhWT@YiaaF zf8F-O(YL)}4ke*$X6D0M*yXYFH^>@Yb06~E<^fdCpG`b$lc6;`DrC-leCuw~o`&e# z_62enn@n?OlfI>vRK&063nBUHQ$}m{b^*99r`!4Uh%u7d`#~To1{eWJva(p{IoI8U1 z7eVxLTfFeU1Q7yO`tE28D^dTA1b?{+@A#rJ1pVoiw4eo9{pYG280NEQz1gWLnjjZaj&8yJ+hVUj&#;B!42ELfdUn zi#G;wr$xgkI=uvV{|Qg}E^X4aF~T9=*$a$sg&#@L3MoO`0}Wkn9hAgQ|Byg$e08?2 zDHW>vK0cE6)wW)HL-zUilXTp`(kFr=%4dogLziHvc}B0R-ZS?R)LP$nNun=(j`~yy zn!X2I>c@}swO)FwWPAzQr+;?>$eK{oDT4q=lgtyojnSwvxnTo5% zBS5l37wYfpF&e&lBUfXJ%VtPff-=ZeRu{R>$IA!^N?o-$&%G;pDalpA2i4)ZEvu4co)B_w&Px_dU=}n-3q)%!T4&{0A4h#{~4^SNdz0 z-I(W(hsvx@pBcHZE`R?gRvzzo~5Kv2Pkded0MP<{9_}?;!0e`*wLLTn(ogv0PDOVa;<` zWSp@+@!%I)xQ7K=$67RG>&Ljh!XSlU$#si23lKDp1%yV9cYmMiGY=yX+@D)|7zkg` z92kgo_@Z<8HqVtht})ZnN79&IWn^%)O;& zI^;a$a(^_Du@GpI^w4303BhV8D@rfo;7mBNr_jWcom0;W4~j`2coj`Fcr63%pq^Y ztK|H_!mpU7ucpW$$b={IO}y>Jhgw!TGNGBF$Tk&ll$!`(;EDg zZup?+(L4;N^66A``|uF%2O2*4)q);R^2Ce)eps1qOELQHMzW>W0G>O z`Qz@=(e(=GqV{TP-Kg*i=nOi@?0^vK1pxZd-qURm<$6*T{ZMqg$Jb?t8(5na3SA z6qmZgaW{4Ly>_RD*}9A?zE6R`n%jHau+cj#W|`HvmCi9e%z zx=&lOiVJ$aof8fo$Mqz`_9I(YziHC=n4}hbFd2T+^7JguhSupgNT_}Y_VNkXI9eFXE=7j zw+g1mn%3QOo1`X>(hd~Po-!nE7~QBq%s+n|$z2(h_={;B#|M)CIp!0UzbhHcifwF@ zub^_Q>73N75n36I8jt@F3i8IOq1d@|b^A2KQR2y`Vb`5K=d|7SP*?s+Arv!$AYO>h zz@`{^c(+7HE&y?x0;R9yfkr|cYLeLr*;o*oBmZ}2YpIano=pTZGt(qbexZr6#Ug)7 zld#$Z`Q+*dL#<+T8TALj;)+w71E#+X`~@-bR(@ar06(z**fjlT;CC`Jwl@C9^Pd|I z&eUaXkwsCuR8L$n&T*~CTtbO(P`Fsl2@ptv!*|`jZsKyc)umyQJq2%vDwR@JHY=5R z9Oqg@fGALX_el*_kf*#xeK9eyzU+TDj87DM7eyg?IJ4dSd_3q_iAcU6hB-$jppeDp z-}mC+BZhU)E|Mo|o;lCZgpE~VKQ|myoP`(^0!v=p^1UR~QDhK@@P9AW>Wjixq12@M zZUix=mUW0J{&U4I0)*;`GEYHw8#pJudRC#OT|t6g8aQzWWLO6e#!PJb7SDgz<9Q)p z_kzc7OV7JEf5K0`tUw1Mb$Jdav~EW4wJ%&`xWD1<(Ro&XU! zR$hMdcLT_({qz)#>Za-{L!TS(=im>!kt-B=+tK>j(nUHenPY4K#oK0=whar_qB|IX z5CSs`V~W`d7Zs`r$O)ifpNxOv4a%iaWpv$~E^ac%juorLlNRcv62O(11&%ih_rlhi zy=~ax9ZSb23&;Eg4f`uFqiZV1r^%ofiG=}dxp6bj3_;5f7fz0Q3Zw3oB=k|A`TqM1T<7`HOC0S$j!#~DCBFvbeA@OgG3U>pJZCc9Z=6iYC-sO^7V*JgjB7@S?UG0Z&0nv~A~s-hTff2Q@bY)S(T^ntf?x1JBTqDRE# zeVJ6<=?AoNoJ`YlgS8XBrBrL?k|5%BWT4z}Vc2}Uw)r`4Z|#}LzmNe^X!xokg~Q;A zA%hw%CV?_L^%RQ`dRBEm{^qmimK!{=W=P3Br zflctyYTo-TyV^f0118ve_On46b-svR5NkdiKGi`?i7V=hb`adhEvkn+ZML^|)^~%F z**cvyr_GVxK~Fx+HAO>_9};t(lI(sjxN6LT-%??U1Jr-e`i9ykTOt+h*A@xiAS3Q-DjxNTas{ctwofeD%(<7Ej{3Bz6%;OOuV|dx3JsFjHDbh zF*2P8&eW3HDVU6*Z$_&RNHk1a{jfkKN}~vmwov@u6LMSDvooJIy@G!f(mhH=|8BXW zzu6Oc*RX$aPR(N5iuynLt{@2uTzZb9d$z83VO`l6IzP#}$?k zepUv(EZzRds*?sY&O~?I{xv?Dnue52a)zI%WGTr45XycL0*s!rZ-^MUN^(QW0IjD% zu_O@o)i7Zt@N_)g*;h?v`=M{uTSmVa&Pbq4n%aL58|y&+3lKF+Ku4T!DVWJuDp0F} zPf&^^RRW9;R*LTEAC@C}d;-c&F8TxOo)~;O63=3YHRzA7q9FlL=z8J@N*a8Nn_Lp<4hrW`%B3#S7wsNMEyYEku^WJnAt>1{ zTYW<}(*11WFf~u94;EKApM`*gI*bbkCE$`vlDfkctccInP9h$IObw+BrDCFTi8(`F zTwt*i&OQeWCzzLJ85#5I!Hwd5^vvS#5MzJi_?({{BE22g*5ceae1blR{^=Cv+@kW zFPmB!1U?2bA2WooX3T6Ztz+J{zuQRUoF#PVFtXgSN!@^XKC zbmufYM02syK6Cn76kPB%EwA-!8Vutg!$FYxwK3Y|2AHUAuVnzD;%p~vGw@O{z40BZAT?I_g{PHHx!7 z=(hrvB1I=gG$AzOBpRL=Eiy=(gG7HHbNr2?!NCg!;D=A2>9FP`X#?Qc^Di+f>+|*zuYIAPkbph$NUgliay>II=?mEIL2N(9YYcNO_Ze+JUqgHD zeM7#IqR+6~vLg7E{>y=YPTxGB;5mM)Kt4*c@hiSfmYnJA^rCEhi=B6{Ue2;JNwNw0 zi#9|t3ZgFnnS_&9U5bBy#|y%9(89HgrbbLy1AUpvHJtvoLCEvOlfS39f%5ndj8uIm z;8(abqEL3&3rr6%dbd))2GI2zwK!1+XFT7O#UJZ-MSO;Re(dz3L;B5-vq;G=+UQZ_ z!=c;Pf$zmViQ?2bCNXF`q+U z78`MZL#i7nx+CRntf^8cKR?9Cl)%NA?$cNk^2X;1I8UXm+iZpxYD4uur7Vp?Od=-F`qr%k zeKg?b#cZI2|Mf6okTX&kLzkdw{Hc*Yl2rCC2;Xm2!;q34YU~Fl(U@WQZE}r%*c(?v zojBi>=g}y2l(dn>;Ef)b!go&tY1`?HITJwJ?@ zM)NiMas;~r1&pwQK&f;m0@*&qkCoC3M@T{Uh%bL?{E5~xL^P{@RSLVNvYmyQgYh(+ zl4iWKc`bntL_g_r-xIy(gnQx13a_@_Ld1s#yB=+Jd0s)`zkGF^zP$1?9Q(3__*nSp z4R!lDyZ5c}MKY5+$*u15c14W*4#ewlqC?boFMb6iuJ@&dU4S3UP>p=lj0b>&-dFVsX^up{bU1P3JUcte(^@wl){8b7(wxg zstTDTZ{{ba6?9%CT^7Oh*KR5@Cl|Jl*7$C z3}wyjR<(FMZ>_TunK9|O+)P&&_(^3Fpw52}usDh;JyQ|ikv9A=aG7gOXgkDh9_H_! zU>&Z;flEazI|p0=_lZ3$Jg7BlMjxC)#b#{Lmb#jg4Iq?LYcJX%!rAsjHCyHp_pe zL3b3N=SGqcb^4%>YU+f@^+A4q$L!GyQazk_*k8ygYoI)&sniiHT4bG~W2y78_i^Vi zQ!V=*0iWth0_Uda-?a(I!Xnav+vR`Pf zRL@^&V0It8Fsl)jRthVX@3B&nt($)e%oMP(eoGS?ZiBJ20Ry&qCU-`F{#qkFn3U21 zH3(6RouXG^Cw+9>#`OOAw;@l;Ib)I^8~`8;6953^e}z0VeFtMBMJESy8`D1{UxoUH zES5ToFWFCDeB$&o6GcGFwvDLO5Z3fF!36JR@8#mC@_LriZKw?^IlUu&8&#N@WL3A`;@-)2HK!{Yd|eP@49`^LRL=ljJFc#FR@10^VK#?^ESR4+)V6g0 zEr*Jo`^bQ*pVIrHTE@V3?Qrh|Xkx(Zf@b18VKvS{i2>1%qmkT^uaSRk4b*FZhm>1J z)$m;NRlh^an;-4Q!an+9f1P4#3(Nh!FM1tfWEJ_d>I_ z4h?Ua2%ht9Loz{luEl@&;V`YK6g^WkDuwU@8LqrQLy;vHbDJ@*XeA5gten&|E#IKf z#6m*#EYjlw1@5O_FvlsVK^S{pN#lIHKe&9dvwmd$NCF{OJtYM9iGaDzL>0I2 zNfsjfid5u@ud6b~^f`{z%^u|3N zr@)P0ojCY~5bbWS`tJQpcl{c-cSQy5nEgrdow?;IZJ~EX!Rf0A_gJ#^RPJ6$QpUK?c+J4}x}r$b}o{mR90rK}QC&z?wT2 z^s$9%tgn9#>}QRq-UakTNNK}Gcf>LZ(8GOVQAQt`jYuXKSMWqg!|}xaCw*?A*Ej~S z1|n;l06q``ZPq#PV34@f*S6!cXYmTzAuQY26BOFshEO5;itP$e^J#7PO(b#_kWZj0 zKtP2k$s~<634?sNYoSg{dNLm3OdzcTT=_$;_R)X+S#@LXh~LDSHSOQNby+@MXt#MT zjeeh3WUOk;L)kWnAO0fIx)4DT|26pyvvb)aUfu28u@n?7lg7Io4TU_-S+#2uX|3(nR}5l zUbIK8%QXq+s31})_%KaSQ0}YMPayf=B^ZCWd0(c!Ii0Yx+Ft`u?NZu91)uZK9D7!nyOL-l(x6*)usRf+le7Dg;{9tCJptVze2l-(^%^ zW>U~A2LeqtE1;5>-9M43+kS}URU?DXyX!k&y{#v~(3G`KDxjNMOy7Veuj2HSaS4Af zp{gWa#e!@t6XWw${Qlz;AN0MFMmgs0HX*F_*p6#@1)Iok;iETlS0sCARy!wZT6m49 zl}+$+;hY18k;|je#@N9_ARe=vEnUW+K&t}94-$U`TP-zDdY=FuZ?c>jPaoloNOpN_*?ty zh#E+lJ;4j?q#SZv%Il?2ZGbUnDoOBdnkYa^ij(qDe{un7(|VMU&2O)$-XMQeh?P)L zL3tBWlKT$(Lh8B*Y+CgB86b?LSR5BF_du1$XpbD)y%B&sG#jQ`CT2o6C?_uA1?^z7 z;fInxWVq{lZ*v~BN-+?;5X!Jyf}r)Rlw;b{JBVQmS&X}KDs{F?)qar4rO9*3*M7Be zm8}u!O)RGt#@YtEw}xK0-8X;fqmqELbtYNl!S)(R^ZiI8(}`%Un+x(Sg!zR3yO0Zv zOm_AI1OT8C`M>Xn8ae2@{t<2e>*614qiWK&YpfWZ@XNjkP8&FywbUyjdxRg;a`?mk ztpk(wLIb_z5=6%_^+(plPJ(oOwAj_~dfhJOG1llH&rJ65?-3nuc6)#BeDGgEMI0e1 zI=!B`F9pM68b0+>ku9S!r=YM_Cw2N7>7ycu^T~4G_w1D{*U->INkdUkLLMj%9s)Lt zv(M;|7qzbl>hJ;gwU2@yltODYt8U%G9s3`{krXkcp_7OJwOtfsF*Nv2GUhi#`l@c@ z^%Jis1`SF?trFn9`5J$5jOQ;XjQpJaAUSfb>-ApbN5i$6cKq+KUY$qySQkLdyi$v> zV~k~^stsnKo$9TAWRG0Sj9G6)l|WLOHz4UiQRxV1XLj4N1|(Sz6z86EO{nzMoN}Vm zRpJa(Kv=IK(SI|#vot&9=fq1M3g+`-<~31C3T(90MA^?7oS=X6t)%s7!U+}8PVpQL zGFN9x3VNs`cX+Lo-&-IwTWA;AD!&)iDMo9Vco>Gw`?hwMJ+>0P6~zw?xVEidyV!mG zSuBtRsH9V1Ku3Gy5m%%hxm4y~6s@XCNuDz0@3LhM3;)u<&m3-%#dWmA*(akE5xi-} zev==(Wx2|#ByZX!JS0C6&X7Z>ajA77yxAcn|j{NMKDp3D9XU`FyQ;3ucL6v(uf@2 z*g$J&Lfs=tcZ79QHVZf^aHw(@qf-Jc6rVj*&40 zE0w=R`Z*Z?$SA@crN0c5o!2s78-8wqF-9XRM&pKyrznPmMsTh!gVP49STi=(uY!Jc z5B*izwvUTJ@*kx(1M*{cu3ouWMi?$^n0J+GDqDXnamlSn>@T^A86>*i*n|GZR4NPp z*6v^sNFk$wdK#XL!MZSZ-`N%@vd9GyB&P&>68q#Z%SDm<8Pv3!S0{pGD}$UYvxu}E zbo?jw?}XCR{EfouRgsWQ$r1qd7jeEV0jNUz9z-9e>(8dcB4(ekvl#V4D4X-(lgTLB zeH(u?L}&W8;+95T0hwAO3UT$KcluL}40E}r$SX`)l+RDsAn1t_dF~qJyKBW~pUA}Y z0$)J}VboVS_xfGtpAwZ^0IRI3%iaC{eDMWG8=XFN9`-FS&r`mWT^-M_4)-@_CvP$3 zO>{qKJG)xkoIRiC&TY4}wL4oserDcnU+sVL%Ooi_IkC2G9#?eih-O|!OlEiK@(?Wz z8G6XZ9G~o4vgfPXPW|xpDu&;`PrqGQsnRSnNW&otF3YyUi`nn+dRO5rMWYE(6i<IetV?FHMp&nImdsiu(%Pb zD&LS)1{ZaJ1Ec|=4hT7x0A_p3 zh7yL8b59M+ETG0RPTGgmDTRMZYxNN<&C%nrJogN!p2OmN*Q?rn>Kk_EoS}DmNbl<~ zL5L#U+VZ5mot8UN{cnmZQxY?!Sobh!miR?+jQ^lG{Nq?_vBouvwjb!j>hr{x3&3_2 z{z{P%bav`$wTNplWCF&R6M$L4?GABq<{YDt>bY~F#4^(!=RsoSVrNLWDq%m6a1Iap14I4t`!4x z4bX&I^qlx!VN`0MVf25c<>x??DWpKbyJsRvW0gDX2x5hL2;xs!SrA#qk&00#<$$Q( z>-;%|Fi>ZL0g0@|o`MN}vf!l%(9jEtkr>Ogr=?49^Q{B<$A2eSE`uyHZo~y4p%R>~ zf^4lEhSdkO4hW1-(#NP^u<|^ANTN@yhv};}IdZp-wc}#`qhNm)rN7sd^Rg1IOlgi8 ze4dtDaA*rDC_YAiR>1%hV5TYaC&5{=2#|0{cD}Gmfy}8^jDoI}V0Me+lwbiV9*$sa zVr)~|mTGg$gYpwvet{C^NGTKgnuZ^pJ0DcOq4hM+`R%pqybVxkL>SbVws@$ughD)P z^hUy9=gf@}e>{JUsDve_EGWBW_qjE_Vj?(HwjrAllTAQ51wJ&a4yKGx(J=W>j>}R* zW;BdJ*oMum2(ivQkc)2EBT%sg1iVM08c=OXi7qZ_HGIcowFsO9BV0f+KZ^^`r;^$I zG2aTDGj@Q5jZ%XjOHAR>RJBE|t3~VkahrW>Yx~iu)yaR|#`(E>avo70acN7dv!V0h z^t$G%nq2k6*Nx25&dohGV1F7mGwO#c=c&eZ{^X*-Uwp z=@M_}T>8z+#PiMB609ZqoV`RP0K-*Mbw^kPKS|2xMq{Vm58e4$4bt5y1qPI&srTcj1-;b zfV=@fSEXyE6#A~F)EZyWJ8ol3%lOdLF$L;pU@kMc4%eAtBrkZ?4*Js!2kZPr8rxKx zXry)tM~=jec-^@jG#Up$^B@U92jaZLTi$bCkI8>t#{!+v-u%=N{BGc!h&(BUR!SG# zxCc0PJcYw3)aLy6#rTpl=aGWZ5ID(Ls&wEj+l??tyuxePr_t8>1@RDQL@^uMpfL4t z^#nYav(Th?CDh|iRkUJlyt_y-hl{WPqUh$Fc5BWkpsCO{)`bBRI zO^n5jJR61O;VjnQZkA4VT*p9d=fBm2Xr&~v7^)lbVn?<6(BnK$LTE(mUcSos9yMjg zEt$b~9GGph^d36YW4jnk3v@HOrBtxk^?iSq#+m|rM=xEDh-gMD9b55T}p(4 zI;hj1#(L?|J9_HVpE3u}?>2|?;P;(=z?$gxroEL@JX-oo#r;WfCVx^K^&ct@ z?!PGRG(?}OWbD5vE+Fv_ii^{%MO=Xy`Y(!e`9*OIqY&!(e^T5T`p7>hu1T*X(&~R> z0*1j#bB|y@Zo|bJZyIXhI-uwm#hIsCY5bzNxc{O!?c7~s+doCzVPf4siMY9ch&YEP z-b~H_qI{8kfrI{_w_Ysc5X$1vjBas$D`>AT`6ExIJ#-Avd0ORug%b>y4MJ31n zV<<)bz}s#jhQnn#%?M(7+Xy4h`U!vJ?G7m@0uVu1J)e z#AJLGkAz{*9csBlPoo8x9a2bHaQD1BV=x<7^C-3jx~vjE!dO~}fIM6gqe={Es3E!Y zPYX75o?jEv&n7Q6KS~a|-0@#J4xI&b1W8>-Tq+||3M^3F5u^c3so{#rm3zx6pYz~l@OsGT73zPd62X0#@lyT6PEKS$?Z zgPmuJpAJPl&u^+xjg&x?eJ|ay^BtjZtBP6 zXS2ua&dJVedW33IGVjL6!^XmX`6=G!2o{dcmpwfWCrQ)%)6B_MmA8MATko0Y+s84} zy_aU`%VSpU4lh{GyOZ;k`_nNoA=7!+yE@(Fc3Y&9U94S#jJFyW}!k zv{PHavc8|CFF?YKQa{U(%-*l{PS?KQB(-b7}FEpOOJmd{0RIZ=;oQQ7z87z$VS+#doj7Z2}iZJ>Loxv}cHJR(<8UO4G$(!+x@k0!hOit3OBEnFcH)BM~+ftA+|) z6C_Xkj?w4SzfuzoSsKf8up%DjPCxP-fjwPOW?_A!3tmqr({O)Dz2~hO!1+}{{o^d! z8;{#2ziU$LW-3seBUXAeC+lC^6y#zF{OND?bp@x z|EUES|GNb$;wEJJ=wbXW#o7h;xWw0h1R$J*VRC=}Ey$1%y3&S^;2DK53QY&Ttqoj`I@&)SIX4KI(dulv>6@LnI;7*Oe&khxvu{^Ms$zfYPg8?wKI?iQTC4 z?baDH%*?Lh%@C;gj|%$S<|z+#;a0{xwdohFUB~H@GMImZR_WJl))pZoYC3X-LN{aQ z876f1;w{2=v9txem%rcIjfv=N@E^4e(?7S31TX`F-=+U0!hub#Hos8Xxp1IP0}r2+ ziL0P1839w}!+BJQzb2GU`vm;$1lzdBEsN|)=pSuEwc#glLm`Ak-F~Ta@#U9?K-owH zqR9+bAKQP}E>^K~lnQbWj+ZHf(nJzIk6=6yO-4J9iZ#p?Gjf%hV@kRBT!JxM&vB>R zqyujFmp1kYtOTRYUnHI$bgh(L<_{h2!865csp|{aXW!R`I~nuU-q;XB*et4Y98?ZEBPWHsuD{)mtx)BAUgCA}CYAiW4iY5Pt8b z@Y;XAKhfAqna^<`X}*k{mC}bX=fxmAVF5wb1v1Yk=FR(rUXqtOG3se} zf)UA3Qam7WF1lEs#?eSlxwMl~ot*yE zNWYaCXbsG5&J-mj`uPyNt%Xn!zxqKVu2X-MAp4Gu*ApS$GK_?-xy+j3yTE^ioFv!j zj|hFVJ4V!U1FnRL#zT;IB3jNZ*D2HKpp8Evg<}ARi(-`sq#w?alN;}&T&xi%AHZB$ z${=2}tC6=ngM&|UjzSEE)RJD^rNAhv8OC@PHi>iA>r#5dsWuH8jhX)OMpTK*=Hq_~ z2|p!`$8_Xry1@PvxyF%-vh#AYC~2eOS17h5eCyH2K2 z{I-)h#UmPw0Gp-NP+Gv*qe@K@WhGB7Dhu|8N{#3PZADVSNx7K%BvpVZw4L2dILcaR zjbUp|P|{e$g$gA+n%Ulk_UH1IQCfdk!B$)-^3b77KVss5oNztKk||W%3pvUVBYi1z zD0HrZz5)noLK%W^5o#~K1mTdhSf(3r(7VE(`b|v?o5d@jG0S?nzzNkairJogH6%T6Ucx6?{qBV z|8(sCe|9X>|8(sCFLdnD3nua4#aCGZddAOMYQ4donc?HuV0Z5@pNSLW*fNgwzN zUU6Fzee@Uum!Mm@d!5p&y(zipe8#G9AXMS51ka7A>CD74HkSlXNIKz7JW-x-b2jC- z@B%iy99wjUTqC4Z>fkYYRttY6I0K0MfaIH@5;P7@+A@6%P!)y})vfZe`7CP86wxt^ zKPYTrw9-TZ>`|Ay6A}xx4$Y1;iZC=gK}M|ha7QC<2gMHF7O1OD-m+)_$O0p)L54sa zVO+cA;Dzc1p?L7`14=#pwlOSXb20|(QFiI7fQintfjb14A6uZ0luTSG zE->=s*9?y0eQ}wsdu3GxdJrD&h)njvf3s}jFQ`GsSm2z_r{=KyQ;mB$eZxv@MZp5ksxHZJo}~xF#5BB zUTcWnDaRmGbygU^3`sNfb!%GfHh${DMYI&WXiq#%q9^rMaTeVl+uC`@zgQ41e!EqS zTO0i88={Snp#OiV= zpaeZ#QfrfSUcYqbZ4SX8&7XT+T~fS}rU`T9c)OhY{;q#79|kT@v|ZekJXxqiA$22b zo>l`R=GXW4-i>U$wg#`(_BJC;xK z_#5AQBdG;hU#0HxJFnMKN7))Ry@^{}HzDwXKAz`2K(>4^Jz)QCAbfCob~62Pb1a}g z4#fO36FYx9I@wzP&sg{i1#um}rqCF|uEd)JHy6wH2?wI$l&keHF!=JL8BfJgY0Giv zD3tweyHFAX-9Wp=p3Y7`I=voNT{pj3&QYrSbq{s###1hiS_5V+Ql$V)Eo;=aD#oL4 z55uN>Us8PzPyt?Q+#hs=Fo&wHa~VcpbQ*eHeWHI&qD7Q=Y;Z2#BqR}%bT2$wb~H!q zaSJ~(t2p_26$PB#ex~;sZWNw%Hg4jLlVOwU+Y^&@WIYCTr6L?r7H$VJ!l>O10PdI~ zGmEhUV#r7qq3luT1-@xViM&11>N=PGeUnY%+;%95n;B&P5$o{e@_qo7vRDF zw`AeJSN_+u$Nvl`C;)(ep9J}LJHO|={R@9xF#kRS?(bH9Pqg?KVv+uR+Qr|k{GJo& zFHqt9`wT(9TlxJU{a@fF`S-`_f4B1csl30yLi4w0^nN$+`zeXPaKQB2nTg-4{=VDv zFRXC>{od2xE&RTD<}XMI{QIpmzgzkJ_Viz%7yb7)tADrh`wgJKfFkwpZwLKu<@bLT z*1zy9_aCjd{%-L11tA3{{*Tw5{&S;Hs{ir2$A4~gSM5KZbN_DiUuSs#jCKtGfd6g2_rF#D7k&QE_^J&6 z@Vi?7z4pI~ntz6f9st1KNE|syP_QgN{*3YKr{vdFt-&9q{|8V@0|XQR000O8T3K~e zu=C7YJ#GL16N>-blL$##r;16lAp&g zu3GCzY^eiD=2Ec?75sz~v(Qws=RcZ~CKommwQoE7lFyXePA~f-G-@<$fu8`E9V-o| zeykW(y7(tBMHDE2s>w-!fuSoP5gbgA_85$UA@fhFvP5w)BXx`za-0`1p^aM3vV~^y z58NIziEP#H;;P@y>~%+fUC_ydkI0Ulh>xQp=gcJE&+H6;uwp5wApTZ zfWzl1d0h3^=B>|pOi~cGc}=`yw|PamgQiPaKHBE7M}?pEZ175d9(Q*fszU%_x>99X zLd~Hk!Uxo(w=J2%z;aY}<`cD7wR}@Dh1DJeUf2c(0Qmd_2KeU~N7n5$0s0l=TfagW z`d5tW*_&87(9`|#_rGKNzvU09h?kWHX8aY~{-1>79o%bFM6*`(qCaJg-vJrZ-u2nj zVhdW|AH@V6a~tu0+%v0Ovfa||O>6UA^AS9pk&;Cr{WDGH+SGcb-P%*WhqM+%9lV~a#4V>OiwYN01wYB`CODs@Tv|JZM z@TR}x5A{laDNG_AAg2L;^(+czVGKh?Mo8r~pVFi;Us%Y#lo?hwB#UFNLNH zYLvu=D3B!d8JunS%p)Fg;d_N>4vTeeNYAkCN_#f7eX!?`PNbz`8bn6lp~R(RxpwQ0 zhehAe)=~Nz8!s6TLb40#G{ZJAeb7?Xm45!MX64X-QyI{g#6gk5ai&F|HZ~TQeC-%Ack{WiZb4XKUp^AZdx1UB4)UYjK}v>+rjc46;T51QsIXU0rP9 z3Igo|JrFu_&5EpQ&Jd+Qy+;4OGiZ3?vP&{M5}gFMfA#CK(hHCcHeN-aK8y>{T)!IQ zE$EbgtGFCsy;?$cDE=wd;8&&TobjH4SQ*)ATD3*HeyQc0kx@K@m12GMPeT@%*|Pdw zfg3*L39N6-)9Y3tqIYVvIza`;sz@nG;ju_@GL1lF=G%GF)%(2eFFiuxKZ~Gs(EJt{ zCd_fo9f&!rAk+oUkBB8jg-EP#MEvLFN_3LN0bWrX3G1DfeOjnT7wMq}Ci{>Hz{OGZn>ONvz{s#Y!)FqPxMp@ohwl!6M z44;QQsgO^tL~+&G?h1P17+@v1Ab{N?sZ1}dadqdu3k_biW!`vbJ;qeCYO#`Rp{f1_ zyO}ZnWU+Ug)X3X>gbnRNh@scnQ?8YX2T=s_oCvv$-{2+rE(EQDTL&$3wmCmX+k!I( zJGimUr2AmTC1OU`nJUY^^lnKV=_)&aLd8lzVeM;5$7u5)5T^eFRx2cbX_uGqiWo#> z&4O8C6j5Y+TErxSW(6i~PhoN&rr0V*;Ylp0#X<#%su51t+SDT)IKJ-3?Fqu<-3`VM zCD`-rMDDNyfRwnXR}}CrRB-qR{EuNDcg0t9d3<=jv*_oPbCx@Hz8#+{%a7N8IUjtU zXAqD~X5!Fe$WVNIn1@UBN9UW3rlCu`qpHtQm#xTicvL*jjH9eu{ur=JA3D5q93M|z z;Yc^R7&px$UhpYAye=Q69i!;y<)o{S(g(@?Du}|&vikHQ6P1$Hs~r0a{=W=QI8@^i zv|l}%2Pgml761g`ukiePr}mG3LHeH^9N@1G4iMmfb7@bMwfIHef*yl5187rF@LV3 zMExM~nbO5;%p|1LDOog&^#s^|z5B3vgsLQRfjlh|KU86n(nY?X64KXy6)t9A;5B2X zj5N%9G(V$Y7B#wO9kVPz^1dy_Sx?xP{63vp2MSSf&f`ue>Tn zEk08g3IITr82|v|PtbQTGcj>=p#R$o;~$Qdsk{=t#(?5Qe}^BrX{6Oyx7?2@6_N{V zLLr;-RW#X%F&UM_B)N`E?&+U6s)IPS1k?3~{$_f3>cH%U zD*hO*s;>h0D8xa)VO*iTc8CzY*z-)r7EmEH(sC;u1>!webMX{v$iUa9;rNbIWIs{3 z1m|zB8S<5Id<}F!W}muo z>KV6+a=^?5es()%e3D>gf`oV2t#!vyxob(d^4WTCM>De{YO`i1vua+hhy0PNf`EYYoe{^Q?Lkg(?!0Tq%Lq7l z=Wcmf&lQ8*=KM>a(GT~X@3(Z$)wq23=ySqD3}DuOYX-~@=ltLuH0jCCq933(7$0{LHdUM9ve)M9_b#q1kFft9k-+@Rl>ad z8&aB8(OSfY&wT*XW5UY^75mu=*uep))ank{FRfF9K+kYxBIoO!-J={o4M1) zr2*%AyGNYtTP@dE{MHBJ_pa#dPj~gLjW_q^HaEF+GD{nzRbr;lv%r%ieAhkMobyMr zfcJxo#2SP7cZ=JgWladJeB(B<_;~4u@Pb``qy&=94^D~)XU5z4MNl)?UoGkV;=0AEX^$9f$W~G|z$dK&nR7f4=4XL9aTSGmV!IK#flh&k znf4vD{54mJ4m-lI3?o2-0ZgU6l4%8Ltq~y?MPO@0frJ6-2D(U|4(TPE8LqrVnerun z1Jwch6?)H_JLaPqV%OpzYJfv?16Ov?1IBg{!R)z_2%P~K1+7ed^fX?Uq7)7-@YLUk)nP{BPCpk}79xifiUnZearG}h@ zuTrJtESdw_sIG)ENdD50FxVLAW$?7}ih6uLTP*{F0NoF0?spgVq{c1poGsP~&sT*@ zZB#y>lk}QNlJ{fKU|v;{CemI&Q>q!eb_goL{o_P=P_7iuHVCbYhPI~0Z}VwlhZ z(J9nj1UOGz1U%Ta-x%3Nu|J)u(UcVyo*;ng_x-NM5v~TVO5_rKz{82YG(;gKqVt3& zh_In}h`1QLJDit}B$;AC7x8z@p%1^*k0G$1v>U}UImd~bSsbRTkE#Wf94a#eVFqbT zHdh|82Ih8$M336ekx{3Ar_F36R&aadrHf$&X#};T%>Yj+(LB;B%63gtR(x4zs8Oi7 z!SS@?QXj>;y(M!`3`sqxog-13+Y3~3<|vc+^EV;1Ft@r?RkXKA4iz%PU6sTNt7!Sz z%`d^>yxX#8#?1m-qc)uH2W0|Nz3K6javCiAQBr@YVJRNko;a)Q*D1J@|58KNP49ZBcuD&fLZyK+ zDPk1ZKe>i557w$;S&jflx~}Jh(g0r)4l>{hFrxqs0(b%FEa0&pe~bX09}a~9;9923 zH=faVaBx?}`nZL+esJ6xEc6{b(k<7~LU&KI<)ye+-M{S z)BSDo8e9iC8*0_Kbu|kjAC~Vv1SoW{SIWibpg9&%@=#kAHJ3Sy_AN5CS)Uu83)N^^ z9bQUt))Bv&tO4>me`<+qC{DgilZ4*hn~Qezv0awK;DLFHm$d2dI-|6}Fk6VRL1w^9 zL3&M;Po`Mn*}Y*!gv=9Rt;|b_5&t`gX3;KR3Ft8qevu_#c3`cPb>5i@lHraNa9D9N z;RRYH4d2!flSkZ_n(rtdZE4S*^q!{81Z~^H{RMvGpk;=1e}VLWFM&e;u>pVTxY~ zEK`Z3QyyESe`cveJ{CLJwgA7LxJiLJ9(FG`AlRgGna9#?}yUay`2V5(1`CrvR8)^7fI1#_0-Z} zj-YH)x->mstlS(#_X7K0-q@_MKeTf|0RYgE{YwhU^fwBcsAZeMfHJg2e$K7#4X-~O zMNyEhrg}QYQrX7CJt$dWh_fP>V72P9Rnz1514%jp$!a@utL5Fm%^@DueRmZ?6+Kl1 zQmoyye+=cmv3sj)BkB+XQ~ESst?Uq#&mq88?Q)AYMv6Zj_XrIzmko4NqfM{B#(B>02z5tExo{i08!u&YP7`0fEDT)-8)dm9E3s%^g&Hq|!04{#1(a%g*5&AhJ zYdJ$8;S4LY;N`j+pON&@S3N>%xh}+zWM$V|e~Vgn33c9!$Y^w0vX4H<2d($%m7Ykl zr=H2eh?rnVc9MQ?2JowI?6}+fO|C2Y;EAxv`+-6@ZAPs5LZ? ze^j1h=20Eyw;`+SuN=CxduR=s$v`T5TtO^bC{Mr|Jo}Tq*l!4LX6_z$(v;8LCD@;y z{%vDZa&xK%iV@O!0 z$5UhoR!`zpw$!-v7WyG_W0V_bP@4y^8w}AxFLtMk&fRfZcH_f%(alZr#~gm{Gi~!* zz8hHYCDd4IRmB6^KK*$9S>3p)@xa41?_@%*ADj(p`BMZf&YRqqH5M8WkR3Ttf40N~ z=^jvF31OQEa2W)^jW6;O!Ji4j3W(5cf&;>=j4}@ygk}G}6)38SU^!3)-~$XvqFl0c zPCc0|0rSLE0qwXTNjAd>J*e~}>=N`eIA$2hU5jagOM!vKB`?Jb+<(IVC^z8txx zCp&JMqmO;MlqZ9C7G2X;Q4 znBp%zVtVV-8j~@z`{j;^=+RkzPX|<2YqL2MA+}@BR}$$-vod5dd#%bke<&KF!O9gP zy2F|NaW?ghm~O!oHR0MDlnoWMSB?{6=0(JvY_=5$`4U3J?+0e-IgxZ&hg`LvqCfNTPl#&N3BF|0dojz*M%W*8m(J-~dy?FuhyYXdDf5ER;i9RBrcts~P z#8{k6Xadq$C<)jCz*(hVA1s+6h5?=cB1)no&J=jm{qPkLFeI=ffQ(f^#ET=s`*qSH z35FA{^|--v3AjnnSR@J108&7BMgAzHh5;96M#xkdrtRvvxme`|tu``C5 z2hS>HQLr3*#CXGI{O*l2kDb}#Y%`ba*JvSNi}Oy8`IJ)xf2aspH6r+@IwiN7+oDvB z@#L-YYHH#;7E1YH%(YaqN1qYj`_LtdCa?U+^$JE!mvde|{|tfoFQ@WrYAByyXncT< zTh~uHyhS8QxSc7KxbbElHhc-ygflrOf3nG*K;gy&Ib(yW0i6n16($TC3Ht)6ex@zU z@!jh!e?uY=f2@#NvR=6evCMI}xaRHhz*{2cGFeU#>m4?}nNL+6=3-2rzWzy?QX3V9 zK?@z1DDXIt@AYMDZ$^7{6f2sO%~%;(Z4na#TqnCIQ{F)=a#9nL`ZdhpNR}GgEc!J1 zBQBe92QssKLVdYXXYoy7aGaZ^@GH||ef&(_BT!$7f9GmC-tZyRqz-Y;61hPRnR1== zn2nLQc2m3F_tIDA0)78)IeUlt+aqAerVNlp`rXnDod6zWG#+KKGm@EuAO>hV2)O5M z#$vCl=kMa@UBn__+`-+Qut2>yy#^$bI(PW1ieH^LV?00 zk-vP_e>XHVG*CTKeO7k64;T38gKyhsWX33{-AJ}Wd=*m=Z}8{IhvdP1QP<5lZ4y;g z@_GRI<|tr+Eit9-Z5$v4O4b3XPhT8N^xgWQ5k?OS)6)((l|tz0xz{5JF8km(CGYKr zlWAZ~q~n>%4wyvq!joyG!Ja}Q-7`(%Ry5UAf7iYUA=5OY;Wb#l>=fj7i;e1%H`1{! ztcY%+sH`$+@DA`i z?<9ZD(fNmb0pS>Eka8Q+a-BY^#8Z(&e{Y{y(!I{@Qm~>ce}5b2-sqB>XU$2mbl7T@ zN85OjK5)d$gKB{vy?CQ6%bM^<$g6U{18OP!(rtqjrr~^k!0f4f7Cf1 zi_sp9HIEyt-@|LFXfK2DV=uFdZ;jO!K4I9dya|-kuR%oJq&~2MDU--IA63ynMGdi! zid;fc)HS2Y_Tl=I6b$RW0uT2R1?-bFrbvQhL9L2K1JXd%L_H4@M%>s>(JuaLsF16q zBItNo!A5>;+(IF!3MKl6ICF`;fAenkS?;QBTSMRN>ZNo^W9N=7y`XLi;r4s}`^hF+ z+2s2!-Ng&Gp2tv|?c~vczmX!Onf~2O{!-X4&468&PimpTc$4;Ye-LKN{$9$# z%EOABykD0oZ<&8KlBCyK%?)$i)6t0?(X7=t&6T>iHuB*XwBkah(|YJ<&T|i%k9DTV zV+SLD{$*l#zLkK!91;Mai1=T!P3FI`O%)y6RR$EVocd3M=PVLAUy@J-+48dc!t_NO zFScmF2oAAE%4+jZuO&H|f7sX}0g#sHbBBwinj?5|MR0r>bGi(q9R@K#%aRJ$I=Y#u zreeitAZrQbI8C++5%Qv$zTMm6XTh?{O$JjSeKW@}w!t$~#e(Bt$UNZ|BiM?H0;K-# zVoh=PVvJH8iFrk&p*abJ&F{$uMZtE%3*pKS6vw*NgY_ig3;hCbf9`!Qt96iEfpQ29 z8<%1#;kXJkZW9wDad`sME4Qt2;WU=Ruc1SMVB(-%ARnbJdxup#ka9`$_9jC5(W|Ld zbM$#cM0ewkS)T-0Jkcnx+l_v_s`h#kuJ(sg?zMMvwa01W$4%^qUs?-skk1<5_Z@f8_xE!@8lqc_sB^95REVaVE=r z8oC7(n&bJ=7K~LKC4*{I3RbFl^sW!tYq&Oj^pkKehB$A@O6^L9YdP`?pU;M@I!y@= z7&L|JnpeyP=#Oyp&)MsYzE)I?M6as?PnYdX8AzzZQ}3}Mf3}fT?6Kf-!gfFFS*Y*cj*uCfLYda3NwmBO{AFt;HkB&>N_s#2}i)RY&);iqlF|V!0*N*q8 zz2gH)S2wTKtWDvr${8D<$NLx;jtlsy-eC5{=C0JsH6p!Ls$G2X_w1)J#jCa6viA- zE6BX{EWtMS3Kh|8g~f+I(~>BeXPLvy7mRol(&e@cijy>wdWG`;%2lNGE=l)>x{f zGo2x+7QwVdEuLsv4jH=4h?(M4nj1BKucTx#e_SeI3tncmh|C>h#R`32ww9^^tg5D5 zqcXgddkwfn1NkP%gMd#004YdB`B1?9f<&Tb=#+*k0hFX13qt}9u$OVsuszN%zyC0JNe ztXcqx0w?H*fPE}b0Z8dDUDCOgYC@W@e}BKoh?xWBwiiVh!Tgb^W|MskRNPJ7La|2qEu6`xKCN6@ax#l=?KXLhIBbVJj=8tzyZ){Oou%~?MGf5;h5_;vf5OV& zn2h7Be4}LuGqOfzQFfWVDuf(48m-tCD`f~nI&dXqLa^(k%+a~@HvTYlVra^fV(SX)WgpOLe#W^KEs zg7QI~%es|a_LZY2P@kekVYa&SNt}yfAo6Xi5h+; zg$2j6>DmI1m)BMkA^7xTLn0bB_<;vfqXq3H+W2YOv6W%XRxj#xEX7I=?1)CKTN{jp zGTq=LLlZng@Ci!($cN5x(iDR)O^UUqy>R>nyJEsqLHNO@%~!~5<}lt+ZJG|#?h~^s zFbSHe(d3$ReN0t%I2@+gfBo1J8m0@cN0C2jMl9cU0J{o{*4X@_R){U&C$ ziK_N71@|x%Q;kG+^YQpLZe#FXW7sG^ciilnd4GECU1qiiaFcuQ0p;Lr&t0_nfP%{R zpb(@2^?mOO>arOB@auh?0)Ow&K;=B`_L);$TG_wX5dTI)UxuXoe_d1qR9v!5Vho9V zu01nJgpm45NjKdEO074J2ZSoYJPv9j+2JIIhnB=prtIK4rS3I?0v0-+#oRbF-VS$_^n|RT&sp>dC z35wJEe=ZRwJ59N|EkqLI4Drj| zFJ@tE(+2tFI^lf@SxYp>8jlhLoMFwNM*3SGxGbx%*T)3%9D} zz~+vU9}WW1R*3&zYbQv_LtDorT~|9E=9V4ekeL;Oi_^0smw{i zl9#Iu>%CJre+n+zKLM9xm{;QR`>WM5XHoFI-jy>q$4f82t#EQV>l7i2tI0j8CE36y zUyfeeK)C`;x0a`{xC!#6^O$-7m%p353QD%5Oa_ojoW_rK$Xgut`gkOgnqAlII=(on zU|l8!iffWYtY~(`?>``xXt8uBNVPXu6=vFjN&SS7f8dy4*CN8BSdO`dg8_HKzr-l|A2@pEmc`efCv%i;0>!eYE&naE+ZG`%y?)bv(~C2@7X(+mYx+eO~HaCu=> ze}XNSui?JDiV$43PK&Jm$n5=BRZ3j-5>|EJyoS6+Oe|3Y9?3Zp!XKo!j*(XuVcca4 zOy~-%7X?5Q5injv5mlvYJM3>rp0;#@J@|$D%=vWhx0GByd@boeRwZ3v7p1ImpAdT^ zCjC=9;XkkhSUBl_{;1vlu#H@CWyc zmB|8AM&*F^A^=_2mPjc8w|%5#Ow08>k5sKyCc>=%6_DZqID?#SWdcZdB&f!v2(H5i z5CG970ylvZ!NPy~Nm=PiX!umc_ z5N^KO>E+UZd>MHe-re(ZuJr35^u5Ij1ty1CJB_{9gPvk}VMYHd#Be zukv!KOq8Q)vs5@)v+7)heIr80Di`t@8Vz$&NGs*v9yO)QS=D~jrZWu_9ph+Eo}F-| zFmo%)Pb!IUTC&9U+e#&m0^{n)v2prgMVPbgu2`*SLs*xGslW6by@M+ue`v_dK^FLz zVMzcNu#(6ZPl6NR##!0B6P1U-%yUMPIqt^~i}TX$uC!#uG^+BoObo?xWJ(Caje$#m zseT)^D=!cIVfZ?f8j5EWXBsFYL; zp;98Kd02`8C8CZ3f6tOe1BKx@h)27<+{c%kHhPag#!;kMD|!$gJa}nf)S|V?aZyue z%~}Ch7HwJyYmEk#1W(!e*54WI3h6JjiJx4=y?7M#P);lk?xAOm>%g5&`G5ZDYxN0J zwsQ<9L!YQ)M}cJ4f3sw&nx)T*r6E!h3C$S`))j@{?6jeTar9S%$q@W|5Dd)>u_BSR zr&C9}=8V^TdMrzN!$H_RYu@iY+%7GBb|XtM6l25`!xx`Pl4&dU8kNf=rVXH7DonR} zlNyzuaW|dgV~12~?=yg4-Do_3hbxUpF3IbIj4rO9=uj#5f3Arf1V~y$iNKgCOlqi5 zw0JcS#c7f-;wW~N*@>w7hgP}<95x1yJ>91>1OuJL4@FK%1tBD=#bvVZ#zy_1 z`86~U);odFln}sB!qe=2c1X{VmOJT11|Vj@FH5L1+5}|oz#ZEpMRWf@P{^Wpm_Ipf1NPw%Qk<6A?(~#X&G{s@%cfj!<{9% zu+s{CRgltTV{jD ze|{#NldkaK=ulL8CYpDS;e1| ztJK+3dGei_Af_ntGCi0);B8R`qjdvW=24<}?O@3In)D6y*95Y)irMnTEcM5-eEr6J z#NcJm74h5Y)yl)+t^GM>*KUcyq~8YQe<|56&amGZ#dsaiCO=Ih<-6p2=Fhzu)&qhV z%K^MWyv!+d>ixmRi5}bJ9mVAf0~@?FjwJDSO#mm7N>*C$32ss~X zTBtXiAc+QC5T&%Malyaw{M^#RG=Y83xbICkCdD)Qy#0FL?$fP}SC>9!?E32Cbn2v| zT)Uz5v$K6;uPUWg^WAA}?EYY=e`{&&-QB~(ap5qdynJsby?rZz6U&QbuXIr&{5F#tNbhtwf66ZX3c zHY?Z7`~m}`CdaMLZeR~g3_N9UQv(cr+QJnUD>L~`_mu#`eluY97VAjGf5=|oQI-=C ze5~NFk7}n95;WqpI!N{bnIQbv)rWuWm$L@D0l)+iw4vQMUNo*6{@X4by@sQ&+-a!tOf=#gl}|X~X!vQ4e@heH2_@4h`*Dg>fi(&5dr8fUw!@Qb%QjJ|xmO4M$yqqT zlmj`#^XV<|Jh0Y%8h*GZ6s5Hu$!Mf(NGHX}#&QPPf3(ji4@{*gF}9_Q;%C@JI`sUM z8A;ucCXJPqD7G69=V3|foskbTQUqH8aa1AMK#BII!f|4$gFJRzf9bDVlZ!;&Sw6A5 zGZx~axLJ|i`AI$*SVe?IxA~%OdjpoW_UOf=&11P(Cku4ifCXiu9ZN?)(RTw zO_Yq4O6F2^mr=EX0HU0Y#L(;*9|aWYQuO$OwAzW=IQVcw%6p-B7Ug6&zQaP4?* zGwg68Z7f#CV123jf3xUvY`v;nX)3NBdFA!Ve912Zl5^VZW}_VffQ$N!)L3+E2Eq_6 zDO&l=9JLnd5>nFXgYkhx}|igAwr`QC;HMV65&K6|V z9LaC)OIDTEU5xT`1eCG?gmo<&(Tf!q_a+KBw=-&S@KynCtXVtzn(M?iwv|sj{^RuX zHn3NO)0`34ur5e!ff9Rqn6HN4MIwDDZN`L^ZQO?kN zXBV^GCYxUBNB>Zbc;d-l&Jy-cc2+J01pv@S{+Hbf+kbW||1oH;|D44Ei69|TQlz%= z_iiO>42JSZ1p?cT|btAj;VraxwAl+^<=Bm^AZ z-YCZ-jYi8H-EWB?M};0%^|DqMhi{QnV&S*!W?MbU)$U6iMoWLiR@{HGUFHK0jl=F0 zTIpejc zQLkBDO~IN4Mj**WU+oOP*}#reKoB8He}}Hfq6AEgB&cmo-@Ntqn+HJ@Qpi_qqa>?a z*En$q*KT2g##j!R_$MX^_j5snHl96wdrW2vMg;D0hUR#13@^OUtmg96f&qcE2AvUR zb4G-iRl01fyHV(X<($<|c;6?yci{huq|7f`(Q6Da?cuq={mFV^=yJX2TwdOk40@RDL2mV$m^3r;ree29Z^^3l*m1L zY0mF+F+LLv4}ELzG@ zfRwE5c@+-JU=b2cSf~>Zqy%4hYHP-&u?UHzH)uqm=wXGocU@T^LIV;afAxknfGfQr z$a&O$F(%bnW)=^XK$pRy>~yRV*Np41?5$#sSF3_lx??4TrO2Pk4ALEd>(eh^>b84J zANB&{<}7r8yoZ~AFh;2%W-I`G*MXy+!I2ckuxcQN`6`&*QpR;NqS&QtTa{(6foNtV z>zqovJi*fK%n1v_yx|;{e-WKH?ol2FmM{rdGg3&iNOPqbK9g;{cz29R9A!;9y^jyy zmj)WbP-ol^J|QE0WSjw?T&uA)TgdWd37S15hJ`Fu;#34oDHFr{F%;7VMiIG*f&Xf5yZx>&1D#&=Buz zFW6xtAhK6YRo~sIN2f5c3aC z+r(WQvpiNAxp7inVODM33x~{hr`aCjY{WS%0v~d^{~@d57$<8J@CWNLd|v)fGSE33W|;R=;xc$TEvuo@G0!jD*S!gKa8@1v42hCFcRp|483 z?wc-2$y(uCz$&Xo5g$M-+;?LcJ#bgX=62p{$al5A6FTWff7fI!S=zn(!PoqQ7|ANh zX7~Q%uB~N=R^as|>eAH1U#^uO0X*TTmH`~?@MpDupvD7FB^P!`fs>G(s-K|C4Sx4} zyoaB`o;~FOvU`X8D|inje_^!#b=RPR{l^3Ge}i{NGZSl*zyJN)^B-p#^0vt0C|zGp zTrkdY4apnBe~58VxY^8w38Y|9hpye*xm}&VvNFqERr(thN~xL;6e=x9!>ekM#A=q_ z%>^ncQeC6In3`H&_8Y|u6nylB^mD&vJbre#*?K;YZUp866OkO46I1BXfQA+jUe2*t zfUvh^L6-x@Llt|CyGmj8qz-S7zPw)Q3|dl=K?+v$esEgqw<8CmC|1kPRlOO+Lx+mNioO*C+>m_Z(_ihNle$}__$q9^yzyEbxin*mKEqi zq%AMiht&<}zxLIN4cAyP`oS?+f^?Tm!ME-IfI{d~>WL6jV9L=qf4@P}9b;!~(6=?v z8}hvIe|ir7uv@u8QM4VcUoV}fx0XA`22j3jc5d6SNGZO90SF;9voN8Yt#DKun}D1E z8urdA-k?&IMn%{A-o-@j(6M5rcG^OdTmraKmBjgGQL470?tBGie7(TwS=cgTv4GPK zsNrc1x7DIjrK;TyI1pLX$64=eR-B-mBLtRdf97y+%4WQ){+876x=eh4_h~FBXZ}y(-)L z^W@m*?<>-$Oq7;@#2l^JAt1pO*IP9-3VK?qJH6_ruW_{Cs{qpZA*{bnkYWU7y#T ze}u1H-WT9PU=t+n9|!qcIXvzkS99oFyjR`qAQz}RI_U^uKN5uNhmfZyFb0z{@A_Aq z9gSqNa5=zM@n)@2xw}t|#yy+KzD2o63tV3TRz+WM)Lsl37LqPVUkmlp7zBweNgla+#Z53e1`4|-xHh*vj~3xzFq6|Mia%i zbuW9uW=Uf40uA4v?8I?jtcyR$SiE!?O;O6O+YEU)v)H!HZVLMsYmnL@9_eY?Gh7od zkV5aD1CDeyyuP>ue0px^B#sqVe>TybFj#))92Fs!ASFnh%t)lYCp z=1#CB7^qIcG~!8AIJ<7qRiS+Cqr_yU6f^zEWYC-eksGr*m|bI})+$9yf1gmTv=U)1 zoK&3~*m0b_1W#x+GAm(W|=n4CavGFv=4A;R3_8}TZ*&wf-~ z;V?&{PGGosl9+NMe=6y&{4vrA+BC;eI{c&7ccb6KcCT>6j{7!#a?R*?c-GLq76q5h z-`%MN>pQ~ND187UT2EP~f2-E{D11{yZMYz*UDxy^;9E3D8HRQpUn?Dt{oFgeR$4y&BAnvaNtGD(aIE##a_ zllGI_Po0y$jYcvVf0+qU72%7i+8G`vK}ETxzHH7pU^wBtEbGXaZx3z^|0Czrcin=F zOdpFQqlD**bH58Xs|b_FoLcl!lyL7IiV}}0zBy&tu^vmf2WGs6M#Bm7c5U8!#f+Xp z_*tLrw|pYw{=gbOg*H!k3u^x@EGv&7f-?H$LEvK`^D!fMe=PDgvjEA2T3G4LjcgBW zQ1)53V(tTIjTf@43(P29>q%{AIl9iySDuU-2Waj_I_FkAW#L&odBqJpSuo5!jN3Z3 z>k#tIHsI*ZKs`fS3x46z~e_sa-aQkGmY>rHCp0P|Ie}^8+ zir}7F+meiLTQx5_*U>RR|@c68f(E&tC6aZCO5wHk^iWAExEU)N``yw1{d2{k?*qmgb0(w*IweW9M0EY~Fn_lKC^ovMd;KShI-%TUZUX!lWShu77ef3s? z&mr(=LF1=q5Jk~9Wx#%kNKYMx*Hu_H4&CE}#)2C%e@B{eb>%6if zf25z{cEFA3O`4-DP6kKttrfu)MXFO8 zO9FWu(>xbsq*HsAbwE^ED>oq2N^&qr%^neMMbb$qW25iKA2#Lq1T8qh@g*%`YpYdQ zO&EaIO@;%fA@xeV!{=9zB1a6Q2t)`oe@B>YXj+QHqC6CUK9A!cq}^sOvWbqb(}j|6 zFc7tw1=cgHtB-e+-Lnj7_JR{Odvl!&f@|sXy{4lyjhS~i%_qzb#mnAg9P(_h26u`n zSm9S6#@sP#PMNJAZAXMc52~+8gLF$w)B(8gsR?LB-oAwNtZNx#@KAnVt~;+Vf5=B( ztsO;}KG@P4hq2xRjK}e66ZYZth*2>0z&is$t84gSV=c`ZONhePb46m6sUO3F-hq4e zO(;Qz*VS1+PEgOx_wB=hTWA}6`lxZhp(A-MfOJq zk<36E!dK{&R}g5L%FtO!KMfXYXKM?WeZ z^WbYR$|fHxA}=mqN*wmUDsXOf8u*sbX;O8xp28}wcX$S-b3zjlFAGLxSTD=8bkI)d ziR(Mm8_$aE{KGct=!{73kcF3|;g#2Bg6Z!tv5e|Ch`rwuVi2jeXXgA{f48v7_i=>8 zfTxNQt(~Bm_g!e++Z+s*QHz7SD&%awgPo=f_VZIJ6_a`R=$gA$zh9nGRPg zfHzDrIrD8rg2D`CnL=<+W+kg|m9h`8+=Mc^wy$A`@2EFsMuhOJ&@m1i)>Cv!HtF!% z!2oWAfPVsKyat;}11e~uUk)Ix$}E`UMkByWcrM3jwm~%8U=RMFe^L0SSh6)_E-n%q z@Jf&e-(~r?A2gkFlBljE>-FbfDd*C1Sks}J>?3ZeEUKS50d#G^1q^b}qR7SuD}ymX zEqL`b+3EQ?Xkoy<%8lsw1Y;QL`dM-Ft}n$TpQW(t>k_&ID4zHY-sazREPYc#-0=X$k!i zsGL6Hr5U2-ABh_aXV=P|L>a3%x|ijrRzJ0U9ygNdj*4zA$?j4L>qW{%IZg-07JY>H zU}jUGY2EWf%vXY*oEJ`GBT4p1x(Gu>(C;iEUNUsHuOxDEe^JwFqQ0A8&e4oTsH#AkRFQV4IBBtmHb(%rDWUS~q;EQJM1|{kjs|3RNcxM#l zU4blTWz-m-vYbc-FbauHIo}^QRJkj`_m%Nfg9eh)$yv{303k5Fv9JPzENOkab%Jr8 z*huOKH%q`)f7BKf=yms;6JxekALC(65}wy6BbeCK_7u~Q*HXK+g8RI2c|}6mC;11$ z^{H`*;7pV+nycn&V?dUQGl4UuNXP_U3-hdV1HKfnSBt$NIB_{yNb}DK6qqV65yh^B z-xQf9!buSnQPD{PNt(94pqdrSQA-hmVFMuNoz4+uf2FZl9vdpH-{!SkVeJf2lO~P@ z5k_>;_O4J=Za)}IG8yc|$FE?CdL@A>8!poxQEQg6fVao*5t>eP8%t6&2(uvO1d8l)_SRDv+ zG#aR)KtRatd9_KN4L+ezXz*=m=z%+rO#bnw9(lPhq$9ag?T;{=%A?`Lb{*xFdO^? zpkJ)vW0U}d+437b)nj=p!tqdieA-1n?ZSrZsVQ<6FN-qp71^;&mY!#Iu$Y2#of>#@*^jFpkM8!fwhk6{ z3WxxHOc_Yg=qmo)#f~8Pu)R?)?~rd}??E9TNnpzmtU-g{Id_%&4HYgLuHyaV!};aO zV&zhH|5ehKV_K}^_~%CrI~LzMe?K2xvAv%66Ie4E?wk|2ID{(4GZg+3=z(?8PL^f& zv$~wXysw1qu7^Y1(-mV``6d1?kbXk7{HxJ(UmVe6GO)%m?9fR8J0`qX$AQE#e{{%W zmDm^};A_c#sakCT#fOF##M4X`_|XJLE9#B$aM-?%zSvVLBP3-(AWBY9f8*0%FUfM< zbFzB`4FCYm2>^idAI#Luz~01I+0owI=Ih@Hs+N{K_7a+ROyVa)tx8xKhX;RRC@R#`wUYAzV|SKEe7pMz4?g*Go+PYxK#c zM?CnxNL=o0$$8?Wl>SYRe=0AHCELn_Ye5iYH;78t0xhnA+a6AzF2XODs z%jYHdt@V#_;-FqHzYs6r9^cQ-BX*zRTa(KPY~EZ2_1;y1pPfgF96V2=U%ve8A^zO! zRQPH)jo&>i-;+D!W#EbP(n8I`v481-;lBSEf)DTL_A)LHy0 z*Cg(a^z(BH`SZ&z_7-nWaTEFc)*AA~{W~JAn#*R%QI#ZDev*`hi3T;QM{92fuZ~r4 zYGKUz7YV~PE-~mTGeSWJ4`Zj&NeoV26?hlHx}L~>X!6VJ)s@^WmQ-&M0f0KnR=kzE-(qU*N=~A4; zp0NCs&qZD_n4|gy-JFQrw1c@RF+$YIRF|@f^2oe4rF5!=J1e|h?5NiDOL``X=WMtZ zNBom6ZF2o=x_ztSk*|LrY_sc4I%H?NAiODxhN-O<*AL-<`9sPZveZS_O}EAA08*C-e1)PCB&^Od=US`U#)zox)^DPc)Jj z6q)dhsM5mMD&X*uu`IE*)<_C9n3&;`mj?}pq)5pp4RMu6kxh+^O1=~6wW~t6xLG0rUy3)CST_ae-?%4z2KsSdUTD!1<%-Ct0b>A z)uYBSlQ|&_&nQyhYu= z^9|xkLT&nP=FV_FBJg1&_}M` ze_OWh$YgzZXe0MF7~f%jKn#Fr?>qblBgs1oOkkH6#J2quagYx-NU6Y8xxN56OZE>- z2tn!}3F_mt7REkVH6MmGtqOJ#MWmXJ-X^Okk!Np@TzKY>-!7eJ2T)r%kQ zqfX_)kX~X_&H;+xLoQg@hh~?AR(R5tfIb5TG!D)_O;{cja3pCQIJc|aBmUaDPoAe>vcvK>Vpy-RVsFTGT6o{UQ#wrW<1iaz| zp5*|F^8(zLDshWTYw3eLi3A7yyX0}ksjephEvEOKhCGke~hKUwoUudC)3vq~I4scK>*w}>6oqZ8?GLpf|w{MORN z;VKL&e|p3R|e5j`R>G6qd=R_jEm70YMC6LGsWTddIRIz*y~?> zJTN^p{OHNDv?Ttt$rphzcBWdBP~RET^JfkOs1#hFL7@CyJD|XG=Qz@VMT?zm=lQlO z@C6JkIu;$G9PbghHVA)M3B6|5DaM}4{@KJrP4sQ49`aR38MN(8f`4a(`1kP|#)@_0 zJ~2-_w3!2`RR05B6xxos#$DuNx9UmHc?OMlJNg(Rj%@ai&P9{_kU!H}&COr#ajXp) z{^)%>23>5OWC2uGd?}3`R=6%BqG$gYsMj7F?nlY`J0;ew7J?;0(hc)paVD#-naFBf4Z-2`-uRMwV!gp2vCsZV^_2gmKT zLL~X?Aago!YjO_ql6i?k?_XkKdT((>7BGGja?q`P!^$H}4wTh0_fAi>SaQL_)7`V! zHbHOC8Zjq<9>jMvS*md>=UpVoP|&2$4ZlsCXszBDt-GhSMUPAwNY7-DhjY{&3RS49 zzI#=omkzK_(s?PdL=y#6dO}?_OR7iP2dYX83j>=A6HDvz4%otRC%&0I&qm8QjJSOF zX^)IMp2G}xt~eyqpFhl0UWEWzS-YHTGSfjYI==YnYjwW>NdZ$P=kM6a%2xDEm(ttW z^ZwVYo_zRpJdw88=GgaWdid%j*ozqthJK883Xc7Kr$3zRs)NxPf}Z!tu5 zimTk7Rz)0rt$j>QiNkPiM8oh7UAwXGy&ZKNY$BN-YXfUHs!Whn_^MRXKv`9P8e(tE za;w?>OL+OKrvFJx;q9YakcIp!5zpe(2%=U0c0&;o(8`tYKJEEMwK!EjOf5LBZ%pN< z!TnF5bO>bmH77SAaIvcWJZWfLWR$sBmqW=WJZ($4jmI>@j8b6XJMQn9t6 zFEFWLe%Dt%Yhj)7%>4DD&>ti%0_q*!`|EFjAdNsVM)Kw5*s!nU+o2BIOs}tyQn@jU z^<-`Ihn&Vq+|k=EpZP>I3Zg#<2$1X5Cv5eqdD}f%TGBg)e?v^RlzWUl>O8X;S;z8t zdI+C+gl1l$ydH<@^KtL62rq|~tX_!$cVv++hO%m8Qag>|)6abW0F@BcAcM)y1P69E z;Ahik2(-TgzWSmj;YHI`7Gn-9=M9-D_ga{>A-7aw=n}&asYryrhD_O`@Orpr^H#`4 z*3`0yYEEDRJ%*^_)`6KK{r=>!jx4pOII^Tl%k!7`D(1eYM|Rc{4B$Kn7G5rthFbQ? z0jojZZFtvD=;2R?T?WUlxg$Df%93(kpwMtLocNO~+Nf5B7q8*-mz~e-Oe6VKzO}1@u)a zSFht|=M3WmD~+K3?h{2~t@grM-lt2htuLv2q?EQTCd%!}|~JqlzGPxbE7mp)6 zUnhlJxmDe#hZnh2wxle9VXKzS1Tc<0BdD|&{Z4$=%yay!8l`kJhFOI4$; z@=LwyLQKcY2)9<6a-oB|-b!tckST3uI^XFF&K z7RUWRYCj>xawQF(9_8ngW{rEl{2t+8y2qlrtQ2L6Q?tD9Ol=j9dop^<3EWE*guT!f zr?_=BGBiULhbV9d@20&C-Wd5P)(gdIi%EW_S!R8P>!}J2MLrcy4Y$04p|<|&qbum~ zMJDI-go_;EzPx|;yT|A)=C-W6d33}REV#^^GJZU&cQ|3H!Kq1Gb5ST5jl@RUUq|dX znXSwwM5S5U?Rj@9$aU1#-F~H!rwMpxqEe%W{=gbID39GN9^s>==MixdzH;11%4db& zp>U>KKDI7)l3*J|AazvX7Bc9~6>|qzNGlU-eB8}oLQAKb8vEMI`jo#v|Dv6XFkfVm{Ek%nu`L=R zLF|Jh-(J6NbSmk1l)OSDX9!YRupZ-hsu+*SB5F$YGw{n$j}oBM6+|Lr8GBbc++a#= z-da1ag?K)~QER|$ThB)UQ`Whz)bf*J{JuWhKK)E;^Hm9zjkp<&Y+cxx(=g=NQLoLk z6T_N|k~)gH?_+Ow7g-ItQIETM5W1qai!NLSb&5X(Z$o66duFj6DPLBCAS9GFJhIA_ z8)cwx2MI;;Gd=)S$#-W%nW{~C-%a<9gTbb)Yq%VQ8=5q%AWrlpU9Rh{5;>npM8dM* zTPXVhI-TRhHCr?fbY^5r1svXR&OSDWVd1D2_%tDCk}yyo zSV4)0Rra7-K_M+d+_a~_vyFZ46Ft)>_lxXJAJn%*>{IMq_eb`=l6w~jBY zd`hFd=3Jaw{WLHA&wgOn)R!7&mprSlp*t*dR08sT@qvWx`~5<{q=#%EAdVK`T65x$4d`SKQChb zEm;kz>FNIM^-XsPVT-on!o?p~^}T_uK|cGLdR_pzBx_62JDa=Srd@rztt;Z-J^N0* znxTGP7wwwfx6^l5YX{a33rw_H!i4F!3kBa|UZwMt-}kqwanJYPH%%sCWU@6JxlbNZ ze3T@bvVAJ3AVi<%udUSwm7XMR(wZXqg`3-%g*ue`#sYCiQmJ?E1hu*rt5ln-jG^@| zKx_btN3}v2a`;ro+>Do+@_Ws13h=TDnuTSi@{Q+}3utMo8Mujy9~YNq4NptNA^_Vv2eRSW9b!w2Lim(R`p?gp|M8tTb!7CPxa`sPzhvoL1AA`!>qq&~2u1%F zWJ*>VcUUt}3JqDXJRA(!=|9Dq6-loZaHo#pDD?F^RzG2`Xdfm^qTl9Fp5O9@BLNHj z^|42Wjn~DS*medM0n>C_>^pkjMQ!5oll;Euw83i(qo!HjAi0)+8CPOuZ3k_2WUiA8 zyXJ#0#f<}iMkJOcRT$_fbl`tnPB`YbgQnK6A;*-T+{=t2SL#tjMrg9FT6<&g(|Q{43*r| zO$fwA)4mG#>CL#QOC2D4?!Deu>X+4?j(!=YBZ?{{S=l%%vR|n?B(BsRxwEY@GcSs@ z{G?us&-Bavo#iyJ`$Qt9KO*6K~AW(TFK++vR<+>yq?QmRsmpr6>lP3*AH2L zy?)=sK|wR-enF3eFkpIwjnpXqo0trF8T5w?^IIZ&Iw@#0jGd4AV=5J8+AZGj0)fgG ztT>N7LFUoCpWT}yxC6Wy7O}Y8?3C}N6mGK#OawXgR9dkMJEp5UaG>KpLkGPI=$$T| z5{dgNq{j>5m~Xw+lnwzPbb)H-x9nl}vUJt@VO|Lz8AiLG@}8j>WP+{MIy^zVt|m8T zn|73hL~j1=mx|(GJ6zxDggCd>5FrUQDY}gm?^jja{3U`2R{L<5R$EUiZmS^McHxaI z(GM^7!}p!CwK{Gku%~EN5o~1=&Su{)nO=#7X2iaj9B!`m%>D>W&tIW9dMQa6w*-e8 z4bbEb+~nq!+|uOD-1upF2|Fx4_xryLB@A5V&)j^~~|L z5yG6a+&1yvEPtVWIK=x0Le$Xe{*msD!i?s}6_^x8wUKB_d~Qtt`DsoKA$sJUF&fh^ zg~$NbqUbMCqjodEMnafRn9tnrIzo?!%t&?LP z*Y=ah)6CrSuaquK&zbTGlFpDvP80hdtNmslwmzle_BdlNjbi?Ru2*Wy7rplVxShh7 z>FtZDN~TqhC#f=SMT$aSo4&U^$C)HF-q0z!8e<`Nn!2ey2xO%aW4j>KXYl-%Z7r*l zx2-K3dd;yBZz?(O>6~T&W+%Fi`q2<5kl0j`QDX@t3UaEje|$qVYi7Ma_0m5}rsdO- zn=_6B=kNILSjIh#=906fy)nt4^yo?;q5JSxb@6=06M9!m^sGDyh+Bc{$rFrc=YC^5 zZiiL@EiJ}W0ElSoXB5fQc19*$Nt|mYjMnKf)epAPo=y94r`Q?l-|vYof-KE;s;Er^ z`qgEaR|SNnBTI?8tZZdyQ8a>}=e!U^Ow}~x9cD#sLlNJ`rx&SbmmxQwirswHTL83= zo)=#1pD$zXF^IiE>O)l6%yNS9NhORVpXK2#b#!0>K=V=6PvT!tOS)BYml?bxi9B(= zR5#L3odX9_JLJa*bY}#=xfL$sHHx$6sXpyD539Z)v}j@*6YHJoc+M--mT_y7idS%3 zJV=49%7Zqf5qM%CkJ7X)sX(7@}UGeGARP2>r2ByLwO|oS1&@bko=x1FcjG!G=qoa=e!jL50 zj@MVMXUjn(ci~8n@aDAfvH~|dhUsp>wiV$#KoBC_xpEN^?feoE;ryt%IyG5Ouf# zu(*;DwY+<5OuwW%^5{)=*t`MSJw^;i$BPi@TnI{`bB-N4|ZC&sWz+o@B=+lEV6f8ZFZkW2aZgC%#g= zPsV?2Zm#*>c@msJCmXy#${oUQGvbY>fxbe$D+J|i>B)4&)FAih}Hb~&RN_`uh0i^j0bJd9gIU8Y5XAMdpzGWWhnM*e0^JHM|}w-p;v|| z#wsyE@-HvSdU2mIDr=L6I8B>7%GJp0h=*` z>4m>k(b7^9Fw{yaS}E02lfh~E@5Ny7HBB7K?Al~c{qP}?y9sVRjy zwHD1^ToZKlzb`uWAl{D{w@O(SWcA=DV);z=ejLW!Ey@uPyza!}zk8DCvV(%AZ7m_` zdvgRk&Cq&3?Ef^_MGG;`(e?WgF_0dzYa@;R>365Re=XccDVlwf=tIFrG*zKsoLa?- zcCO~8;?s-e=KG8jSEI&Zv&vTWmkrrOmEnp!aSm7=);~u18beTJ52BfZStpnwr@KG2 z`952Uuyx`dG8^^PiI~Q%ap-wDbES@wh^5twAeU#E6k>~n4p(_+w3wU-tN}L!GOVRc zqYbYadMG{5)4V#iMpyiOhKQNJXrz#y35a)xTQhKxCHluK5*2uh+}_C#t2C|EY=1cx zW!tN|TgbT2HI+C8OoJ4b!WC#BaSwOKu1ht_D}Y9^gR*_%_YPalp}{T>4xO_@RdER= z31&vmE^j7DH)Y4tDb~o|OTe@7Cl5Khl6hH@CGzPmyPt+>uvxDg%dZ%`Mz{y6$~%(y z-;`O!J>p^OHqY}LljO(wNgws4OsE$U;CS_`E){R3^NrC^)Y`sR;M_yo>#E8d-UiDw z9W^orW~n@u^cgl@<2|95TqihJlu3jbGBcG876Kw6-h}PuFGY2B$pPa5yE}A;PmD@UhuLu~o00~%c{&MLgMBl`7k zjh9NuFVuVN9QW>@5PDuZDa1O01>HpK86}*U(VNt@#{&unjO#c|DThdXS}|>!BggJq z9k=%qk%3P;azl`Fvw1}kGTzRMXJ9EnH(EERrx$tGt1X_<5B31?L)BzEkTOw7wM>zjq!&1qOMEcJqXD&b!uYz7e(3)8 zxJ@n2ceqpqsFPv&F%><|y+Vq4+bg&fzP@BNVvurwM4?|rf8r;v3@`p2x`=hu$rpOe zi8aw_gVYQ-yxu{Kr>`J#Fwk!#;s^lK`%7+H)qB6kbMu*tA{le+nIcc`<0%p6IZ0z* zm$p<5jVjDQ-6KZGC`q#<xde?=LTB;=0IkNIa8eTcqfIPaKeH zEfTd7Fp<;9OeFb>wwSc2wuEurhhrz;Q*yu66GR7Z2Cr8}S3X zH#-G^zz?w~AB_G?Tbjtt+~<-~`4$Q4WezlQ9^#75sPzF)7LncSroHNZZICm%i5Y5t zFYHFIGc=C3j>uYiKUJ)ye==2AZ{b!p9V7KszvvyM-Wvz?$?$Z!MbT0D!b*i1(w3R< zVzs`ka;=_1!w%7J`y6IurBOuA{SkDJs6L<3GXc0P(K9JrK@pCD`O;*TmMk_H5o3CM znn<)NEOL09vippQbmYnJhCESl0}K{s(=p03Sg3N~zJ+0!zXn{#l_U{=}1w%XDz-*Vw~r`&0}ao4#$MLt1fN7`H;M&6k< zSO9QDn+0Ol8JdQ0okIvxq@4j#k#`87_c~L1<)G@ zrXb3=@0J;_gJbNL(sXGc16_B?w;uOwv$_~!B+4K$@ z4Nx+gqJ9{5s7P0U+t-w?uy~yT= z;Gl1JsSi>AMAl?9kwZI^ZTnO2Gv|%Z-zQ$3pri$KJAm-?qH>$Ywu;1c-bo*fbd8)| z{RsVbV|qT8Mhj;Tj*~cQrRg&cp|5v24(OgOgy89B*Mw&!2F51iZRSx=9*Ffh^wyzet+ro~}Op zF8XH}pT=Xd4?gbr98$OqXzaB}RhfN~f>8^#{n*KLg~;k7u~FqhMGb7O+BfBX<9?3y zT5-Eb(?4gsc)M$R1xvmXW+G=9}wJ`5P^|9o6vwW2=lplFaS9*fHp$1Ctv0QxZusJ9zON+t{S8gc%n#esyu zjOTx_!Bq3196d-YfO*{S8ZCNelf6i@(I+uNC;`Rwy5PF!agQj}$SQgC6;EZVA$EVB zmeib9Dnd*wYa0hXxJ^QE&fiez+=SPW>j?SjhK^G>`SD)O#85?jb(rAixQH@e3HFKb zRQ_nvU{VSzFn-b2N_V)deaARg&i2V{|Lc2+v-bJO!YkUkQi;pAW?$b{Ds(=>CkS>D z8p77TJUH46l;!Sx_NvF8Zu}In%y8o@R8Ik&ApOCI1=b`b~+lEJq_%imqI~3H=E79 zGaWfp=)F%R{SBDP?)hvDt9b~2@KX`KXLV9V1kesH zHvzXD+OxSmeOEQJ`_~WOVfEayM&AM-#77S?g8^HFMmfRVKF0m>qr1EO3MmEc)f$?* zYt!Dt25tnQ+&&;da{9of;d`wkf^&a1RrPCs0y>09b}PKp;TIgs4cS z`+hF|;@98>43`@r_2Z64Qw5Af1HuIT^~#IY)cyP7zi%iYf&X6N{nxg(f4b+!1U>ot zBN#*q+KuN6d)P+_K3Db)T@s%Ihm<#ubI{F#ecZ7@;G`+$jU9OS20>dh_n$o4Mm{j= z90&yq{{v2Y+vM!{%7?lCfhD3*Hky2Zi!09zd4Pp|NQcm~(trpb{Lw*TPy=1Gw}C>q z&p@DM0}zM@Wbt=C56XNG)*S>&>0~2;QNkhEu($aTT-ZSt1eNzjW1OmYyem1y4=6|qZJpYT0 z=Wh+^FENYWSt;sTld;r$5qmp2{k%M$oMrNVkLAO`;i zr@hwHjmv6@+n6-=CB)=%+w2{5TF2=w358*P1bC6mqQJ4Hbt7DW(< z6ZGN_;(jtPtSbwWi1E+(_`xW1AXG>gx-hXE$g_VlD0Rxvk`+Y`@u35OhB!bVevtJa zD2lqU${a{G);}Qq4{HwonhhjXKbS`@K;6Eo>!Q{V_Ofv-rHJ1%6)Rnbv{m&$?XB^G9kXQ()L|K7{`7nm7&1M4^8jiGM8NP1Ao* z8aoKQl=$&~WiQ?Qk;pm!9J#&+D*KYtK7of5?(P73=z-oJR8}HLFjEBx#oZ`eoCjZ#(*Z*Yl|I_+}B@{r=aq&U;ApM7jTI0>b HO$YrS4@q^G diff --git a/YLErpWeb/Controllers/supervise_reportController.cs b/YLErpWeb/Controllers/supervise_reportController.cs index 6177bdd7..56eef48b 100644 --- a/YLErpWeb/Controllers/supervise_reportController.cs +++ b/YLErpWeb/Controllers/supervise_reportController.cs @@ -945,28 +945,34 @@ namespace YLErp.Web.Controllers public JsonResult superviseSACReportQuery(ReportInfo req) { - LogFactory.GetLogger("superviseSACReportQuery").Info($"1"); if (PS.Config.ErpElement.SecuritiesEnvironment) { try { - LogFactory.GetLogger("superviseSACReportQuery").Info($"2"); List filePath = new ReportService(CurUser).Execute(req); - LogFactory.GetLogger("superviseSACReportQuery").Info($"3"); return Json(Return.Success(filePath.Select(O => O.FileTag))); } catch (ServiceException ex) { - LogFactory.GetLogger("superviseSACReportQuery").Info($"4"); - if (ex.Tag is List objs) + var errFilePath = ""; + if (ex.Tag != null && ex.Tag is ExceptionExtensionInfo) { - LogFactory.GetLogger("superviseSACReportQuery").Info($"6"); - string key = Guid.NewGuid().ToString(); - Server.CacheProvider.Set(key, objs, DateTime.Now.AddMinutes(1)); - ex.Tag = key; - LogFactory.GetLogger("superviseSACReportQuery").Info($"7"); + var obj = (ExceptionExtensionInfo)ex.Tag; + + if (obj.Tag.Count > 0) + { + string key = Guid.NewGuid().ToString(); + + Server.CacheProvider.Set(key, obj.Tag, DateTime.Now.AddMinutes(1)); + ex.Tag = key; + } + errFilePath = obj.ErrFilePath; + + } + if (ex.Tag != null) + { + Server.CacheProvider.Set($"File_{ex.Tag}", errFilePath, DateTime.Now.AddMinutes(1)); } - LogFactory.GetLogger("superviseSACReportQuery").Info($"5"); return Json(Return.Fail(ex.Message, ex.Tag)); } catch (Exception ex) @@ -1003,7 +1009,9 @@ namespace YLErp.Web.Controllers public ActionResult superviseErrorInfo(string key) { var sacInfoList = Server.CacheProvider.Get(key) as List; + var path = Server.CacheProvider.Get($"File_{key}") as string; ViewBag.ShowMessage = true; + ViewBag.DownloadPath = path; return View("supervisePreview", sacInfoList); } @@ -1112,6 +1120,7 @@ namespace YLErp.Web.Controllers } [MyAuthorize("监管报告-证券业报送")] + [DisableRequestSizeLimit] public JsonResult UploadSACReportFile(string fileType, DateTime date) { LogFactory.GetLogger("UploadEventReportFile").Info("开始上传:"); @@ -1151,7 +1160,8 @@ namespace YLErp.Web.Controllers Directory.CreateDirectory(absPath); } var name = $"{date.ToString("yyyyMMdd")}{file.FileName}"; - file.SaveAs(Path.Combine(absPath, name)); + var fileName = Path.Combine(absPath, name); + file.SaveAs(fileName); fileInfos.Add(new tempfile() { createDate = date, @@ -1163,7 +1173,7 @@ namespace YLErp.Web.Controllers validStatus = true }); LogFactory.GetLogger("UploadEventReportFile").Info($"文件 {i + 1} 保存成功"); - var fileLength = new FileInfo(Path.Combine(absPath, name)).Length; + var fileLength = new FileInfo(fileName).Length; if (fileType == "报送模板" && Path.GetExtension(name).ToLower() == ".zip") { LogFactory.GetLogger("UploadEventReportFile").Info($"处理报送模板"); @@ -1171,15 +1181,14 @@ namespace YLErp.Web.Controllers { return Json(Return.Fail("上传失败,单次上传模板文件大小不应超过200MB")); } - var path = Path.Combine(absPath, name); - var pathName = Path.GetFileNameWithoutExtension(path); + var pathName = Path.GetFileNameWithoutExtension(fileName); var temp = Path.Combine(absPath, pathName); if (Directory.Exists(temp)) { Directory.Delete(temp, true); } LogFactory.GetLogger("UploadEventReportFile").Info($"解压"); - var outPath = ZipHelper.unZipFile(path, absPath, out string msg); + var outPath = ZipHelper.unZipFile(fileName, absPath, out string msg); if (msg.StartsWith("解压成功")) { LogFactory.GetLogger("UploadEventReportFile").Info($"成功"); @@ -1253,6 +1262,44 @@ namespace YLErp.Web.Controllers return Json(Return.Fail("上传失败")); } + [MyAuthorize("监管报告-证券业报送")] + public JsonResult UploadFile(string fileType) + { + LogFactory.GetLogger("UploadFile").Info("开始上传修改编号附件"); + try + { + var service = new TempFilesService(CurUser); + LogFactory.GetLogger("UploadFile").Info("文件数量:" + Request.Form.Files.Count); + for (var i = 0; i < Request.Form.Files.Count; i++) + { + var file = Request.Form.Files[i]; + if (fileType == "修改编号") + { + using var inputStream = file.OpenReadStream(); + ReportService.EditContractNumber(inputStream); + } + string filePath = $"/App_Docs/Download/Report/{UserId}/{fileType}/{DateTime.Now.ToString("yyyyMMdd")}/"; + string absPath = Server.MapPath(filePath); + LogFactory.GetLogger("UploadFile").Info("保存地址:" + absPath); + if (!Directory.Exists(absPath)) + { + Directory.CreateDirectory(absPath); + } + var name = $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}{file.FileName}"; + var fileName = Path.Combine(absPath, name); + file.SaveAs(fileName); + LogFactory.GetLogger("UploadFile").Info($"文件 {i + 1} 保存成功:{fileName}"); + } + LogFactory.GetLogger("UploadFile").Info($"入库完成;处理完成;"); + return Json(Return.Success("修改成功")); + } + catch (Exception ex) + { + LogFactory.GetLogger("UploadFile").Error(ex); + return Json(Return.Fail("修改失败" + ex.Message)); + } + } + public JsonResult QueryEventReportFile(BaseSearchReq req) { if (string.IsNullOrWhiteSpace(req.sidx)) @@ -1342,7 +1389,7 @@ namespace YLErp.Web.Controllers var sourcePath = Server.MapPath("~/App_Docs"); var sourceFileName = Path.Combine(sourcePath, "导出模板", service.TemplateName); var targetPath = Path.Combine(sourcePath, req.ValueDate.ToString("yyyyMMdd")); - + if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); @@ -1381,5 +1428,34 @@ namespace YLErp.Web.Controllers { return double.TryParse(str, out var v) ? v : null; } + + public ActionResult ExportDetailsV2(string encryptId, string fileTag) + { + var id = DecryptInt(encryptId); + var path = $"~/App_Docs/Download/Report/Output/{CurUser.UserId}/{fileTag}报送文件{DateTime.Now:yyyyMMddHHmmss}.zip"; + var absPath = OtcAppContext.MapPath(path); + new ReportService(CurUser).ExportDetailsV2(id, fileTag, path); + return File(System.IO.File.ReadAllBytes(absPath), "application/zip", Path.GetFileName(path)); + } + + ///