#EQD-5843 国联民生-交易确认书编号规则, 客户编号规则, 以及确认书相关的一些调整:除了上传确认书
This commit is contained in:
@@ -1347,6 +1347,9 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
return Trade.TradeNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成国贸确认书编号
|
||||
/// </summary>
|
||||
private string GenerateGuolianContractNo()
|
||||
{
|
||||
if (_contractType != ContractTypeEnum.Trade)
|
||||
@@ -1355,13 +1358,11 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
}
|
||||
if (Trade.TradeType == "收益互换")
|
||||
{
|
||||
var posi = GetSwapPositions(Trade.id, true).FirstOrDefault(p => p.PositionType > 0);
|
||||
var isLong = posi?.PositionType == (int)PositionTypeFlag.Short ? false : true;
|
||||
|
||||
return "GLMS-" + _client.Number + "-" + Trade.TradeNumber;
|
||||
return GuolianContractNoGenerator.Generate(DbContext, (trade)Trade, _client.Code);
|
||||
}
|
||||
return Trade.TradeNumber;
|
||||
return Trade.TradeNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成国贸确认书编号
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
using YLErp.BLL;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.DBModels.Consts;
|
||||
using YLErp.DBModels.Enums;
|
||||
|
||||
namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 国贸交易确认书编号生成器
|
||||
/// 规则:
|
||||
/// - 对客交易(OpponentRole为"甲方"):GLMS-{对手方代码}-{成交日期(yyyyMMdd)}-{标的代码}-{当日第N笔对客交易(数字递增)},从001开始
|
||||
/// - 非对客交易(OpponentRole为"乙方"):GLMS-{对手方代码}-{成交日期(yyyyMMdd)}-{标的代码}-{当日第N笔非对客交易(字母递增)},从A开始
|
||||
/// </summary>
|
||||
public class GuolianContractNoGenerator
|
||||
{
|
||||
private static readonly object _syncLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 生成国贸交易确认书编号
|
||||
/// </summary>
|
||||
/// <param name="dbContext">数据库上下文</param>
|
||||
/// <param name="trade">交易记录</param>
|
||||
/// <param name="clientCode">客户代码</param>
|
||||
/// <returns>确认书编号</returns>
|
||||
public static string Generate(
|
||||
YLContext dbContext,
|
||||
trade trade,
|
||||
string clientCode)
|
||||
{
|
||||
// 根据trade的OpponentRole判断是否为对客交易
|
||||
var isClientTrade = trade.OpponentRole == "甲方";
|
||||
var underlyingCode = trade.UnderlyingCode ?? "";
|
||||
var tradeDate = trade.TradeDate ?? DateTime.MinValue;
|
||||
var tradeDateStr = tradeDate.ToString("yyyyMMdd");
|
||||
var prefix = $"GLMS-{clientCode}-{tradeDateStr}-{underlyingCode}-";
|
||||
|
||||
lock (_syncLock)
|
||||
{
|
||||
var existingForTrade = dbContext.trade_contract_r
|
||||
.Where(r => r.TradeId == trade.id && r.Type == ContractTypeEnum.Trade && r.IsValid)
|
||||
.Select(r => r.ContractCode)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(existingForTrade))
|
||||
{
|
||||
return existingForTrade;
|
||||
}
|
||||
|
||||
var existingCodes = dbContext.trade_contract_r
|
||||
.Where(d => d.ContractCode.StartsWith(prefix) && d.Type == ContractTypeEnum.Trade && d.IsValid)
|
||||
.Select(d => d.ContractCode)
|
||||
.ToList();
|
||||
|
||||
var existingCodeSet = new HashSet<string>();
|
||||
for (var i = 0; i < existingCodes.Count; i++)
|
||||
{
|
||||
var code = existingCodes[i];
|
||||
if (!string.IsNullOrWhiteSpace(code))
|
||||
{
|
||||
existingCodeSet.Add(code);
|
||||
}
|
||||
}
|
||||
|
||||
if (isClientTrade)
|
||||
{
|
||||
var maxNo = 0;
|
||||
var prefixLen = prefix.Length;
|
||||
for (var i = 0; i < existingCodes.Count; i++)
|
||||
{
|
||||
var code = existingCodes[i];
|
||||
if (string.IsNullOrEmpty(code) || code.Length <= prefixLen)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var suffix = code.Substring(prefixLen);
|
||||
if (int.TryParse(suffix, out var n) && n > maxNo)
|
||||
{
|
||||
maxNo = n;
|
||||
}
|
||||
}
|
||||
|
||||
var nextNo = maxNo + 1;
|
||||
var contractNo = $"{prefix}{nextNo:D3}";
|
||||
while (existingCodeSet.Contains(contractNo))
|
||||
{
|
||||
nextNo++;
|
||||
contractNo = $"{prefix}{nextNo:D3}";
|
||||
}
|
||||
return contractNo;
|
||||
}
|
||||
else
|
||||
{
|
||||
var maxNo = 0;
|
||||
var prefixLen = prefix.Length;
|
||||
for (var i = 0; i < existingCodes.Count; i++)
|
||||
{
|
||||
var code = existingCodes[i];
|
||||
if (string.IsNullOrEmpty(code) || code.Length <= prefixLen)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var suffix = code.Substring(prefixLen);
|
||||
if (!TryParseLettersToNumber(suffix, out var n))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n > maxNo)
|
||||
{
|
||||
maxNo = n;
|
||||
}
|
||||
}
|
||||
|
||||
var nextNo = maxNo + 1;
|
||||
var contractNo = $"{prefix}{NumberToLetter(nextNo)}";
|
||||
while (existingCodeSet.Contains(contractNo))
|
||||
{
|
||||
nextNo++;
|
||||
contractNo = $"{prefix}{NumberToLetter(nextNo)}";
|
||||
}
|
||||
return contractNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryParseLettersToNumber(string letters, out int number)
|
||||
{
|
||||
number = 0;
|
||||
if (string.IsNullOrEmpty(letters))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < letters.Length; i++)
|
||||
{
|
||||
var c = letters[i];
|
||||
if (c >= 'a' && c <= 'z')
|
||||
{
|
||||
c = (char)(c - 32);
|
||||
}
|
||||
else if (c < 'A' || c > 'Z')
|
||||
{
|
||||
number = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
number = (number * 26) + (c - 'A' + 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将数字转换为字母序列(1=A, 2=B, 26=Z, 27=AA, 28=AB...)
|
||||
/// </summary>
|
||||
private static string NumberToLetter(int number)
|
||||
{
|
||||
if (number <= 0)
|
||||
{
|
||||
return "A";
|
||||
}
|
||||
|
||||
string result = "";
|
||||
while (number > 0)
|
||||
{
|
||||
number--; // 调整为从0开始
|
||||
result = (char)('A' + (number % 26)) + result;
|
||||
number /= 26;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user