Elég sok minden ...
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WorkFlowCheck.BL.Services.Interfaces;
|
||||
using WorkFlowCheck.DL;
|
||||
using WorkFlowCheck.DL.Entities;
|
||||
|
||||
namespace WorkFlowCheck.BL.Services
|
||||
{
|
||||
public class NumberGeneratorService : INumberGeneratorService
|
||||
{
|
||||
private readonly DbContext _dbContext;
|
||||
private static readonly Dictionary<int, SemaphoreSlim> _templateLocks = new();
|
||||
|
||||
public NumberGeneratorService(AppDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<string> GenerateNextNumberAsync(int templateId, DateTime? baseDate = null)
|
||||
{
|
||||
var semaphore = GetOrCreateSemaphore(templateId);
|
||||
await semaphore.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
using var transaction = await _dbContext.Database.BeginTransactionAsync();
|
||||
|
||||
var template = await _dbContext.Set<NumberGeneratorTemplate>()
|
||||
.FirstOrDefaultAsync(t => t.Id == templateId);
|
||||
|
||||
if (template == null)
|
||||
throw new InvalidOperationException($"Template with ID {templateId} not found.");
|
||||
|
||||
var now = baseDate ?? DateTime.Now;
|
||||
var (year, month) = GetKeyDateParts(template, now);
|
||||
|
||||
var templateDate = await _dbContext.Set<NumberGeneratorTemplateDate>()
|
||||
.FirstOrDefaultAsync(td => td.NumberGeneratorTemplateId == templateId && td.Year == year && td.Month == month);
|
||||
|
||||
if (templateDate == null)
|
||||
{
|
||||
templateDate = new NumberGeneratorTemplateDate
|
||||
{
|
||||
NumberGeneratorTemplateId = template.Id,
|
||||
Year = year,
|
||||
Month = month,
|
||||
CurrentNumber = 0
|
||||
};
|
||||
_dbContext.Add(templateDate);
|
||||
}
|
||||
|
||||
templateDate.CurrentNumber++;
|
||||
var formatted = templateDate.CurrentNumber.ToString(template.DigitFormat);
|
||||
var dynamicSuffix = BuildDynamicSuffix(template, now);
|
||||
var result = BuildFormattedNumber(template, formatted, dynamicSuffix);
|
||||
|
||||
templateDate.LastGeneratedNumber = result;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _dbContext.Database.RollbackTransactionAsync();
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetSampleAsync(int templateId, DateTime? baseDate = null)
|
||||
{
|
||||
var template = await _dbContext.Set<NumberGeneratorTemplate>()
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(t => t.Id == templateId);
|
||||
|
||||
if (template == null)
|
||||
throw new InvalidOperationException($"Template with ID {templateId} not found.");
|
||||
|
||||
var now = baseDate ?? DateTime.Now;
|
||||
var formatted = 1.ToString(template.DigitFormat);
|
||||
var dynamicSuffix = BuildDynamicSuffix(template, now);
|
||||
|
||||
return BuildFormattedNumber(template, formatted, dynamicSuffix);
|
||||
}
|
||||
|
||||
private SemaphoreSlim GetOrCreateSemaphore(int templateId)
|
||||
{
|
||||
lock (_templateLocks)
|
||||
{
|
||||
if (!_templateLocks.ContainsKey(templateId))
|
||||
_templateLocks[templateId] = new SemaphoreSlim(1, 1);
|
||||
|
||||
return _templateLocks[templateId];
|
||||
}
|
||||
}
|
||||
|
||||
private static (int year, int? month) GetKeyDateParts(NumberGeneratorTemplate template, DateTime date)
|
||||
{
|
||||
int year = date.Year;
|
||||
int? month = template.GenerateType == GenerateType.YearAndMonth ? date.Month : null;
|
||||
return (year, month);
|
||||
}
|
||||
|
||||
private static string BuildDynamicSuffix(NumberGeneratorTemplate template, DateTime date)
|
||||
{
|
||||
return template.GenerateType switch
|
||||
{
|
||||
GenerateType.OnlyYear => date.Year.ToString(),
|
||||
GenerateType.YearAndMonth => $"{date.Year}/{date.Month:D2}",
|
||||
_ => template.Suffix
|
||||
};
|
||||
}
|
||||
|
||||
private static string BuildFormattedNumber(NumberGeneratorTemplate template, string formattedNumber, string dynamicSuffix)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (!string.IsNullOrEmpty(template.Prefix))
|
||||
sb.Append(template.Prefix);
|
||||
|
||||
if (!string.IsNullOrEmpty(template.PrefixSeparator) && !string.IsNullOrEmpty(template.Prefix))
|
||||
sb.Append(template.PrefixSeparator);
|
||||
|
||||
sb.Append(formattedNumber);
|
||||
|
||||
if (!string.IsNullOrEmpty(dynamicSuffix))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(template.SuffixSeparator))
|
||||
sb.Append(template.SuffixSeparator);
|
||||
|
||||
sb.Append(dynamicSuffix);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user