Files
jsmr/JSMR.Infrastructure/Ingestion/EnglishVoiceWorkUpdater.cs

131 lines
5.2 KiB
C#

using JSMR.Application.Common;
using JSMR.Application.Scanning.Contracts;
using JSMR.Application.Scanning.Ports;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.Languages;
using JSMR.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
namespace JSMR.Infrastructure.Ingestion;
public class EnglishVoiceWorkUpdater(AppDbContext dbContext, ILanguageIdentifier languageIdentifier) : IVoiceWorkUpdater
{
public async Task<VoiceWorkUpsertResult[]> UpsertAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken)
{
EnglishVoiceWorkUpsertContext upsertContext = await CreateUpsertContextAsync(ingests, cancellationToken);
foreach (VoiceWorkIngest ingest in ingests)
{
Validate(ingest, upsertContext);
VoiceWorkUpsertResult result = upsertContext.Results[ingest.ProductId];
if (upsertContext.VoiceWorks.TryGetValue(ingest.ProductId, out VoiceWork? voiceWork))
{
result.VoiceWorkId = upsertContext.VoiceWorks[ingest.ProductId].VoiceWorkId;
}
if (result.Issues.Count > 0)
{
result.Status = VoiceWorkUpsertStatus.Skipped;
continue;
}
result.Status = UpsertEnglishVoiceWork(ingest, upsertContext);
}
await dbContext.SaveChangesAsync(cancellationToken);
return [.. upsertContext.Results.Select(x => x.Value)];
}
private async Task<EnglishVoiceWorkUpsertContext> CreateUpsertContextAsync(IReadOnlyCollection<VoiceWorkIngest> ingests, CancellationToken cancellationToken)
{
string[] makerIds = [.. ingests.Select(i => i.MakerId).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()];
string[] productIds = [.. ingests.Select(i => i.ProductId).Distinct()];
EnglishVoiceWorkUpsertContext upsertContext = new(
Circles: await dbContext.Circles
.Where(c => makerIds.Contains(c.MakerId))
.ToDictionaryAsync(c => c.MakerId, cancellationToken),
VoiceWorks: await dbContext.VoiceWorks
.Where(v => productIds.Contains(v.ProductId))
.Include(v => v.EnglishVoiceWorks)
.Include(v => v.Localizations)
.ToDictionaryAsync(v => v.ProductId, cancellationToken),
Results: productIds.ToDictionary(
productId => productId,
productId => new VoiceWorkUpsertResult()
)
);
return upsertContext;
}
private void Validate(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext)
{
VoiceWorkUpsertResult result = upsertContext.Results[ingest.ProductId];
bool isTitleEnglish = languageIdentifier.GetLanguage(ingest.Title) == Language.English;
bool isDescriptionEnglish = !string.IsNullOrWhiteSpace(ingest.Description) && languageIdentifier.GetLanguage(ingest.Description) == Language.English;
if (!isTitleEnglish && !isDescriptionEnglish)
{
string message = $"Product title and/or description is not in English";
result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Information));
return;
}
if (upsertContext.Circles.ContainsKey(ingest.MakerId) == false)
{
string message = $"Unable to find circle for maker id: {ingest.MakerId}";
result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error));
return;
}
if (upsertContext.VoiceWorks.ContainsKey(ingest.ProductId) == false)
{
string message = $"Unable to find voice work for product id: {ingest.ProductId}";
result.Issues.Add(new(message, VoiceWorkUpsertIssueSeverity.Error));
}
}
private VoiceWorkUpsertStatus UpsertEnglishVoiceWork(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext)
{
EnglishVoiceWork englishVoiceWork = GetOrAddEnglishVoiceWork(ingest, upsertContext);
englishVoiceWork.ProductName = ingest.Title;
englishVoiceWork.Description = ingest.Description;
englishVoiceWork.IsValid = true;
switch (dbContext.Entry(englishVoiceWork).State)
{
case EntityState.Added:
return VoiceWorkUpsertStatus.Inserted;
case EntityState.Modified:
return VoiceWorkUpsertStatus.Updated;
default:
return VoiceWorkUpsertStatus.Unchanged;
}
}
private EnglishVoiceWork GetOrAddEnglishVoiceWork(VoiceWorkIngest ingest, EnglishVoiceWorkUpsertContext upsertContext)
{
VoiceWork voiceWork = upsertContext.VoiceWorks[ingest.ProductId];
EnglishVoiceWork? englishVoiceWork = voiceWork.EnglishVoiceWorks.FirstOrDefault();
if (englishVoiceWork is null)
{
englishVoiceWork = new EnglishVoiceWork
{
VoiceWork = voiceWork,
ProductName = string.Empty,
Description = string.Empty
};
dbContext.EnglishVoiceWorks.Add(englishVoiceWork);
//upsertContext.VoiceWorks[ingest.ProductId] = voiceWork;
}
return englishVoiceWork;
}
}