summaryrefslogtreecommitdiff
path: root/backend/Elements.Backend/Services
diff options
context:
space:
mode:
authorPaweł Bernaciak <pawelbernaciak@zohomail.eu>2023-10-25 20:28:48 +0200
committerPaweł Bernaciak <pawelbernaciak@zohomail.eu>2023-10-25 20:34:22 +0200
commit1912feb9cfe51deaedbe3abe9239fd1bcf2b37f8 (patch)
tree8d7f0e448c0ba1e6e4980e8d99b136ca14391b95 /backend/Elements.Backend/Services
parent2e86ace4593d32a2cb1a4be9a758911ff25e4a89 (diff)
Make voting work
Diffstat (limited to 'backend/Elements.Backend/Services')
-rw-r--r--backend/Elements.Backend/Services/FinishVoteService.cs95
-rw-r--r--backend/Elements.Backend/Services/PeriodicService.cs38
2 files changed, 133 insertions, 0 deletions
diff --git a/backend/Elements.Backend/Services/FinishVoteService.cs b/backend/Elements.Backend/Services/FinishVoteService.cs
new file mode 100644
index 0000000..8486036
--- /dev/null
+++ b/backend/Elements.Backend/Services/FinishVoteService.cs
@@ -0,0 +1,95 @@
+using Elements.Data;
+using Elements.Data.Models;
+using Microsoft.EntityFrameworkCore;
+
+namespace Elements.Backend.Services;
+
+public class FinishVoteService
+{
+ private readonly ApplicationDbContext _dbContext;
+ private readonly ILogger<FinishVoteService> _logger;
+
+ public FinishVoteService(ApplicationDbContext dbContext, ILogger<FinishVoteService> logger)
+ {
+ _dbContext = dbContext;
+ _logger = logger;
+ }
+
+ public async Task DoSomethingAsync()
+ {
+ _logger.LogDebug("Starting finalizing votes");
+ List<Suggestion> finishedSuggestions = _dbContext.Suggestions
+ .Include(s => s.Votes)
+ .Where(s => DateTime.UtcNow > s.VotingEnd)
+ .ToList();
+
+ if (finishedSuggestions.Count == 0)
+ return;
+
+ bool finished = false;
+ while (!finished)
+ {
+ Suggestion currentSuggestion = finishedSuggestions.First();
+ int firstElementId = currentSuggestion.FirstElementId;
+ int secondElementId = currentSuggestion.SecondElementId;
+ //Get all suggestions with same recipe as current suggestion
+ List<Suggestion> sameRecipeSuggestions = finishedSuggestions.Where(s =>
+ (s.FirstElementId == firstElementId && s.SecondElementId == secondElementId) ||
+ (s.FirstElementId == secondElementId && s.SecondElementId == firstElementId))
+ .ToList();
+ sameRecipeSuggestions.Sort((s1, s2) => s2.Votes.Count.CompareTo(s1.Votes.Count));
+
+ Suggestion winner;
+ if (sameRecipeSuggestions.Count > 1 &&
+ sameRecipeSuggestions[0].Votes.Count == sameRecipeSuggestions[1].Votes.Count)
+ {
+ List<Suggestion> sameAmountOfVotes = sameRecipeSuggestions
+ .Where(s => s.Votes.Count == sameRecipeSuggestions[0].Votes.Count)
+ .OrderBy(s => s.CreationDate)
+ .ToList();
+
+ winner = sameAmountOfVotes[0];
+ }
+ else
+ {
+ winner = sameRecipeSuggestions[0];
+ }
+
+ Element newElement = new()
+ {
+ CreationDate = winner.CreationDate,
+ UserId = winner.UserId,
+ Name = winner.Name,
+ State = ElementState.HasColor,
+ IconPng = winner.Icon
+ };
+ await _dbContext.Elements.AddAsync(newElement);
+ await _dbContext.SaveChangesAsync();
+
+ await _dbContext.Recipes.AddAsync(new Recipe
+ {
+ FirstElementId = winner.FirstElementId,
+ SecondElementId = winner.SecondElementId,
+ ResultElementId = newElement.Id,
+ });
+
+ //Delete votes
+ foreach (Vote vote in sameRecipeSuggestions.SelectMany(suggestion => suggestion.Votes))
+ _dbContext.Entry(vote).State = EntityState.Deleted;
+
+ //Delete suggestions
+ foreach (Suggestion suggestion in sameRecipeSuggestions)
+ _dbContext.Entry(suggestion).State = EntityState.Deleted;
+
+ await _dbContext.SaveChangesAsync();
+
+ finishedSuggestions = finishedSuggestions
+ .Where(s => !(s.FirstElementId == firstElementId && s.SecondElementId == secondElementId) &&
+ !(s.FirstElementId == secondElementId && s.SecondElementId == firstElementId))
+ .ToList();
+
+ if (finishedSuggestions.Count == 0)
+ finished = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/backend/Elements.Backend/Services/PeriodicService.cs b/backend/Elements.Backend/Services/PeriodicService.cs
new file mode 100644
index 0000000..48cdf2f
--- /dev/null
+++ b/backend/Elements.Backend/Services/PeriodicService.cs
@@ -0,0 +1,38 @@
+namespace Elements.Backend.Services;
+
+class PeriodicService : BackgroundService
+{
+ private readonly TimeSpan _period = TimeSpan.FromMinutes(1);
+ private readonly ILogger<PeriodicService> _logger;
+ private readonly IServiceScopeFactory _factory;
+ public bool IsEnabled { get; set; } = true;
+
+ public PeriodicService(
+ ILogger<PeriodicService> logger,
+ IServiceScopeFactory factory)
+ {
+ _logger = logger;
+ _factory = factory;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ using PeriodicTimer timer = new PeriodicTimer(_period);
+ while (
+ !stoppingToken.IsCancellationRequested &&
+ await timer.WaitForNextTickAsync(stoppingToken))
+ {
+ try
+ {
+ if (!IsEnabled) continue;
+ await using AsyncServiceScope asyncScope = _factory.CreateAsyncScope();
+ FinishVoteService finishVoteService = asyncScope.ServiceProvider.GetRequiredService<FinishVoteService>();
+ await finishVoteService.DoSomethingAsync();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogInformation($"Failed to execute periodic service, Error: {ex.Message}.");
+ }
+ }
+ }
+} \ No newline at end of file