Try your search with a different keyword or use * as a wildcard.
using Microsoft.AspNetCore.Mvc.Rendering;
using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Directory;
using Nop.Core.Domain.Tax;
using Nop.Data;
using Nop.Plugin.Misc.RFQ.Domains;
using Nop.Plugin.Misc.RFQ.Models.Admin;
using Nop.Plugin.Misc.RFQ.Services;
using Nop.Services;
using Nop.Services.Catalog;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Seo;
using Nop.Services.Tax;
using Nop.Web.Areas.Admin.Factories;
using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions;
using Nop.Web.Areas.Admin.Models.Catalog;
using Nop.Web.Framework.Models.Extensions;
using ProductSearchModel = Nop.Plugin.Misc.RFQ.Models.Admin.ProductSearchModel;
namespace Nop.Plugin.Misc.RFQ.Factories;
public class AdminModelFactory
{
#region Fields
private readonly CurrencySettings _currencySettings;
private readonly IBaseAdminModelFactory _baseAdminModelFactory;
private readonly ICurrencyService _currencyService;
private readonly ICustomerService _customerService;
private readonly IDateTimeHelper _dateTimeHelper;
private readonly ILocalizationService _localizationService;
private readonly IPriceCalculationService _priceCalculationService;
private readonly IPriceFormatter _priceFormatter;
private readonly IProductAttributeFormatter _productAttributeFormatter;
private readonly IProductAttributeService _productAttributeService;
private readonly IProductService _productService;
private readonly IRepository _customerRepository;
private readonly IStoreContext _storeContext;
private readonly ITaxService _taxService;
private readonly IUrlRecordService _urlRecordService;
private readonly RfqService _rfqService;
#endregion
#region Ctor
public AdminModelFactory(CurrencySettings currencySettings,
IBaseAdminModelFactory baseAdminModelFactory,
ICurrencyService currencyService,
ICustomerService customerService,
IDateTimeHelper dateTimeHelper,
ILocalizationService localizationService,
IPriceCalculationService priceCalculationService,
IPriceFormatter priceFormatter,
IProductAttributeFormatter productAttributeFormatter,
IProductAttributeService productAttributeService,
IProductService productService,
IRepository customerRepository,
IStoreContext storeContext,
ITaxService taxService,
IUrlRecordService urlRecordService,
RfqService rfqService)
{
_currencySettings = currencySettings;
_baseAdminModelFactory = baseAdminModelFactory;
_currencyService = currencyService;
_customerService = customerService;
_dateTimeHelper = dateTimeHelper;
_localizationService = localizationService;
_priceCalculationService = priceCalculationService;
_priceFormatter = priceFormatter;
_productAttributeFormatter = productAttributeFormatter;
_productAttributeService = productAttributeService;
_productService = productService;
_customerRepository = customerRepository;
_storeContext = storeContext;
_taxService = taxService;
_urlRecordService = urlRecordService;
_rfqService = rfqService;
}
#endregion
#region Utilities
private async Task PrepareProductAttributeModelsAsync(IList models, Customer customer, Product product)
{
ArgumentNullException.ThrowIfNull(models);
ArgumentNullException.ThrowIfNull(product);
var attributes = await _productAttributeService.GetProductAttributeMappingsByProductIdAsync(product.Id);
foreach (var attribute in attributes)
{
var attributeModel = new AddProductModel.ProductAttributeModel
{
Id = attribute.Id,
ProductAttributeId = attribute.ProductAttributeId,
Name = (await _productAttributeService.GetProductAttributeByIdAsync(attribute.ProductAttributeId)).Name,
TextPrompt = attribute.TextPrompt,
IsRequired = attribute.IsRequired,
AttributeControlType = attribute.AttributeControlType,
HasCondition = !string.IsNullOrEmpty(attribute.ConditionAttributeXml)
};
if (!string.IsNullOrEmpty(attribute.ValidationFileAllowedExtensions))
{
attributeModel.AllowedFileExtensions = attribute.ValidationFileAllowedExtensions
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.ToList();
}
if (attribute.ShouldHaveValues())
{
var store = await _storeContext.GetCurrentStoreAsync();
//values
var attributeValues = await _productAttributeService.GetProductAttributeValuesAsync(attribute.Id);
foreach (var attributeValue in attributeValues)
{
//price adjustment
var (priceAdjustment, _) = await _taxService.GetProductPriceAsync(product,
await _priceCalculationService.GetProductAttributeValuePriceAdjustmentAsync(product, attributeValue, customer, store));
var priceAdjustmentStr = string.Empty;
if (priceAdjustment != 0)
{
if (attributeValue.PriceAdjustmentUsePercentage)
{
priceAdjustmentStr = attributeValue.PriceAdjustment.ToString("G29");
priceAdjustmentStr = priceAdjustment > 0 ? $"+{priceAdjustmentStr}%" : $"{priceAdjustmentStr}%";
}
else
{
priceAdjustmentStr = priceAdjustment > 0
? $"+{await _priceFormatter.FormatPriceAsync(priceAdjustment, false, false)}"
: $"-{await _priceFormatter.FormatPriceAsync(-priceAdjustment, false, false)}";
}
}
attributeModel.Values.Add(new AddProductModel.ProductAttributeValueModel
{
Id = attributeValue.Id,
Name = attributeValue.Name,
IsPreSelected = attributeValue.IsPreSelected,
CustomerEntersQty = attributeValue.CustomerEntersQty,
Quantity = attributeValue.Quantity,
PriceAdjustment = priceAdjustmentStr
});
}
}
models.Add(attributeModel);
}
}
private async Task PreparedRequestQuoteItemModelAsync(RequestQuoteItem item, Currency primaryStoreCurrency)
{
var product = await _productService.GetProductByIdAsync(item.ProductId);
return new RequestQuoteItemModel
{
Id = item.Id,
RequestedQty = item.RequestedQty,
AdminNotes = item.AdminNotes.Replace("\r\n", "
"),
OriginalProductPrice = await _priceFormatter.FormatPriceAsync(item.OriginalProductPrice, true, primaryStoreCurrency),
ProductName = product != null ? product.Name : await _localizationService.GetResourceAsync("Plugins.Misc.RFQ.ProductDeleted"),
ProductId = item.ProductId,
RequestedUnitPrice = await _priceFormatter.FormatPriceAsync(item.RequestedUnitPrice, true, primaryStoreCurrency),
RequestedUnitPriceValue = item.RequestedUnitPrice,
ProductAttributeInfo = product != null ? await _productAttributeFormatter.FormatAttributesAsync(product, item.ProductAttributesXml) : string.Empty
};
}
private async Task PreparedQuoteItemModelAsync(QuoteItem item, Currency primaryStoreCurrency)
{
var product = await _productService.GetProductByIdAsync(item.ProductId);
return new QuoteItemModel
{
Id = item.Id,
OfferedQty = item.OfferedQty,
ProductName = product != null ? product.Name : await _localizationService.GetResourceAsync("Plugins.Misc.RFQ.ProductDeleted"),
ProductId = item.ProductId,
OfferedUnitPrice = await _priceFormatter.FormatPriceAsync(item.OfferedUnitPrice, true, primaryStoreCurrency),
OfferedUnitPriceValue = item.OfferedUnitPrice,
ProductAttributeInfo = product != null ? await _productAttributeFormatter.FormatAttributesAsync(product, item.AttributesXml) : string.Empty,
RequestedQty = item.RequestedQty,
RequestedUnitPrice = item.RequestedUnitPrice.HasValue ? await _priceFormatter.FormatPriceAsync(item.RequestedUnitPrice.Value, true, primaryStoreCurrency) : string.Empty,
};
}
#endregion
#region Methods
///
/// Prepare request a quote search model
///
///
/// A task that represents the asynchronous operation
/// The task result contains the request a quote search model
///
public async Task PrepareRequestQuoteSearchModelAsync()
{
var searchModel = new RequestQuoteSearchModel();
//prepare available statuses
searchModel.AvailableRequestQuoteStatuses.AddRange(await RequestQuoteStatus.Submitted.ToSelectListAsync(false));
//prepare default item text
var defaultItemText = await _localizationService.GetResourceAsync("Admin.Common.All");
//insert this default item at first
searchModel.AvailableRequestQuoteStatuses.Insert(0, new SelectListItem { Text = defaultItemText, Value = "-1" });
//prepare page parameters
searchModel.SetGridPageSize();
return searchModel;
}
///
/// Prepare a quote search model
///
///
/// A task that represents the asynchronous operation
/// The task result contains the quote search model
///
public async Task PrepareQuoteSearchModelAsync()
{
var searchModel = new QuoteSearchModel();
//prepare available statuses
searchModel.AvailableQuoteStatuses.AddRange(await QuoteStatus.CreatedFromRequestQuote.ToSelectListAsync(false));
//prepare default item text
var defaultItemText = await _localizationService.GetResourceAsync("Admin.Common.All");
//insert this default item at first
searchModel.AvailableQuoteStatuses.Insert(0, new SelectListItem { Text = defaultItemText, Value = "-1" });
//prepare page parameters
searchModel.SetGridPageSize();
return searchModel;
}
///
/// Prepare a request a quote list model
///
/// Request a quote search model
///
/// A task that represents the asynchronous operation
/// The task result contains the request a quote list model
///
public async Task PrepareRequestQuoteListModelAsync(RequestQuoteSearchModel searchModel)
{
var createdOnFromValue = !searchModel.CreatedOnFrom.HasValue ? null
: (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.CreatedOnFrom.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync());
var createdOnToValue = !searchModel.CreatedOnTo.HasValue ? null
: (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.CreatedOnTo.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()).AddDays(1);
var items = await _rfqService.SearchRequestsQuoteAsync(searchModel.RequestQuoteStatus, createdOnFromValue,
createdOnToValue, searchModel.CustomerEmail, searchModel.Page - 1, searchModel.PageSize);
var customerEmails = (await _customerRepository.GetByIdsAsync(items.Select(p => p.CustomerId).Distinct().ToArray())).ToDictionary(p => p.Id, p => p.Email);
//prepare list model
var model = await new RequestListModel().PrepareToGridAsync(searchModel, items, () =>
{
//fill in model values from the entity
return items.SelectAwait(async item => await PreparedRequestQuoteModelAsync(item, customerEmails));
});
return model;
}
///
/// Prepare a request a quote model
///
/// The request a quote
/// Preloaded customers emails
///
/// A task that represents the asynchronous operation
/// The task result contains the request a quote model
///
public async Task PreparedRequestQuoteModelAsync(RequestQuote requestQuote, IDictionary customerEmails = null)
{
string email;
if (customerEmails != null)
customerEmails.TryGetValue(requestQuote.CustomerId, out email);
else
email = (await _customerService.GetCustomerByIdAsync(requestQuote.CustomerId))?.Email;
return new RequestQuoteModel
{
Id = requestQuote.Id,
CustomerId = requestQuote.CustomerId,
CreatedOnUtc = await _dateTimeHelper.ConvertToUserTimeAsync(requestQuote.CreatedOnUtc, DateTimeKind.Utc),
//fill in additional values (not existing in the entity)
Status = await _localizationService.GetLocalizedEnumAsync(requestQuote.Status),
StatusType = requestQuote.Status,
CustomerNotes = requestQuote.CustomerNotes,
CustomerEmail = email ?? string.Empty,
AdminNotes = requestQuote.AdminNotes,
QuoteId = requestQuote.QuoteId,
Items = await PrepareRequestItemListModelAsync(requestQuote.Id)
};
}
///
/// Prepare a request a quote item list model
///
/// Request a quote identifier
///
/// A task that represents the asynchronous operation
/// The task result contains the request a quote item list model
///
public async Task> PrepareRequestItemListModelAsync(int requestQuoteId)
{
var items = await _rfqService.GetRequestQuoteItemsAsync(requestQuoteId);
var primaryStoreCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
return await items.SelectAwait(async p => await PreparedRequestQuoteItemModelAsync(p, primaryStoreCurrency)).ToListAsync();
}
///
/// Prepare a quote item list model
///
/// Quote item identifier
///
/// A task that represents the asynchronous operation
/// The task result contains the quote item list model
///
public async Task> PrepareQuoteItemListModelAsync(int quoteId)
{
var items = await _rfqService.GetQuoteItemsAsync(quoteId);
var primaryStoreCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
return await items.SelectAwait(async p => await PreparedQuoteItemModelAsync(p, primaryStoreCurrency)).ToListAsync();
}
///
/// Prepare product model to add to the quote
///
/// Product model to add to the quote
/// Quote
/// Product
///
/// A task that represents the asynchronous operation
/// The task result contains the product model to add to the quote
///
public async Task PrepareAddProductModelAsync(AddProductModel model, Quote quote, Product product)
{
ArgumentNullException.ThrowIfNull(model);
ArgumentNullException.ThrowIfNull(product);
ArgumentNullException.ThrowIfNull(quote);
var customerId = quote.CustomerId;
var customer = await _customerService.GetCustomerByIdAsync(customerId);
var taxDisplayType = await _customerService.GetCustomerTaxDisplayTypeAsync(customer);
var store = await _storeContext.GetCurrentStoreAsync();
model.ProductId = product.Id;
model.QuoteId = quote.Id;
model.Name = product.Name;
model.IsRental = product.IsRental;
model.ProductType = product.ProductType;
var presetQty = 1;
var (_, presetPrice, _, _) = await _priceCalculationService.GetFinalPriceAsync(product, customer, store, decimal.Zero, true, presetQty);
var (presetPriceInclTax, _) = await _taxService.GetProductPriceAsync(product, presetPrice, taxDisplayType == TaxDisplayType.IncludingTax, customer);
model.UnitPriceInclTax = presetPriceInclTax;
model.Quantity = presetQty;
//attributes
await PrepareProductAttributeModelsAsync(model.ProductAttributes, customer, product);
model.HasCondition = model.ProductAttributes.Any(attribute => attribute.HasCondition);
//gift card
model.GiftCard.IsGiftCard = product.IsGiftCard;
if (model.GiftCard.IsGiftCard)
model.GiftCard.GiftCardType = product.GiftCardType;
return model;
}
///
/// Prepare product search model to add to the quote
///
/// Product search model to add to the order
/// The quote identifier
///
/// A task that represents the asynchronous operation
/// The task result contains the product search model to add to the quote
///
public async Task PrepareAddProductSearchModelAsync(ProductSearchModel searchModel, int entityId)
{
ArgumentNullException.ThrowIfNull(searchModel);
searchModel.EntityId = entityId;
//prepare available categories
await _baseAdminModelFactory.PrepareCategoriesAsync(searchModel.AvailableCategories);
//prepare available manufacturers
await _baseAdminModelFactory.PrepareManufacturersAsync(searchModel.AvailableManufacturers);
//prepare available product types
await _baseAdminModelFactory.PrepareProductTypesAsync(searchModel.AvailableProductTypes);
//prepare page parameters
searchModel.SetGridPageSize();
return searchModel;
}
///
/// Prepare a product to a quote list model
///
/// Product search model
///
/// A task that represents the asynchronous operation
/// The task result contains the product to a quote list model
///
public async Task PrepareProductListModelAsync(ProductSearchModel searchModel)
{
ArgumentNullException.ThrowIfNull(searchModel);
//get products
var products = await _productService.SearchProductsAsync(showHidden: true,
categoryIds: new List { searchModel.SearchCategoryId },
manufacturerIds: new List { searchModel.SearchManufacturerId },
productType: searchModel.SearchProductTypeId > 0 ? (ProductType?)searchModel.SearchProductTypeId : null,
keywords: searchModel.SearchProductName,
pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize);
//prepare grid model
var model = await new ProductToRequestListModel().PrepareToGridAsync(searchModel, products, () =>
{
//fill in model values from the entity
return products.SelectAwait(async product =>
{
var productModel = product.ToModel();
productModel.SeName = await _urlRecordService.GetSeNameAsync(product, 0, true, false);
return productModel;
});
});
return model;
}
///
/// Prepare a quote model
///
/// The quote
/// Preloaded customers emails
///
/// A task that represents the asynchronous operation
/// The task result contains the quote model
///
public async Task PreparedQuoteModelAsync(Quote quote, IDictionary customerEmails = null)
{
string email;
if (customerEmails != null)
customerEmails.TryGetValue(quote.CustomerId, out email);
else
email = (await _customerService.GetCustomerByIdAsync(quote.CustomerId))?.Email;
var model = new QuoteModel
{
Id = quote.Id,
CustomerId = quote.CustomerId,
CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(quote.CreatedOnUtc, DateTimeKind.Utc),
//fill in additional values (not existing in the entity)
Status = await _localizationService.GetLocalizedEnumAsync(quote.Status),
StatusType = quote.Status,
CustomerEmail = email ?? string.Empty,
AdminNotes = quote.AdminNotes,
RequestQuoteId = quote.RequestQuoteId,
OrderId = quote.OrderId,
Items = await PrepareQuoteItemListModelAsync(quote.Id)
};
if (model.Editable)
model.ExpirationDateUtc = quote.ExpirationDateUtc;
else if (quote.ExpirationDateUtc.HasValue)
model.ExpirationDateUtc = await _dateTimeHelper.ConvertToUserTimeAsync(quote.ExpirationDateUtc.Value, DateTimeKind.Utc);
return model;
}
///
/// Prepare a quote list model
///
/// Quote search model
///
/// A task that represents the asynchronous operation
/// The task result contains the quote list model
///
public async Task PrepareQuoteListModelAsync(QuoteSearchModel searchModel)
{
var createdOnFromValue = !searchModel.CreatedOnFrom.HasValue ? null
: (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.CreatedOnFrom.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync());
var createdOnToValue = !searchModel.CreatedOnTo.HasValue ? null
: (DateTime?)_dateTimeHelper.ConvertToUtcTime(searchModel.CreatedOnTo.Value, await _dateTimeHelper.GetCurrentTimeZoneAsync()).AddDays(1);
var items = await _rfqService.SearchQuotesAsync(searchModel.QuoteStatus, createdOnFromValue, createdOnToValue, searchModel.CustomerEmail, searchModel.Page - 1, searchModel.PageSize);
var customerEmails = (await _customerRepository.GetByIdsAsync(items.Select(p => p.CustomerId).Distinct().ToArray())).ToDictionary(p => p.Id, p => p.Email);
//prepare list model
var model = await new QuoteListModel().PrepareToGridAsync(searchModel, items, () =>
{
//fill in model values from the entity
return items.SelectAwait(async item =>
{
var model = await PreparedQuoteModelAsync(item, customerEmails);
if (model.Editable && model.ExpirationDateUtc.HasValue)
model.ExpirationDateUtc = await _dateTimeHelper.ConvertToUserTimeAsync(model.ExpirationDateUtc.Value, DateTimeKind.Utc);
return model;
});
});
return model;
}
#endregion
}