Try your search with a different keyword or use * as a wildcard.
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.Security;
using Nop.Core.Domain.Vendors;
using Nop.Services.Attributes;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Html;
using Nop.Services.Localization;
using Nop.Services.Media;
using Nop.Services.Messages;
using Nop.Services.Seo;
using Nop.Services.Vendors;
using Nop.Web.Factories;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;
using Nop.Web.Models.Vendors;
namespace Nop.Web.Controllers;
[AutoValidateAntiforgeryToken]
public partial class VendorController : BasePublicController
{
#region Fields
protected readonly CaptchaSettings _captchaSettings;
protected readonly IAttributeParser _vendorAttributeParser;
protected readonly IAttributeService _vendorAttributeService;
protected readonly ICustomerService _customerService;
protected readonly IDownloadService _downloadService;
protected readonly IGenericAttributeService _genericAttributeService;
protected readonly IHtmlFormatter _htmlFormatter;
protected readonly ILocalizationService _localizationService;
protected readonly IPictureService _pictureService;
protected readonly IUrlRecordService _urlRecordService;
protected readonly IVendorModelFactory _vendorModelFactory;
protected readonly IVendorService _vendorService;
protected readonly IWorkContext _workContext;
protected readonly IWorkflowMessageService _workflowMessageService;
protected readonly LocalizationSettings _localizationSettings;
protected readonly VendorSettings _vendorSettings;
private static readonly char[] _separator = [','];
#endregion
#region Ctor
public VendorController(CaptchaSettings captchaSettings,
IAttributeParser vendorAttributeParser,
IAttributeService vendorAttributeService,
ICustomerService customerService,
IDownloadService downloadService,
IGenericAttributeService genericAttributeService,
IHtmlFormatter htmlFormatter,
ILocalizationService localizationService,
IPictureService pictureService,
IUrlRecordService urlRecordService,
IVendorModelFactory vendorModelFactory,
IVendorService vendorService,
IWorkContext workContext,
IWorkflowMessageService workflowMessageService,
LocalizationSettings localizationSettings,
VendorSettings vendorSettings)
{
_captchaSettings = captchaSettings;
_vendorAttributeParser = vendorAttributeParser;
_vendorAttributeService = vendorAttributeService;
_customerService = customerService;
_downloadService = downloadService;
_genericAttributeService = genericAttributeService;
_htmlFormatter = htmlFormatter;
_localizationService = localizationService;
_pictureService = pictureService;
_urlRecordService = urlRecordService;
_vendorModelFactory = vendorModelFactory;
_vendorService = vendorService;
_workContext = workContext;
_workflowMessageService = workflowMessageService;
_localizationSettings = localizationSettings;
_vendorSettings = vendorSettings;
}
#endregion
#region Utilities
protected virtual async Task UpdatePictureSeoNamesAsync(Vendor vendor)
{
var picture = await _pictureService.GetPictureByIdAsync(vendor.PictureId);
if (picture != null)
await _pictureService.SetSeoFilenameAsync(picture.Id, await _pictureService.GetPictureSeNameAsync(vendor.Name));
}
protected virtual async Task ParseVendorAttributesAsync(IFormCollection form)
{
ArgumentNullException.ThrowIfNull(form);
var attributesXml = "";
var attributes = await _vendorAttributeService.GetAllAttributesAsync();
foreach (var attribute in attributes)
{
var controlId = $"{NopVendorDefaults.VendorAttributePrefix}{attribute.Id}";
switch (attribute.AttributeControlType)
{
case AttributeControlType.DropdownList:
case AttributeControlType.RadioList:
{
var ctrlAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(ctrlAttributes))
{
var selectedAttributeId = int.Parse(ctrlAttributes);
if (selectedAttributeId > 0)
attributesXml = _vendorAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
}
break;
case AttributeControlType.Checkboxes:
{
var cblAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(cblAttributes))
{
foreach (var item in cblAttributes.ToString().Split(_separator, StringSplitOptions.RemoveEmptyEntries)
)
{
var selectedAttributeId = int.Parse(item);
if (selectedAttributeId > 0)
attributesXml = _vendorAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
}
}
break;
case AttributeControlType.ReadonlyCheckboxes:
{
//load read-only (already server-side selected) values
var attributeValues = await _vendorAttributeService.GetAttributeValuesAsync(attribute.Id);
foreach (var selectedAttributeId in attributeValues
.Where(v => v.IsPreSelected)
.Select(v => v.Id)
.ToList())
{
attributesXml = _vendorAttributeParser.AddAttribute(attributesXml,
attribute, selectedAttributeId.ToString());
}
}
break;
case AttributeControlType.TextBox:
case AttributeControlType.MultilineTextbox:
{
var ctrlAttributes = form[controlId];
if (!StringValues.IsNullOrEmpty(ctrlAttributes))
{
var enteredText = ctrlAttributes.ToString().Trim();
attributesXml = _vendorAttributeParser.AddAttribute(attributesXml,
attribute, enteredText);
}
}
break;
case AttributeControlType.Datepicker:
case AttributeControlType.ColorSquares:
case AttributeControlType.ImageSquares:
case AttributeControlType.FileUpload:
//not supported vendor attributes
default:
break;
}
}
return attributesXml;
}
#endregion
#region Methods
public virtual async Task ApplyVendor()
{
if (!_vendorSettings.AllowCustomersToApplyForVendorAccount)
return RedirectToRoute("Homepage");
if (!await _customerService.IsRegisteredAsync(await _workContext.GetCurrentCustomerAsync()))
return Challenge();
var model = new ApplyVendorModel();
model = await _vendorModelFactory.PrepareApplyVendorModelAsync(model, true, false, null);
return View(model);
}
[HttpPost, ActionName("ApplyVendor")]
[ValidateCaptcha]
public virtual async Task ApplyVendorSubmit(ApplyVendorModel model, bool captchaValid, IFormFile uploadedFile, IFormCollection form)
{
if (!_vendorSettings.AllowCustomersToApplyForVendorAccount)
return RedirectToRoute("Homepage");
var customer = await _workContext.GetCurrentCustomerAsync();
if (!await _customerService.IsRegisteredAsync(customer))
return Challenge();
if (await _customerService.IsAdminAsync(customer))
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Vendors.ApplyAccount.IsAdmin"));
//validate CAPTCHA
if (_captchaSettings.Enabled && _captchaSettings.ShowOnApplyVendorPage && !captchaValid)
{
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Common.WrongCaptchaMessage"));
}
var pictureId = 0;
if (uploadedFile != null && !string.IsNullOrEmpty(uploadedFile.FileName))
{
try
{
var contentType = uploadedFile.ContentType.ToLowerInvariant();
if (!contentType.StartsWith("image/") || contentType.StartsWith("image/svg"))
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Vendors.ApplyAccount.Picture.ErrorMessage"));
else
{
var vendorPictureBinary = await _downloadService.GetDownloadBitsAsync(uploadedFile);
var picture = await _pictureService.InsertPictureAsync(vendorPictureBinary, contentType, null);
if (picture != null)
pictureId = picture.Id;
}
}
catch (Exception)
{
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Vendors.ApplyAccount.Picture.ErrorMessage"));
}
}
//vendor attributes
var vendorAttributesXml = await ParseVendorAttributesAsync(form);
var warnings = (await _vendorAttributeParser.GetAttributeWarningsAsync(vendorAttributesXml)).ToList();
foreach (var warning in warnings)
{
ModelState.AddModelError(string.Empty, warning);
}
if (ModelState.IsValid)
{
var description = _htmlFormatter.FormatText(model.Description, false, false, true, false, false, false);
//disabled by default
var vendor = new Vendor
{
Name = model.Name,
Email = model.Email,
//some default settings
PageSize = 6,
AllowCustomersToSelectPageSize = true,
PageSizeOptions = _vendorSettings.DefaultVendorPageSizeOptions,
PictureId = pictureId,
Description = WebUtility.HtmlEncode(description)
};
await _vendorService.InsertVendorAsync(vendor);
//search engine name (the same as vendor name)
var seName = await _urlRecordService.ValidateSeNameAsync(vendor, vendor.Name, vendor.Name, true);
await _urlRecordService.SaveSlugAsync(vendor, seName, 0);
//associate to the current customer
//but a store owner will have to manually add this customer role to "Vendors" role
//if he wants to grant access to admin area
customer.VendorId = vendor.Id;
await _customerService.UpdateCustomerAsync(customer);
//update picture seo file name
await UpdatePictureSeoNamesAsync(vendor);
//save vendor attributes
await _genericAttributeService.SaveAttributeAsync(vendor, NopVendorDefaults.VendorAttributes, vendorAttributesXml);
//notify store owner here (email)
await _workflowMessageService.SendNewVendorAccountApplyStoreOwnerNotificationAsync(customer,
vendor, _localizationSettings.DefaultAdminLanguageId);
model.DisableFormInput = true;
model.Result = await _localizationService.GetResourceAsync("Vendors.ApplyAccount.Submitted");
return View(model);
}
//If we got this far, something failed, redisplay form
model = await _vendorModelFactory.PrepareApplyVendorModelAsync(model, false, true, vendorAttributesXml);
return View(model);
}
public virtual async Task Info()
{
if (!await _customerService.IsRegisteredAsync(await _workContext.GetCurrentCustomerAsync()))
return Challenge();
if (await _workContext.GetCurrentVendorAsync() == null || !_vendorSettings.AllowVendorsToEditInfo)
return RedirectToRoute("CustomerInfo");
var model = new VendorInfoModel();
model = await _vendorModelFactory.PrepareVendorInfoModelAsync(model, false);
return View(model);
}
[HttpPost, ActionName("Info")]
[FormValueRequired("save-info-button")]
public virtual async Task Info(VendorInfoModel model, IFormFile uploadedFile, IFormCollection form)
{
if (!await _customerService.IsRegisteredAsync(await _workContext.GetCurrentCustomerAsync()))
return Challenge();
var vendor = await _workContext.GetCurrentVendorAsync();
if (vendor == null || !_vendorSettings.AllowVendorsToEditInfo)
return RedirectToRoute("CustomerInfo");
Picture picture = null;
if (uploadedFile != null && !string.IsNullOrEmpty(uploadedFile.FileName))
{
try
{
var contentType = uploadedFile.ContentType.ToLowerInvariant();
if (!contentType.StartsWith("image/") || contentType.StartsWith("image/svg"))
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Account.VendorInfo.Picture.ErrorMessage"));
else
{
var vendorPictureBinary = await _downloadService.GetDownloadBitsAsync(uploadedFile);
picture = await _pictureService.InsertPictureAsync(vendorPictureBinary, contentType, null);
}
}
catch (Exception)
{
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Account.VendorInfo.Picture.ErrorMessage"));
}
}
var prevPicture = await _pictureService.GetPictureByIdAsync(vendor.PictureId);
//vendor attributes
var vendorAttributesXml = await ParseVendorAttributesAsync(form);
var warnings = (await _vendorAttributeParser.GetAttributeWarningsAsync(vendorAttributesXml)).ToList();
foreach (var warning in warnings)
{
ModelState.AddModelError(string.Empty, warning);
}
if (ModelState.IsValid)
{
var description = _htmlFormatter.FormatText(model.Description, false, false, true, false, false, false);
vendor.Name = model.Name;
vendor.Email = model.Email;
vendor.Description = WebUtility.HtmlEncode(description);
if (picture != null)
{
vendor.PictureId = picture.Id;
if (prevPicture != null)
await _pictureService.DeletePictureAsync(prevPicture);
}
//update picture seo file name
await UpdatePictureSeoNamesAsync(vendor);
await _vendorService.UpdateVendorAsync(vendor);
//save vendor attributes
await _genericAttributeService.SaveAttributeAsync(vendor, NopVendorDefaults.VendorAttributes, vendorAttributesXml);
//notifications
if (_vendorSettings.NotifyStoreOwnerAboutVendorInformationChange)
await _workflowMessageService.SendVendorInformationChangeStoreOwnerNotificationAsync(vendor, _localizationSettings.DefaultAdminLanguageId);
return RedirectToAction("Info");
}
//If we got this far, something failed, redisplay form
model = await _vendorModelFactory.PrepareVendorInfoModelAsync(model, true, vendorAttributesXml);
return View(model);
}
[HttpPost, ActionName("Info")]
[FormValueRequired("remove-picture")]
public virtual async Task RemovePicture()
{
if (!await _customerService.IsRegisteredAsync(await _workContext.GetCurrentCustomerAsync()))
return Challenge();
var vendor = await _workContext.GetCurrentVendorAsync();
if (vendor == null || !_vendorSettings.AllowVendorsToEditInfo)
return RedirectToRoute("CustomerInfo");
var picture = await _pictureService.GetPictureByIdAsync(vendor.PictureId);
if (picture != null)
await _pictureService.DeletePictureAsync(picture);
vendor.PictureId = 0;
await _vendorService.UpdateVendorAsync(vendor);
//notifications
if (_vendorSettings.NotifyStoreOwnerAboutVendorInformationChange)
await _workflowMessageService.SendVendorInformationChangeStoreOwnerNotificationAsync(vendor, _localizationSettings.DefaultAdminLanguageId);
return RedirectToAction("Info");
}
#endregion
}