Skip to content

Commit

Permalink
Move the logic for updating quote attachments to QuoteAggregateReposi…
Browse files Browse the repository at this point in the history
…tory for extensibility (#106)

Co-authored-by: Evgeny Polyakov <epo@virtoway.com>
Improvement: Move the logic for updating quote attachments to QuoteAggregateRepository for extensibility
  • Loading branch information
alexeyshibanov and Jounik53 authored Mar 20, 2024
1 parent 75a6a8e commit 98139fa
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface IQuoteAggregateRepository
{
Task<QuoteAggregate> GetById(string id);
Task<IList<QuoteAggregate>> ToQuoteAggregates(IEnumerable<QuoteRequest> quotes);
Task UpdateQuoteAttachmentsAsync(QuoteRequest quote, IList<string> urls);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VirtoCommerce.CoreModule.Core.Currency;
using VirtoCommerce.CoreModule.Core.Tax;
using VirtoCommerce.ExperienceApiModule.Core.Extensions;
using VirtoCommerce.FileExperienceApi.Core.Models;
using VirtoCommerce.FileExperienceApi.Core.Services;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.QuoteModule.Core;
using VirtoCommerce.QuoteModule.Core.Models;
using VirtoCommerce.QuoteModule.Core.Services;
using VirtoCommerce.QuoteModule.ExperienceApi.Extensions;

namespace VirtoCommerce.QuoteModule.ExperienceApi.Aggregates;

Expand All @@ -15,15 +20,21 @@ public class QuoteAggregateRepository : IQuoteAggregateRepository
private readonly IQuoteRequestService _quoteRequestService;
private readonly IQuoteTotalsCalculator _totalsCalculator;
private readonly ICurrencyService _currencyService;
private readonly IFileUploadService _fileUploadService;

private const string _attachmentsUrlPrefix = "/api/files/";
private readonly StringComparer _ignoreCase = StringComparer.OrdinalIgnoreCase;

public QuoteAggregateRepository(
IQuoteRequestService quoteRequestService,
IQuoteTotalsCalculator totalsCalculator,
ICurrencyService currencyService)
ICurrencyService currencyService,
IFileUploadService fileUploadService)
{
_quoteRequestService = quoteRequestService;
_totalsCalculator = totalsCalculator;
_currencyService = currencyService;
_fileUploadService = fileUploadService;
}

public async Task<QuoteAggregate> GetById(string id)
Expand Down Expand Up @@ -53,6 +64,54 @@ public virtual async Task<IList<QuoteAggregate>> ToQuoteAggregates(IEnumerable<Q
return result;
}

public virtual async Task UpdateQuoteAttachmentsAsync(QuoteRequest quote, IList<string> urls)
{
var oldUrls = quote.Attachments.Select(x => x.Url).ToHashSet(_ignoreCase);
var allFiles = await GetFiles(urls, oldUrls);

var filesByUrls = allFiles
.Where(x => x.Scope == ModuleConstants.QuoteAttachmentsScope &&
(x.OwnerIsEmpty() || x.OwnerIs(nameof(QuoteRequest), quote.Id)))
.ToDictionary(x => GetFileUrl(x.Id), _ignoreCase);

var changedFiles = new List<File>();

// Remove attachments
var attachmentsToDelete = quote.Attachments.Where(x => !urls.Contains(x.Url, _ignoreCase)).ToList();

foreach (var attachment in attachmentsToDelete)
{
quote.Attachments.Remove(attachment);

if (filesByUrls.TryGetValue(attachment.Url, out var file))
{
file.OwnerEntityId = null;
file.OwnerEntityType = null;
changedFiles.Add(file);
}
}

// Add attachments
var urlsToAdd = urls.Except(oldUrls, _ignoreCase).ToList();

foreach (var url in urlsToAdd)
{
if (filesByUrls.TryGetValue(url, out var file))
{
quote.Attachments.Add(ConvertToAttachment(file));

file.OwnerEntityId = quote.Id;
file.OwnerEntityType = nameof(QuoteRequest);
changedFiles.Add(file);
}
}

// Update owner entity in files
if (changedFiles.Count != 0)
{
await _fileUploadService.SaveChangesAsync(changedFiles);
}
}

protected virtual QuoteAggregate ToQuoteAggregate(QuoteRequest model, Currency currency)
{
Expand Down Expand Up @@ -121,4 +180,42 @@ protected virtual QuoteTaxDetailAggregate ToQuoteTaxDetailAggregate(TaxDetail mo

return aggregate;
}

protected virtual async Task<IList<File>> GetFiles(IEnumerable<string> newUrls, IEnumerable<string> oldUrls)
{
var ids = newUrls
.Concat(oldUrls)
.Distinct(_ignoreCase)
.Select(GetFileId)
.Where(x => !string.IsNullOrEmpty(x))
.ToList();

var files = await _fileUploadService.GetAsync(ids);

return files;
}

protected virtual QuoteAttachment ConvertToAttachment(File file)
{
var attachment = AbstractTypeFactory<QuoteAttachment>.TryCreateInstance();

attachment.Name = file.Name;
attachment.Url = GetFileUrl(file.Id);
attachment.MimeType = file.ContentType;
attachment.Size = file.Size;

return attachment;
}

protected static string GetFileUrl(string id)
{
return $"{_attachmentsUrlPrefix}{id}";
}

protected static string GetFileId(string url)
{
return url != null && url.StartsWith(_attachmentsUrlPrefix)
? url[_attachmentsUrlPrefix.Length..]
: null;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using VirtoCommerce.FileExperienceApi.Core.Services;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.QuoteModule.Core.Models;
using VirtoCommerce.QuoteModule.Core.Services;
Expand All @@ -14,9 +13,8 @@ public class AddQuoteAttachmentsCommandHandler : UpdateQuoteAttachmentsCommandHa
public AddQuoteAttachmentsCommandHandler(
IQuoteRequestService quoteRequestService,
IQuoteAggregateRepository quoteAggregateRepository,
ISettingsManager settingsManager,
IFileUploadService fileUploadService)
: base(quoteRequestService, quoteAggregateRepository, settingsManager, fileUploadService)
ISettingsManager settingsManager)
: base(quoteRequestService, quoteAggregateRepository, settingsManager)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using VirtoCommerce.FileExperienceApi.Core.Services;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.QuoteModule.Core.Models;
using VirtoCommerce.QuoteModule.Core.Services;
Expand All @@ -14,9 +13,8 @@ public class DeleteQuoteAttachmentsCommandHandler : UpdateQuoteAttachmentsComman
public DeleteQuoteAttachmentsCommandHandler(
IQuoteRequestService quoteRequestService,
IQuoteAggregateRepository quoteAggregateRepository,
ISettingsManager settingsManager,
IFileUploadService fileUploadService)
: base(quoteRequestService, quoteAggregateRepository, settingsManager, fileUploadService)
ISettingsManager settingsManager)
: base(quoteRequestService, quoteAggregateRepository, settingsManager)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
using VirtoCommerce.FileExperienceApi.Core.Services;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.QuoteModule.Core.Models;
using VirtoCommerce.QuoteModule.Core.Services;
Expand All @@ -12,9 +11,8 @@ public class UpdateQuoteAttachmentsCommandHandler : UpdateQuoteAttachmentsComman
public UpdateQuoteAttachmentsCommandHandler(
IQuoteRequestService quoteRequestService,
IQuoteAggregateRepository quoteAggregateRepository,
ISettingsManager settingsManager,
IFileUploadService fileUploadService)
: base(quoteRequestService, quoteAggregateRepository, settingsManager, fileUploadService)
ISettingsManager settingsManager)
: base(quoteRequestService, quoteAggregateRepository, settingsManager)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,126 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VirtoCommerce.FileExperienceApi.Core.Models;
using VirtoCommerce.FileExperienceApi.Core.Services;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.QuoteModule.Core;
using VirtoCommerce.QuoteModule.Core.Models;
using VirtoCommerce.QuoteModule.Core.Services;
using VirtoCommerce.QuoteModule.ExperienceApi.Aggregates;
using VirtoCommerce.QuoteModule.ExperienceApi.Extensions;

