/// <summary> /// Prepare selected and all available stores for the passed model by store mappings /// </summary> /// <typeparam name="TModel">Store mapping supported model type</typeparam> /// <typeparam name="TEntity">Store mapping supported entity type</typeparam> /// <param name="model">Model</param> /// <param name="entity">Entity</param> /// <param name="ignoreStoreMappings">Whether to ignore existing store mappings</param> public virtual async Task PrepareModelStoresAsync <TModel, TEntity>(TModel model, TEntity entity, bool ignoreStoreMappings) where TModel : IStoreMappingSupportedModel where TEntity : BaseEntity, IStoreMappingSupported { if (model == null) { throw new ArgumentNullException(nameof(model)); } //prepare stores with granted access if (!ignoreStoreMappings && entity != null) { model.SelectedStoreIds = (await _storeMappingService.GetStoresIdsWithAccessAsync(entity)).ToList(); } await PrepareModelStoresAsync(model); }
/// <summary> /// Prepare SendinblueModel /// </summary> /// <param name="model">Model</param> private async Task PrepareModelAsync(ConfigurationModel model) { //load settings for active store scope var storeId = await _storeContext.GetActiveStoreScopeConfigurationAsync(); var sendinblueSettings = await _settingService.LoadSettingAsync <SendinblueSettings>(storeId); //whether plugin is configured if (string.IsNullOrEmpty(sendinblueSettings.ApiKey)) { return; } //prepare common properties model.ActiveStoreScopeConfiguration = storeId; model.ApiKey = sendinblueSettings.ApiKey; model.ListId = sendinblueSettings.ListId; model.SmtpKey = sendinblueSettings.SmtpKey; model.SenderId = sendinblueSettings.SenderId; model.UseSmsNotifications = sendinblueSettings.UseSmsNotifications; model.SmsSenderName = sendinblueSettings.SmsSenderName; model.StoreOwnerPhoneNumber = sendinblueSettings.StoreOwnerPhoneNumber; model.UseMarketingAutomation = sendinblueSettings.UseMarketingAutomation; model.TrackingScript = sendinblueSettings.TrackingScript; model.HideGeneralBlock = await _genericAttributeService.GetAttributeAsync <bool>(await _workContext.GetCurrentCustomerAsync(), SendinblueDefaults.HideGeneralBlock); model.HideSynchronizationBlock = await _genericAttributeService.GetAttributeAsync <bool>(await _workContext.GetCurrentCustomerAsync(), SendinblueDefaults.HideSynchronizationBlock); model.HideTransactionalBlock = await _genericAttributeService.GetAttributeAsync <bool>(await _workContext.GetCurrentCustomerAsync(), SendinblueDefaults.HideTransactionalBlock); model.HideSmsBlock = await _genericAttributeService.GetAttributeAsync <bool>(await _workContext.GetCurrentCustomerAsync(), SendinblueDefaults.HideSmsBlock); model.HideMarketingAutomationBlock = await _genericAttributeService.GetAttributeAsync <bool>(await _workContext.GetCurrentCustomerAsync(), SendinblueDefaults.HideMarketingAutomationBlock); //prepare nested search models model.MessageTemplateSearchModel.SetGridPageSize(); model.SmsSearchModel.SetGridPageSize(); //prepare add SMS model model.AddSms.AvailablePhoneTypes.Add(new SelectListItem(await _localizationService.GetResourceAsync("Plugins.Misc.Sendinblue.MyPhone"), "0")); model.AddSms.AvailablePhoneTypes.Add(new SelectListItem(await _localizationService.GetResourceAsync("Plugins.Misc.Sendinblue.CustomerPhone"), "1")); model.AddSms.AvailablePhoneTypes.Add(new SelectListItem(await _localizationService.GetResourceAsync("Plugins.Misc.Sendinblue.BillingAddressPhone"), "2")); model.AddSms.DefaultSelectedPhoneTypeId = model.AddSms.AvailablePhoneTypes.First().Value; var stores = await _storeService.GetAllStoresAsync(); var messageTemplates = await _messageTemplateService.GetAllMessageTemplatesAsync(storeId); model.AddSms.AvailableMessages = await messageTemplates.SelectAwait(async messageTemplate => { var name = messageTemplate.Name; if (storeId == 0 && messageTemplate.LimitedToStores) { var storeIds = await _storeMappingService.GetStoresIdsWithAccessAsync(messageTemplate); var storeNames = stores.Where(store => storeIds.Contains(store.Id)).Select(store => store.Name); name = $"{name} ({string.Join(',', storeNames)})"; } return(new SelectListItem(name, messageTemplate.Id.ToString())); }).ToListAsync(); var defaultSelectedMessage = model.AddSms.AvailableMessages.FirstOrDefault(); model.AddSms.DefaultSelectedMessageId = defaultSelectedMessage?.Value ?? "0"; //check whether email account exists if (sendinblueSettings.UseSmtp && await _emailAccountService.GetEmailAccountByIdAsync(sendinblueSettings.EmailAccountId) != null) { model.UseSmtp = sendinblueSettings.UseSmtp; } //get account info var(accountInfo, marketingAutomationEnabled, maKey, accountErrors) = await _sendinblueEmailManager.GetAccountInfoAsync(); model.AccountInfo = accountInfo; model.MarketingAutomationKey = maKey; model.MarketingAutomationDisabled = !marketingAutomationEnabled; if (!string.IsNullOrEmpty(accountErrors)) { _notificationService.ErrorNotification($"{SendinblueDefaults.NotificationMessage} {accountErrors}"); } //prepare overridable settings if (storeId > 0) { model.ListId_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.ListId, storeId); model.UseSmtp_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.UseSmtp, storeId); model.SenderId_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.SenderId, storeId); model.UseSmsNotifications_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.UseSmsNotifications, storeId); model.SmsSenderName_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.SmsSenderName, storeId); model.UseMarketingAutomation_OverrideForStore = await _settingService.SettingExistsAsync(sendinblueSettings, settings => settings.UseMarketingAutomation, storeId); } //check SMTP status var(smtpEnabled, smtpErrors) = await _sendinblueEmailManager.SmtpIsEnabledAsync(); if (!string.IsNullOrEmpty(smtpErrors)) { _notificationService.ErrorNotification($"{SendinblueDefaults.NotificationMessage} {smtpErrors}"); } //get available contact lists to synchronize var(lists, listsErrors) = await _sendinblueEmailManager.GetListsAsync(); model.AvailableLists = lists.Select(list => new SelectListItem(list.Name, list.Id)).ToList(); model.AvailableLists.Insert(0, new SelectListItem("Select list", "0")); if (!string.IsNullOrEmpty(listsErrors)) { _notificationService.ErrorNotification($"{SendinblueDefaults.NotificationMessage} {listsErrors}"); } //get available senders of emails from account var(senders, sendersErrors) = await _sendinblueEmailManager.GetSendersAsync(); model.AvailableSenders = senders.Select(list => new SelectListItem(list.Name, list.Id)).ToList(); model.AvailableSenders.Insert(0, new SelectListItem("Select sender", "0")); if (!string.IsNullOrEmpty(sendersErrors)) { _notificationService.ErrorNotification($"{SendinblueDefaults.NotificationMessage} {sendersErrors}"); } //get allowed tokens model.AllowedTokens = string.Join(", ", await _messageTokenProvider.GetListOfAllowedTokensAsync()); //create attributes in account var attributesErrors = await _sendinblueEmailManager.PrepareAttributesAsync(); if (!string.IsNullOrEmpty(attributesErrors)) { _notificationService.ErrorNotification($"{SendinblueDefaults.NotificationMessage} {attributesErrors}"); } }
/// <summary> /// Create a copy of product with all depended data /// </summary> /// <param name="product">The product to copy</param> /// <param name="newName">The name of product duplicate</param> /// <param name="isPublished">A value indicating whether the product duplicate should be published</param> /// <param name="copyImages">A value indicating whether the product images should be copied</param> /// <param name="copyAssociatedProducts">A value indicating whether the copy associated products</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the product copy /// </returns> public virtual async Task <Product> CopyProductAsync(Product product, string newName, bool isPublished = true, bool copyImages = true, bool copyAssociatedProducts = true) { if (product == null) { throw new ArgumentNullException(nameof(product)); } if (string.IsNullOrEmpty(newName)) { throw new ArgumentException("Product name is required"); } var productCopy = await CopyBaseProductDataAsync(product, newName, isPublished); //localization await CopyLocalizationDataAsync(product, productCopy); //copy product tags foreach (var productTag in await _productTagService.GetAllProductTagsByProductIdAsync(product.Id)) { await _productTagService.InsertProductProductTagMappingAsync(new ProductProductTagMapping { ProductTagId = productTag.Id, ProductId = productCopy.Id }); } await _productService.UpdateProductAsync(productCopy); //copy product pictures var originalNewPictureIdentifiers = await CopyProductPicturesAsync(product, newName, copyImages, productCopy); //quantity change history await _productService.AddStockQuantityHistoryEntryAsync(productCopy, product.StockQuantity, product.StockQuantity, product.WarehouseId, string.Format(await _localizationService.GetResourceAsync("Admin.StockQuantityHistory.Messages.CopyProduct"), product.Id)); //product specifications await CopyProductSpecificationsAsync(product, productCopy); //product <-> warehouses mappings await CopyWarehousesMappingAsync(product, productCopy); //product <-> categories mappings await CopyCategoriesMappingAsync(product, productCopy); //product <-> manufacturers mappings await CopyManufacturersMappingAsync(product, productCopy); //product <-> related products mappings await CopyRelatedProductsMappingAsync(product, productCopy); //product <-> cross sells mappings await CopyCrossSellsMappingAsync(product, productCopy); //product <-> attributes mappings await CopyAttributesMappingAsync(product, productCopy, originalNewPictureIdentifiers); //product <-> discounts mapping await CopyDiscountsMappingAsync(product, productCopy); //store mapping var selectedStoreIds = await _storeMappingService.GetStoresIdsWithAccessAsync(product); foreach (var id in selectedStoreIds) { await _storeMappingService.InsertStoreMappingAsync(productCopy, id); } //tier prices await CopyTierPricesAsync(product, productCopy); //update "HasTierPrices" and "HasDiscountsApplied" properties await _productService.UpdateHasTierPricesPropertyAsync(productCopy); await _productService.UpdateHasDiscountsAppliedAsync(productCopy); //associated products await CopyAssociatedProductsAsync(product, isPublished, copyImages, copyAssociatedProducts, productCopy); return(productCopy); }
/// <summary> /// Create a copy of message template with all depended data /// </summary> /// <param name="messageTemplate">Message template</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the message template copy /// </returns> public virtual async Task <MessageTemplate> CopyMessageTemplateAsync(MessageTemplate messageTemplate) { if (messageTemplate == null) { throw new ArgumentNullException(nameof(messageTemplate)); } var mtCopy = new MessageTemplate { Name = messageTemplate.Name, BccEmailAddresses = messageTemplate.BccEmailAddresses, Subject = messageTemplate.Subject, Body = messageTemplate.Body, IsActive = messageTemplate.IsActive, AttachedDownloadId = messageTemplate.AttachedDownloadId, EmailAccountId = messageTemplate.EmailAccountId, LimitedToStores = messageTemplate.LimitedToStores, DelayBeforeSend = messageTemplate.DelayBeforeSend, DelayPeriod = messageTemplate.DelayPeriod }; await InsertMessageTemplateAsync(mtCopy); var languages = await _languageService.GetAllLanguagesAsync(true); //localization foreach (var lang in languages) { var bccEmailAddresses = await _localizationService.GetLocalizedAsync(messageTemplate, x => x.BccEmailAddresses, lang.Id, false, false); if (!string.IsNullOrEmpty(bccEmailAddresses)) { await _localizedEntityService.SaveLocalizedValueAsync(mtCopy, x => x.BccEmailAddresses, bccEmailAddresses, lang.Id); } var subject = await _localizationService.GetLocalizedAsync(messageTemplate, x => x.Subject, lang.Id, false, false); if (!string.IsNullOrEmpty(subject)) { await _localizedEntityService.SaveLocalizedValueAsync(mtCopy, x => x.Subject, subject, lang.Id); } var body = await _localizationService.GetLocalizedAsync(messageTemplate, x => x.Body, lang.Id, false, false); if (!string.IsNullOrEmpty(body)) { await _localizedEntityService.SaveLocalizedValueAsync(mtCopy, x => x.Body, body, lang.Id); } var emailAccountId = await _localizationService.GetLocalizedAsync(messageTemplate, x => x.EmailAccountId, lang.Id, false, false); if (emailAccountId > 0) { await _localizedEntityService.SaveLocalizedValueAsync(mtCopy, x => x.EmailAccountId, emailAccountId, lang.Id); } } //store mapping var selectedStoreIds = await _storeMappingService.GetStoresIdsWithAccessAsync(messageTemplate); foreach (var id in selectedStoreIds) { await _storeMappingService.InsertStoreMappingAsync(mtCopy, id); } return(mtCopy); }