fix:确认书编号生成修复
This commit is contained in:
@@ -38,6 +38,7 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
|
||||
lock (_syncLock)
|
||||
{
|
||||
// 幂等:如果已生成过确认书编号,直接返回
|
||||
var existingForTrade = dbContext.trade_contract_r
|
||||
.Where(r => r.TradeId == trade.id && r.Type == ContractTypeEnum.Trade && r.IsValid)
|
||||
.Select(r => r.ContractCode)
|
||||
@@ -48,114 +49,26 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 通过当天同类交易的 id 排序确定序号(幂等)
|
||||
var tradeDateStart = tradeDate.Date;
|
||||
var sameDayTradesCount = dbContext.trade
|
||||
.Count(t => t.TradeDate >= tradeDateStart
|
||||
&& t.TradeDate < tradeDateStart.AddDays(1)
|
||||
&& t.OpponentRole == trade.OpponentRole
|
||||
&& t.id < trade.id);
|
||||
var sequenceNo = sameDayTradesCount + 1;
|
||||
|
||||
if (isClientTrade)
|
||||
{
|
||||
// 对客交易:GLMS-{clientCode}-{date}-{counter:D2}-{underlyingCode}
|
||||
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 + 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var counterStr = code.Substring(prefixLen, 2);
|
||||
if (int.TryParse(counterStr, out var n) && n > maxNo)
|
||||
{
|
||||
maxNo = n;
|
||||
}
|
||||
}
|
||||
|
||||
var nextNo = maxNo + 1;
|
||||
var contractNo = $"{prefix}{nextNo:D2}-{underlyingCode}";
|
||||
while (existingCodeSet.Contains(contractNo))
|
||||
{
|
||||
nextNo++;
|
||||
contractNo = $"{prefix}{nextNo:D2}-{underlyingCode}";
|
||||
}
|
||||
return contractNo;
|
||||
return $"{prefix}{sequenceNo:D2}-{underlyingCode}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非对客交易:GLMS-{clientCode}-{date}-{letter}-{underlyingCode}
|
||||
// 找当日已有的非对客交易最大字母序号
|
||||
var maxLetter = 0;
|
||||
var prefixLen = prefix.Length;
|
||||
for (var i = 0; i < existingCodes.Count; i++)
|
||||
{
|
||||
var code = existingCodes[i];
|
||||
if (string.IsNullOrEmpty(code) || code.Length <= prefixLen + 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var rest = code.Substring(prefixLen);
|
||||
var dashIdx = rest.IndexOf('-');
|
||||
if (dashIdx > 0)
|
||||
{
|
||||
var letterPart = rest.Substring(0, dashIdx);
|
||||
if (TryParseLettersToNumber(letterPart, out var ln) && ln > maxLetter)
|
||||
{
|
||||
maxLetter = ln;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nextLetter = maxLetter + 1;
|
||||
var contractNo = $"{prefix}{NumberToLetter(nextLetter)}-{underlyingCode}";
|
||||
while (existingCodeSet.Contains(contractNo))
|
||||
{
|
||||
nextLetter++;
|
||||
contractNo = $"{prefix}{NumberToLetter(nextLetter)}-{underlyingCode}";
|
||||
}
|
||||
return contractNo;
|
||||
return $"{prefix}{NumberToLetter(sequenceNo)}-{underlyingCode}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
Reference in New Issue
Block a user