158 lines
5.6 KiB
C#
158 lines
5.6 KiB
C#
using Nop.Core;
|
|
using Nop.Core.Caching;
|
|
using Nop.Core.Domain.Polls;
|
|
using Nop.Services.Polls;
|
|
using Nop.Web.Infrastructure.Cache;
|
|
using Nop.Web.Models.Polls;
|
|
|
|
namespace Nop.Web.Factories;
|
|
|
|
/// <summary>
|
|
/// Represents the poll model factory
|
|
/// </summary>
|
|
public partial class PollModelFactory : IPollModelFactory
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly IPollService _pollService;
|
|
protected readonly IStaticCacheManager _staticCacheManager;
|
|
protected readonly IStoreContext _storeContext;
|
|
protected readonly IWorkContext _workContext;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public PollModelFactory(IPollService pollService,
|
|
IStaticCacheManager staticCacheManager,
|
|
IStoreContext storeContext,
|
|
IWorkContext workContext)
|
|
{
|
|
_pollService = pollService;
|
|
_staticCacheManager = staticCacheManager;
|
|
_storeContext = storeContext;
|
|
_workContext = workContext;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// Prepare the poll model
|
|
/// </summary>
|
|
/// <param name="poll">Poll</param>
|
|
/// <param name="setAlreadyVotedProperty">Whether to load a value indicating that customer already voted for this poll</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the poll model
|
|
/// </returns>
|
|
public virtual async Task<PollModel> PreparePollModelAsync(Poll poll, bool setAlreadyVotedProperty)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(poll);
|
|
|
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
|
|
|
var model = new PollModel
|
|
{
|
|
Id = poll.Id,
|
|
AlreadyVoted = setAlreadyVotedProperty && await _pollService.AlreadyVotedAsync(poll.Id, customer.Id),
|
|
Name = poll.Name
|
|
};
|
|
var answers = await _pollService.GetPollAnswerByPollAsync(poll.Id);
|
|
|
|
foreach (var answer in answers)
|
|
model.TotalVotes += answer.NumberOfVotes;
|
|
foreach (var pa in answers)
|
|
{
|
|
model.Answers.Add(new PollAnswerModel
|
|
{
|
|
Id = pa.Id,
|
|
Name = pa.Name,
|
|
NumberOfVotes = pa.NumberOfVotes,
|
|
PercentOfTotalVotes = model.TotalVotes > 0 ? ((Convert.ToDouble(pa.NumberOfVotes) / Convert.ToDouble(model.TotalVotes)) * Convert.ToDouble(100)) : 0,
|
|
});
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the poll model by poll system keyword
|
|
/// </summary>
|
|
/// <param name="systemKeyword">Poll system keyword</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the poll model
|
|
/// </returns>
|
|
public virtual async Task<PollModel> PreparePollModelBySystemNameAsync(string systemKeyword)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(systemKeyword))
|
|
return null;
|
|
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var currentLanguage = await _workContext.GetWorkingLanguageAsync();
|
|
var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.PollBySystemNameModelKey,
|
|
systemKeyword, currentLanguage, store);
|
|
|
|
var cachedModel = await _staticCacheManager.GetAsync(cacheKey, async () =>
|
|
{
|
|
var poll = (await _pollService
|
|
.GetPollsAsync(store.Id, currentLanguage.Id, systemKeyword: systemKeyword))
|
|
.FirstOrDefault();
|
|
|
|
//we do not cache nulls. that's why let's return an empty record (ID = 0)
|
|
if (poll == null)
|
|
return new PollModel { Id = 0 };
|
|
|
|
return await PreparePollModelAsync(poll, false);
|
|
});
|
|
|
|
if ((cachedModel?.Id ?? 0) == 0)
|
|
return null;
|
|
|
|
//"AlreadyVoted" property of "PollModel" object depends on the current customer. Let's update it.
|
|
//But first we need to clone the cached model (the updated one should not be cached)
|
|
var model = cachedModel with { };
|
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
|
model.AlreadyVoted = await _pollService.AlreadyVotedAsync(model.Id, customer.Id);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare the home page poll models
|
|
/// </summary>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the list of the poll model
|
|
/// </returns>
|
|
public virtual async Task<List<PollModel>> PrepareHomepagePollModelsAsync()
|
|
{
|
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var language = await _workContext.GetWorkingLanguageAsync();
|
|
var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.HomepagePollsModelKey, language, store);
|
|
|
|
var cachedPolls = await _staticCacheManager.GetAsync(cacheKey, async () =>
|
|
{
|
|
var polls = await _pollService.GetPollsAsync(store.Id, language.Id, loadShownOnHomepageOnly: true);
|
|
var pollsModels = await polls.SelectAwait(async poll => await PreparePollModelAsync(poll, false)).ToListAsync();
|
|
return pollsModels;
|
|
});
|
|
|
|
//"AlreadyVoted" property of "PollModel" object depends on the current customer. Let's update it.
|
|
//But first we need to clone the cached model (the updated one should not be cached)
|
|
var model = new List<PollModel>();
|
|
foreach (var poll in cachedPolls)
|
|
{
|
|
var pollModel = poll with { };
|
|
pollModel.AlreadyVoted = await _pollService.AlreadyVotedAsync(pollModel.Id, customer.Id);
|
|
model.Add(pollModel);
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
#endregion
|
|
} |