namespace VirtoCommerce.QuoteModule.ExperienceApi.Commands;

public abstract class UpdateQuoteAttachmentsCommandHandlerBase<TCommand> : QuoteCommandHandler<TCommand>
where TCommand : QuoteCommand
{
private const string _urlPrefix = "/api/files/";
private readonly IFileUploadService _fileUploadService;
private readonly StringComparer _ignoreCase = StringComparer.OrdinalIgnoreCase;
private readonly IQuoteAggregateRepository _quoteAggregateRepository;

protected UpdateQuoteAttachmentsCommandHandlerBase(
IQuoteRequestService quoteRequestService,
IQuoteAggregateRepository quoteAggregateRepository,
ISettingsManager settingsManager,
IFileUploadService fileUploadService)
ISettingsManager settingsManager)
: base(quoteRequestService, quoteAggregateRepository, settingsManager)
{
_fileUploadService = fileUploadService;
_quoteAggregateRepository = quoteAggregateRepository;
}

protected async Task UpdateAttachmentsAsync(QuoteRequest quote, IList<string> urls)
protected Task UpdateAttachmentsAsync(QuoteRequest quote, IList<string> urls)
{
var oldUrls = quote.Attachments.Select(x => x.Url).ToHashSet(_ignoreCase);
var allFiles = await GetFiles(urls, oldUrls);

var filesByUrls = allFiles
.Where(x =>
x.Scope == ModuleConstants.QuoteAttachmentsScope &&
(x.OwnerIsEmpty() || x.OwnerIs(nameof(QuoteRequest), quote.Id)))
.ToDictionary(x => GetFileUrl(x.Id), _ignoreCase);

var changedFiles = new List<File>();

// Remove attachments
var attachmentsToDelete = quote.Attachments.Where(x => !urls.Contains(x.Url, _ignoreCase)).ToList();

foreach (var attachment in attachmentsToDelete)
{
quote.Attachments.Remove(attachment);

if (filesByUrls.TryGetValue(attachment.Url, out var file))
{
file.OwnerEntityId = null;
file.OwnerEntityType = null;
changedFiles.Add(file);
}
}

// Add attachments
var urlsToAdd = urls.Except(oldUrls, _ignoreCase).ToList();

foreach (var url in urlsToAdd)
{
if (filesByUrls.TryGetValue(url, out var file))
{
quote.Attachments.Add(ConvertToAttachment(file));

file.OwnerEntityId = quote.Id;
file.OwnerEntityType = nameof(QuoteRequest);
changedFiles.Add(file);
}
}

// Update owner entity in files
if (changedFiles.Count != 0)
{
await _fileUploadService.SaveChangesAsync(changedFiles);
}
return _quoteAggregateRepository.UpdateQuoteAttachmentsAsync(quote, urls);
}

protected override void UpdateQuote(QuoteRequest quote, TCommand request)
{
// Empty implementation of obsolete abstract method
}

protected async Task<IList<File>> GetFiles(IEnumerable<string> newUrls, IEnumerable<string> oldUrls)
{
var ids = newUrls
.Concat(oldUrls)
.Distinct(_ignoreCase)
.Select(GetFileId)
.Where(x => !string.IsNullOrEmpty(x))
.ToList();

var files = await _fileUploadService.GetAsync(ids);

return files;
}

protected virtual QuoteAttachment ConvertToAttachment(File file)
{
var attachment = AbstractTypeFactory<QuoteAttachment>.TryCreateInstance();

attachment.Name = file.Name;
attachment.Url = GetFileUrl(file.Id);
attachment.MimeType = file.ContentType;
attachment.Size = file.Size;

return attachment;
}

protected static string GetFileUrl(string id)
{
return $"{_urlPrefix}{id}";
}

protected static string GetFileId(string url)
{
return url != null && url.StartsWith(_urlPrefix)
? url[_urlPrefix.Length..]
: null;
}
}

0 comments on commit 98139fa

Please sign in to comment.