Merge branch 'glms/feature/1.4.2' into glms/feature/dotnumber
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
using YLErp.Configuration;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.DBModels.Enums;
|
||||
using YLErp.Modules.TradeModule.DocGenerateModule;
|
||||
|
||||
namespace YLErp.UnitTestProject.Modules.TradeModule.DocGenerateModule
|
||||
{
|
||||
[TestClass]
|
||||
public class GuolianSwapConfirmBookScopeTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void IsPreApprovalTrade_AllAllowedStatuses_ReturnsTrue()
|
||||
{
|
||||
var statuses = new[]
|
||||
{
|
||||
ConsTrade.新增待确认,
|
||||
ConsTrade.修改待确认,
|
||||
ConsTrade.审批中
|
||||
};
|
||||
|
||||
foreach (var status in statuses)
|
||||
{
|
||||
var trade = CreateTrade(status);
|
||||
|
||||
Assert.IsTrue(GuolianSwapConfirmBookScope.IsPreApprovalTrade(trade, CompanyEnum.国联), status);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsPreApprovalTrade_NonGuolianSwapOrInvalidTrade_ReturnsFalse()
|
||||
{
|
||||
var confirmedSwap = CreateTrade(ConsTrade.确认成交);
|
||||
var optionTrade = CreateTrade(ConsTrade.审批中, "香草期权");
|
||||
var invalidSwap = CreateTrade(ConsTrade.审批中);
|
||||
invalidSwap.ValidState = ConsGlobal.InValid;
|
||||
|
||||
Assert.IsFalse(GuolianSwapConfirmBookScope.IsPreApprovalTrade(confirmedSwap, CompanyEnum.国联));
|
||||
Assert.IsFalse(GuolianSwapConfirmBookScope.IsPreApprovalTrade(optionTrade, CompanyEnum.国联));
|
||||
Assert.IsFalse(GuolianSwapConfirmBookScope.IsPreApprovalTrade(CreateTrade(ConsTrade.审批中), CompanyEnum.国泰君安));
|
||||
Assert.IsFalse(GuolianSwapConfirmBookScope.IsPreApprovalTrade(invalidSwap, CompanyEnum.国联));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OtherActiveReferencePredicate_OnlyMatchesOtherActiveTrade()
|
||||
{
|
||||
const string contractCode = "GLMS-TEST-20260728-FICC-04-000001";
|
||||
var predicate = GuolianSwapConfirmBookCleanupService
|
||||
.BuildOtherActiveReferencePredicate(contractCode, 4)
|
||||
.Compile();
|
||||
|
||||
Assert.IsFalse(predicate(CreateRelation(4, contractCode, ContractTypeEnum.Trade, true)));
|
||||
Assert.IsTrue(predicate(CreateRelation(7, contractCode, ContractTypeEnum.Trade, true)));
|
||||
Assert.IsFalse(predicate(CreateRelation(7, contractCode, ContractTypeEnum.Trade, false)));
|
||||
Assert.IsFalse(predicate(CreateRelation(7, "OTHER", ContractTypeEnum.Trade, true)));
|
||||
Assert.IsFalse(predicate(CreateRelation(7, contractCode, ContractTypeEnum.Clearing, true)));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TradeConfirmationRelationPredicate_MatchesActiveAndInactiveRelations()
|
||||
{
|
||||
const string contractCode = "GLMS-TEST-20260728-FICC-04-000001";
|
||||
var predicate = GuolianSwapConfirmBookCleanupService
|
||||
.BuildTradeConfirmationRelationPredicate(4)
|
||||
.Compile();
|
||||
|
||||
Assert.IsTrue(predicate(CreateRelation(4, contractCode, ContractTypeEnum.Trade, true)));
|
||||
Assert.IsTrue(predicate(CreateRelation(4, contractCode, ContractTypeEnum.Trade, false)));
|
||||
Assert.IsFalse(predicate(CreateRelation(7, contractCode, ContractTypeEnum.Trade, true)));
|
||||
Assert.IsFalse(predicate(CreateRelation(4, contractCode, ContractTypeEnum.Clearing, true)));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ActiveOaResultPredicate_OnlyMatchesRejectedTradeActiveResult()
|
||||
{
|
||||
var predicate = GuolianSwapConfirmBookCleanupService
|
||||
.BuildActiveOaResultPredicate(4)
|
||||
.Compile();
|
||||
|
||||
Assert.IsTrue(predicate(new trade_contract_oa_result { trade_id = 4, is_valid = true }));
|
||||
Assert.IsFalse(predicate(new trade_contract_oa_result { trade_id = 4, is_valid = false }));
|
||||
Assert.IsFalse(predicate(new trade_contract_oa_result { trade_id = 7, is_valid = true }));
|
||||
}
|
||||
|
||||
private static trade CreateTrade(string status, string tradeType = "收益互换")
|
||||
{
|
||||
return new trade
|
||||
{
|
||||
TradeType = tradeType,
|
||||
TradeStatus = status,
|
||||
ValidState = ConsGlobal.Valid
|
||||
};
|
||||
}
|
||||
|
||||
private static trade_contract_r CreateRelation(int tradeId, string contractCode, string type, bool isValid)
|
||||
{
|
||||
return new trade_contract_r
|
||||
{
|
||||
TradeId = tradeId,
|
||||
ContractCode = contractCode,
|
||||
Type = type,
|
||||
IsValid = isValid
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -647,8 +647,15 @@ namespace YLErp.Modules.SwapModule
|
||||
}
|
||||
if (changeConfirmStatus)
|
||||
{
|
||||
//删除交易确认书 TODO
|
||||
new TradeDocumentDataService(this).DeleteBooksAfterEditTrade(dbTrade);
|
||||
if (GuolianSwapConfirmBookScope.IsPreApprovalTrade(dbTrade))
|
||||
{
|
||||
new GuolianSwapConfirmBookCleanupService(this).InvalidateAfterEdit(dbTrade);
|
||||
}
|
||||
else
|
||||
{
|
||||
//删除交易确认书 TODO
|
||||
new TradeDocumentDataService(this).DeleteBooksAfterEditTrade(dbTrade);
|
||||
}
|
||||
}
|
||||
int eventType = isAddNew ? (int)SwapEventTypeEnum.新增交易 : (int)SwapEventTypeEnum.修改交易;
|
||||
new SwapEventService(UserInfo).AddSwapEventDate(dbTrade.TradeDate.Value, dbTrade.id, eventType, "", 0, true, "", true);
|
||||
|
||||
@@ -226,9 +226,10 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
return true;
|
||||
}
|
||||
|
||||
// 过滤掉待确认和审批中的交易,这些状态不允许生成确认书
|
||||
// 仅国联收益互换允许在审批前生成确认书,其他交易保持原状态限制。
|
||||
var invalidStatusList = new List<string> { ConsTrade.新增待确认, ConsTrade.修改待确认, ConsTrade.审批中 };
|
||||
var invalidTrades = trades.Where(t => invalidStatusList.Contains(t.TradeStatus)).ToList();
|
||||
var invalidTrades = trades.Where(t => invalidStatusList.Contains(t.TradeStatus)
|
||||
&& !GuolianSwapConfirmBookScope.IsPreApprovalTrade(t)).ToList();
|
||||
if (invalidTrades.Any())
|
||||
{
|
||||
error.AddRange(invalidTrades.Select(t => $"交易 {t.TradeNumber} 状态为【{t.TradeStatus}】,不能生成确认书"));
|
||||
@@ -237,6 +238,20 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
logger.Info($"[GJGenerateConfirmBook] 过滤掉 {invalidTrades.Count} 笔待确认/审批中交易");
|
||||
}
|
||||
|
||||
var preApprovalTrades = trades.Where(GuolianSwapConfirmBookScope.IsPreApprovalTrade).ToList();
|
||||
foreach (var trade in preApprovalTrades)
|
||||
{
|
||||
var validationErrors = new GuolianSwapConfirmBookValidationService(this).Validate(trade);
|
||||
if (!validationErrors.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
error.Add($"交易 {trade.TradeNumber} 无法生成确认书:{string.Join(";", validationErrors)}");
|
||||
tradeIds = tradeIds.Where(id => id != trade.id).ToList();
|
||||
trades = trades.Where(item => item.id != trade.id).ToList();
|
||||
}
|
||||
|
||||
if (!trades.Any())
|
||||
{
|
||||
logger.Info("[GJGenerateConfirmBook] 过滤后无有效交易可生成确认书");
|
||||
|
||||
@@ -7,6 +7,7 @@ using YLErp.Model.Enum;
|
||||
using YLErp.Modules.ClientModule;
|
||||
using YLErp.Modules.SwapModule;
|
||||
using YLErp.Modules.TradeDalModule;
|
||||
using YLErp.Modules.TradeModule.DocGenerateModule;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.DealModule
|
||||
{
|
||||
@@ -295,6 +296,7 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
/// </summary>
|
||||
private TradeOpenResult TradeReject(TradeOpenReqModel req, trade td)
|
||||
{
|
||||
var isGuolianPreApprovalTrade = GuolianSwapConfirmBookScope.IsPreApprovalTrade(td);
|
||||
var oldOrderId = td.ProcessOrderId;
|
||||
req.comments = FormatCommentsWithRole(oldOrderId, req.comments);
|
||||
td.ProcessOrderId = Convert.ToInt32(PStatusEnum.reject);
|
||||
@@ -367,6 +369,11 @@ namespace YLErp.Modules.TradeModule.DealModule
|
||||
var tcDetails = DbContext.trade_cash_detail.Where(O => O.TradeCashId == tcId);
|
||||
DbContext.trade_cash_detail.RemoveRange(tcDetails);
|
||||
|
||||
if (isGuolianPreApprovalTrade)
|
||||
{
|
||||
new GuolianSwapConfirmBookCleanupService(this).CleanRejectedPreApprovalTrade(td);
|
||||
}
|
||||
|
||||
DbContext.SaveChanges();
|
||||
|
||||
return new TradeOpenResult(td) { RetCode = TradeOpenRetCode.Success };
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
throw new ServiceException("没有已确认的记录信息!");
|
||||
}
|
||||
var tradeDic = allTrades.Where(O =>
|
||||
statusList.Contains(O.TradeStatus)
|
||||
(statusList.Contains(O.TradeStatus) || GuolianSwapConfirmBookScope.IsPreApprovalTrade(O))
|
||||
&& O.ClientId != 0
|
||||
&& O.ParentTradeId == 0)
|
||||
.ToDictionary(n => n.id, n => new trade_contract_group { trade = n });
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
using System.Linq.Expressions;
|
||||
using YLErp.Configuration;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.DBModels.Enums;
|
||||
using YLErp.Model;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 国联收益互换审批前生成确认书的范围与资料校验。
|
||||
/// </summary>
|
||||
public static class GuolianSwapConfirmBookScope
|
||||
{
|
||||
private static readonly HashSet<string> PreApprovalStatuses = new()
|
||||
{
|
||||
ConsTrade.新增待确认,
|
||||
ConsTrade.修改待确认,
|
||||
ConsTrade.审批中
|
||||
};
|
||||
|
||||
public static bool IsPreApprovalTrade(trade trade)
|
||||
{
|
||||
return IsPreApprovalTrade(trade, PS.Config.Company);
|
||||
}
|
||||
|
||||
public static bool IsPreApprovalTrade(trade trade, CompanyEnum company)
|
||||
{
|
||||
return IsGuolianSwap(trade, company)
|
||||
&& trade.ValidState != ConsGlobal.InValid
|
||||
&& IsPreApprovalStatus(trade.TradeStatus);
|
||||
}
|
||||
|
||||
public static bool IsGuolianSwap(trade trade)
|
||||
{
|
||||
return IsGuolianSwap(trade, PS.Config.Company);
|
||||
}
|
||||
|
||||
public static bool IsGuolianSwap(trade trade, CompanyEnum company)
|
||||
{
|
||||
return company == CompanyEnum.国联 && trade.TradeType == "收益互换";
|
||||
}
|
||||
|
||||
public static bool IsPreApprovalStatus(string tradeStatus)
|
||||
{
|
||||
return PreApprovalStatuses.Contains(tradeStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理国联收益互换审批前生成的确认书,不复用按合同编号批量清理的通用逻辑。
|
||||
/// </summary>
|
||||
public class GuolianSwapConfirmBookCleanupService : YLBaseService
|
||||
{
|
||||
public GuolianSwapConfirmBookCleanupService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
}
|
||||
|
||||
public void InvalidateAfterEdit(trade trade)
|
||||
{
|
||||
if (!GuolianSwapConfirmBookScope.IsGuolianSwap(trade)
|
||||
|| !GuolianSwapConfirmBookScope.IsPreApprovalStatus(trade.TradeStatus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InvalidateRelations(trade.id);
|
||||
}
|
||||
|
||||
public void CleanRejectedPreApprovalTrade(trade trade)
|
||||
{
|
||||
if (!GuolianSwapConfirmBookScope.IsGuolianSwap(trade))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalConfig.SealHandler.RemoveQueue(trade.id);
|
||||
InvalidateOaResults(trade.id);
|
||||
var contractCodes = InvalidateRelations(trade.id);
|
||||
foreach (var contractCode in contractCodes)
|
||||
{
|
||||
var hasActiveReference = DbContext.trade_contract_r.Any(
|
||||
BuildOtherActiveReferencePredicate(contractCode, trade.id));
|
||||
if (!hasActiveReference)
|
||||
{
|
||||
var documents = DbContext.trade_contract_document.Where(x => x.Code == contractCode
|
||||
&& x.Type == ContractTypeEnum.Trade);
|
||||
DbContext.trade_contract_document.RemoveRange(documents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Expression<Func<trade_contract_r, bool>> BuildOtherActiveReferencePredicate(
|
||||
string contractCode,
|
||||
int rejectedTradeId)
|
||||
{
|
||||
return relation => relation.ContractCode == contractCode
|
||||
&& relation.Type == ContractTypeEnum.Trade
|
||||
&& relation.IsValid
|
||||
&& relation.TradeId != rejectedTradeId;
|
||||
}
|
||||
|
||||
public static Expression<Func<trade_contract_r, bool>> BuildTradeConfirmationRelationPredicate(
|
||||
int tradeId)
|
||||
{
|
||||
return relation => relation.TradeId == tradeId
|
||||
&& relation.Type == ContractTypeEnum.Trade;
|
||||
}
|
||||
|
||||
public static Expression<Func<trade_contract_oa_result, bool>> BuildActiveOaResultPredicate(
|
||||
int tradeId)
|
||||
{
|
||||
return result => result.trade_id == tradeId && result.is_valid;
|
||||
}
|
||||
|
||||
private void InvalidateOaResults(int tradeId)
|
||||
{
|
||||
var oaResults = DbContext.tradeContractOaResult
|
||||
.Where(BuildActiveOaResultPredicate(tradeId))
|
||||
.ToList();
|
||||
oaResults.ForEach(x => x.is_valid = false);
|
||||
}
|
||||
|
||||
private List<string> InvalidateRelations(int tradeId)
|
||||
{
|
||||
var relations = DbContext.trade_contract_r
|
||||
.Where(BuildTradeConfirmationRelationPredicate(tradeId))
|
||||
.ToList();
|
||||
relations.Where(x => x.IsValid).ToList().ForEach(x => x.IsValid = false);
|
||||
return relations.Select(x => x.ContractCode).Distinct().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅校验模板无法正常生成或选择时必需的交易数据。
|
||||
/// </summary>
|
||||
public class GuolianSwapConfirmBookValidationService : YLBaseService
|
||||
{
|
||||
public GuolianSwapConfirmBookValidationService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
}
|
||||
|
||||
public List<string> Validate(trade trade)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
var client = DataCacheProvider.GetClientDataSource().GetData(trade.ClientId);
|
||||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
|
||||
|
||||
if (client == null)
|
||||
{
|
||||
errors.Add("客户信息不存在");
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (underlying == null)
|
||||
{
|
||||
errors.Add("标的信息不存在");
|
||||
}
|
||||
|
||||
ValidateInitialPosition(trade, errors);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private void ValidateInitialPosition(trade trade, List<string> errors)
|
||||
{
|
||||
var position = DbContext.swap_position.FirstOrDefault(x => x.SwapTradeId == trade.id
|
||||
&& x.IsInitial
|
||||
&& !x.Invalid
|
||||
&& (x.PositionType == (int)PositionTypeFlag.Long || x.PositionType == (int)PositionTypeFlag.Short));
|
||||
|
||||
if (position == null)
|
||||
{
|
||||
errors.Add("缺少初始标的持仓");
|
||||
return;
|
||||
}
|
||||
|
||||
if (position.PosiDirection != (int)SwapDirectionEnum.支付
|
||||
&& position.PosiDirection != (int)SwapDirectionEnum.收取)
|
||||
{
|
||||
errors.Add("初始标的持仓收支方向无效");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(position.UnderlyingCode))
|
||||
{
|
||||
errors.Add("初始标的持仓缺少标的代码");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using YLErp.Events;
|
||||
|
||||
@@ -27,18 +28,44 @@ namespace YLErp
|
||||
|
||||
static HtmlUtil()
|
||||
{
|
||||
//获取bin目录中YLErp开头的文件最后修改日期作为JS和CSS文件版本
|
||||
//获取bin目录中YLErp开头的文件最后修改日期作为后端构建版本
|
||||
var binDir = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
var files = binDir.GetFiles("YLErp*");
|
||||
BinFileVersion = files.Any() ? files.Max(n => n.LastWriteTime) : DateTime.MinValue;
|
||||
JsVersion = BinFileVersion.ToString("yyMMddHHmmss");
|
||||
|
||||
//JsVersion(浏览器 ?v= 缓存戳)必须同时反映【后端 DLL】和【前端脚本】的变更:
|
||||
//历史上只取 DLL mtime,导致纯前端改动(改 wwwroot/Scripts 而不重编 DLL)时
|
||||
//缓存戳不变、浏览器仍加载旧版——即"发布了但不更新"(见 ?otcdebug=1 排查时的症状)。
|
||||
//现纳入 wwwroot/Scripts(业务脚本)+ wwwroot/Statics/bundles(打包产物)的 mtime 取 max。
|
||||
//wwwroot 定位用 Directory.GetCurrentDirectory()(与 StaticUrlMiddleware 一致,
|
||||
//开发时=项目根、部署时=publish 目录),目录不存在则回退到仅 DLL mtime。
|
||||
var versionClock = BinFileVersion;
|
||||
var webRoot = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
|
||||
foreach (var sub in new[] { "Scripts", Path.Combine("Statics", "bundles") })
|
||||
{
|
||||
var dir = Path.Combine(webRoot, sub);
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
foreach (var f in new DirectoryInfo(dir).GetFiles("*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (f.LastWriteTime > versionClock) versionClock = f.LastWriteTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
JsVersion = versionClock.ToString("yyMMddHHmmss");
|
||||
|
||||
//从 AssemblyInformationalVersion 读取 git sha(SDK 编译时已嵌入,零额外依赖)
|
||||
var infoVer = typeof(HtmlUtil).Assembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
//格式 "1.0.0+<sha>",取 + 之后部分;无则回退到完整字符串
|
||||
GitCommit = string.IsNullOrEmpty(infoVer) ? "unknown"
|
||||
: (infoVer.Contains('+') ? infoVer.Substring(infoVer.LastIndexOf('+') + 1) : infoVer);
|
||||
//格式 "1.0.0+<sha>",取 + 之后部分;无 +(如固定版本号 1.0.0)则回退读 .git/HEAD
|
||||
if (!string.IsNullOrEmpty(infoVer) && infoVer.Contains('+'))
|
||||
{
|
||||
GitCommit = infoVer.Substring(infoVer.LastIndexOf('+') + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GitCommit = ReadGitCommitFromRepo() ?? (infoVer ?? "unknown");
|
||||
}
|
||||
|
||||
EventBus.Subscribe<DataCacheUpdateEvent>(t =>
|
||||
{
|
||||
@@ -46,6 +73,51 @@ namespace YLErp
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 .git/HEAD 读取当前 commit 短 sha,作为 AssemblyInformationalVersion 无 sha 时的回退。
|
||||
/// 找不到 .git 或读取失败返回 null(不影响启动)。
|
||||
/// </summary>
|
||||
static string ReadGitCommitFromRepo()
|
||||
{
|
||||
try
|
||||
{
|
||||
//从 ContentRoot 向上找 .git 目录(开发时在项目根/仓库根)
|
||||
var dir = new DirectoryInfo(Directory.GetCurrentDirectory());
|
||||
while (dir != null)
|
||||
{
|
||||
var gitDir = Path.Combine(dir.FullName, ".git");
|
||||
if (Directory.Exists(gitDir))
|
||||
{
|
||||
return ParseGitHead(gitDir);
|
||||
}
|
||||
dir = dir.Parent;
|
||||
}
|
||||
}
|
||||
catch { /* 读取失败不影响启动,返回 null */ }
|
||||
return null;
|
||||
}
|
||||
|
||||
static string ParseGitHead(string gitDir)
|
||||
{
|
||||
var headFile = Path.Combine(gitDir, "HEAD");
|
||||
if (!File.Exists(headFile)) return null;
|
||||
var head = File.ReadAllText(headFile).Trim();
|
||||
//HEAD 格式:"ref: refs/heads/xxx" 或 detached 时的直接 sha
|
||||
if (head.StartsWith("ref: "))
|
||||
{
|
||||
var refPath = Path.Combine(gitDir, head.Substring(5).Replace('/', Path.DirectorySeparatorChar));
|
||||
if (File.Exists(refPath))
|
||||
{
|
||||
return File.ReadAllText(refPath).Trim().Substring(0, 12);
|
||||
}
|
||||
}
|
||||
else if (head.Length >= 12)
|
||||
{
|
||||
return head.Substring(0, 12);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取基础数据JS连接
|
||||
/// </summary>
|
||||
|
||||
@@ -926,9 +926,10 @@ function showToolName(cellValue, options, rowObject) {
|
||||
var html = showDownload(cellValue, options, rowObject);
|
||||
|
||||
var title = page.IsAutoSealAndUploadFiles && page.IsAutoSealAfterGeneratedBook ? "生成并用印" : "生成确认书";
|
||||
// 待确认和审批中的交易不允许生成确认书
|
||||
// 仅国联收益互换允许在审批前生成确认书,其他交易保持原限制。
|
||||
var isUnconfirmed = rowObject.TradeStatus === "新增待确认" || rowObject.TradeStatus === "修改待确认" || rowObject.TradeStatus === "审批中";
|
||||
var canGenerate = page.canGenerate == true && !isUnconfirmed ? "" : "disabled";
|
||||
var isGuolianSwap = page.isGuoLian === true && rowObject.TradeType === "收益互换";
|
||||
var canGenerate = page.canGenerate == true && (!isUnconfirmed || isGuolianSwap) ? "" : "disabled";
|
||||
var isWait = (rowObject.MetaDic.SealResult == "用印等待中");
|
||||
html += "<input type=\"button\" class='wentiEdit' title='{2}' onclick=\"gJGenerateConfirmBook({0},{3},{1})\" value='{2}' {4}/>".template(rowObject.id, rowObject.MetaDic.HasGeneratedConfirmBook == "True", title, isWait, canGenerate);
|
||||
if (rowObject.MetaDic.ContractDocUrl && page.canSendEmail == true) {
|
||||
|
||||
Reference in New Issue
Block a user