/// <summary>
        /// Updates settings for a store.
        /// </summary>
        /// <param name="settings">Settings class instance.</param>
        /// <param name="form">Form value collection.</param>
        /// <param name="storeId">Store identifier.</param>
        /// <param name="settingService">Setting service.</param>
        /// <param name="propertyNameMapper">Function to map property names. Return <c>null</c> to skip a property.</param>
        public async Task UpdateSettingsAsync(
            object settings,
            IFormCollection form,
            int storeId,
            Func <string, string> propertyNameMapper = null)
        {
            var settingType       = settings.GetType();
            var settingName       = settingType.Name;
            var settingProperties = FastProperty.GetProperties(settingType).Values;

            foreach (var prop in settingProperties)
            {
                var name = propertyNameMapper?.Invoke(prop.Name) ?? prop.Name;

                if (!name.HasValue())
                {
                    continue;
                }

                var key = string.Concat(settingName, ".", name);

                if (storeId == 0 || IsOverrideChecked(key, form))
                {
                    dynamic value = prop.GetValue(settings);
                    await _settingService.ApplySettingAsync(key, value ?? string.Empty, storeId);
                }
                else if (storeId > 0)
                {
                    await _settingService.RemoveSettingAsync(key, storeId);
                }
            }

            await _db.SaveChangesAsync();
        }
Example #2
0
        /// <summary>
        /// Applies given media storage <paramref name="item"/> to <paramref name="media"/> entity as blob.
        /// </summary>
        /// <param name="media">Media item</param>
        /// <param name="item">The source item</param>
        /// <param name="save">Whether to commit changes to <paramref name="media"/> entity to database immediately.</param>
        public async Task ApplyBlobAsync(IMediaAware media, MediaStorageItem item, bool save = false)
        {
            Guard.NotNull(media, nameof(media));

            if (item == null)
            {
                media.ApplyBlob(null);
                if (save)
                {
                    await _db.SaveChangesAsync();
                }
                return;
            }

            using (item)
            {
                if (_db.DataProvider.CanStreamBlob)
                {
                    await SaveFast(media, item);
                }
                else
                {
                    // BLOB stream unsupported
                    var buffer = await item.SourceStream.ToByteArrayAsync();

                    media.ApplyBlob(buffer);
                    media.Size = buffer.Length;
                    if (save)
                    {
                        await _db.SaveChangesAsync();
                    }
                }
            }
        }
        public async Task SaveAsync(MediaFile mediaFile, MediaStorageItem item)
        {
            Guard.NotNull(mediaFile, nameof(mediaFile));

            if (item == null)
            {
                mediaFile.ApplyBlob(null);
                await _db.SaveChangesAsync();

                return;
            }

            using (item)
            {
                if (_db.DataProvider.CanStreamBlob)
                {
                    await SaveFast(mediaFile, item);
                }
                else
                {
                    // BLOB stream unsupported
                    var buffer = await item.SourceStream.ToByteArrayAsync();

                    mediaFile.ApplyBlob(buffer);
                    mediaFile.Size = buffer.Length;
                    await _db.SaveChangesAsync();
                }
            }
        }
        public async Task <IActionResult> ProductUpdate(ProductOverviewModel model)
        {
            var product = await _db.Products.FindByIdAsync(model.Id);

            product.Name                      = model.Name;
            product.Sku                       = model.Sku;
            product.Price                     = model.Price;
            product.StockQuantity             = model.StockQuantity;
            product.Published                 = model.Published;
            product.ManufacturerPartNumber    = model.ManufacturerPartNumber;
            product.Gtin                      = model.Gtin;
            product.MinStockQuantity          = model.MinStockQuantity;
            product.OldPrice                  = model.OldPrice;
            product.AvailableStartDateTimeUtc = model.AvailableStartDateTimeUtc;
            product.AvailableEndDateTimeUtc   = model.AvailableEndDateTimeUtc;

            try
            {
                await _db.SaveChangesAsync();

                return(Json(new { success = true }));
            }
            catch (Exception ex)
            {
                NotifyError(ex.GetInnerMessage());
                return(Json(new { success = false }));
            }
        }
Example #5
0
        public virtual Task InsertTaskAsync(TaskDescriptor task)
        {
            Guard.NotNull(task, nameof(task));

            _db.TaskDescriptors.Add(task);
            return(_db.SaveChangesAsync());
        }
Example #6
0
        public async Task MigrateAsync(IEnumerable <SettingEntry> entries)
        {
            Guard.NotNull(entries, nameof(entries));

            if (!entries.Any())
            {
                return;
            }

            var toDelete = new List <Setting>();
            var toAdd    = new List <Setting>();

            using var scope = new DbContextScope(_db, autoDetectChanges: false, minHookImportance: HookImportance.Essential);

            // First perform DELETE actions
            foreach (var entry in entries.Where(x => x.Value == null))
            {
                bool isPattern = entry.KeyIsGroup;
                if (!await HasSettingsAsync(entry.Key, isPattern))
                {
                    continue; // nothing to delete
                }
                var dbSettings = await GetSettingsAsync(entry.Key, isPattern);

                _settings.RemoveRange(dbSettings);
            }

            await _db.SaveChangesAsync();

            // Then perform ADD actions
            foreach (var entry in entries.Where(x => x.Value.HasValue()))
            {
                var existing = toAdd.FirstOrDefault(x => x.Name.Equals(entry.Key, StringComparison.InvariantCultureIgnoreCase));
                if (existing != null)
                {
                    existing.Value = entry.Value;
                    continue;
                }

                if (await HasSettingsAsync(entry.Key, false))
                {
                    continue; // skip existing (we don't perform updates)
                }
                _settings.Add(new Setting
                {
                    Name    = entry.Key,
                    Value   = entry.Value,
                    StoreId = 0
                });
            }

            await _db.SaveChangesAsync();
        }
        public async Task <IActionResult> Delete(QueuedEmailModel model)
        {
            var email = await _db.QueuedEmails.FindByIdAsync(model.Id);

            if (email == null)
            {
                return(RedirectToAction("List"));
            }

            _db.QueuedEmails.Remove(email);
            await _db.SaveChangesAsync();

            NotifySuccess(T("Admin.System.QueuedEmails.Deleted"));
            return(RedirectToAction("List"));
        }
        public async Task <IActionResult> GenericAttributeInsert(GenericAttributeModel model, string entityName, int entityId)
        {
            model.Key   = model.Key.TrimSafe();
            model.Value = model.Value.TrimSafe() ?? string.Empty;

            if (ModelState.IsValid)
            {
                var storeId = Services.StoreContext.CurrentStore.Id;
                var(readPermission, updatePermission) = GetGenericAttributesInfos(entityName);
                if (updatePermission.HasValue() && !Services.Permissions.Authorize(updatePermission))
                {
                    NotifyError(await Services.Permissions.GetUnauthorizedMessageAsync(updatePermission));
                    return(Json(new { success = false }));
                }
                else
                {
                    var attr = await _db.GenericAttributes
                               .Where(x => x.EntityId == entityId && x.KeyGroup == entityName && x.Key == model.Key && x.StoreId == storeId)
                               .FirstOrDefaultAsync();

                    if (attr == null)
                    {
                        _db.GenericAttributes.Add(new GenericAttribute
                        {
                            StoreId  = storeId,
                            KeyGroup = entityName,
                            EntityId = entityId,
                            Key      = model.Key,
                            Value    = model.Value
                        });
                        await _db.SaveChangesAsync();

                        return(Json(new { success = true }));
                    }
                    else
                    {
                        NotifyWarning(T("Admin.Common.GenericAttributes.NameAlreadyExists", model.Key));
                        return(Json(new { success = false }));
                    }
                }
            }
            else
            {
                var modelStateErrorMessages = ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage);
                NotifyError(modelStateErrorMessages.FirstOrDefault());
                return(Json(new { success = false }));
            }
        }
Example #9
0
        public override async Task OnAfterSaveCompletedAsync(IEnumerable <IHookedEntity> entries, CancellationToken cancelToken)
        {
            // Update HasDiscountsApplied property.
            var manufacturers = entries
                                .Select(x => x.Entity)
                                .OfType <Manufacturer>()
                                .ToList();

            foreach (var manufacturersChunk in manufacturers.Slice(100))
            {
                var manufacturerIdsChunk = manufacturersChunk
                                           .Select(x => x.Id)
                                           .ToArray();

                var appliedManufacturerIds = await _db.Discounts
                                             .SelectMany(x => x.AppliedToManufacturers)
                                             .Where(x => manufacturerIdsChunk.Contains(x.Id))
                                             .Select(x => x.Id)
                                             .Distinct()
                                             .ToListAsync(cancelToken);

                manufacturersChunk.Each(x => x.HasDiscountsApplied = appliedManufacturerIds.Contains(x.Id));
            }

            await _db.SaveChangesAsync(cancelToken);

            _requestCache.RemoveByPattern(ManufacturerService.PRODUCTMANUFACTURERS_PATTERN_KEY);
        }
Example #10
0
        public virtual async Task <int> SendNotificationsToSubscribersAsync(Product product)
        {
            Guard.NotNull(product, nameof(product));

            var numberOfMessages  = 0;
            var subscriptionQuery = _db.BackInStockSubscriptions.ApplyStandardFilter(0, product.Id, 0);
            var pager             = new FastPager <BackInStockSubscription>(subscriptionQuery);

            while ((await pager.ReadNextPageAsync <BackInStockSubscription>()).Out(out var subscriptions))
            {
                foreach (var subscription in subscriptions)
                {
                    // Ensure that the customer is registered (simple and fast way).
                    if (subscription?.Customer?.Email?.IsEmail() ?? false)
                    {
                        await _messageFactory.SendBackInStockNotificationAsync(subscription);

                        ++numberOfMessages;
                    }
                }

                _db.BackInStockSubscriptions.RemoveRange(subscriptions);

                await _db.SaveChangesAsync();
            }

            return(numberOfMessages);
        }
Example #11
0
        /// <inheritdoc />
        public override async Task <SignInResult> PasswordSignInAsync(Customer user, string password, bool isPersistent, bool lockoutOnFailure)
        {
            if (user == null || user.Deleted)
            {
                return(SignInResult.Failed);
            }

            if (!user.Active)
            {
                // TODO: (mh) (core) We should return an error message for the user saying "Please check you email account for an activation link".
                return(SignInResult.NotAllowed);
            }

            if (!user.IsRegistered())
            {
                return(SignInResult.NotAllowed);
            }

            var result = await base.PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);

            if (result.Succeeded)
            {
                user.LastLoginDateUtc = DateTime.UtcNow;
                _db.TryUpdate(user);
                await _db.SaveChangesAsync();
            }

            return(result);
        }
        public virtual async Task Run(TaskExecutionContext ctx, CancellationToken cancelToken = default)
        {
            cancelToken.ThrowIfCancellationRequested();

            // Delete all media records which are in transient state since at least 3 hours.
            var olderThan  = DateTime.UtcNow.AddHours(-3);
            var numDeleted = 0;

            using (var scope = new DbContextScope(_db, autoDetectChanges: false, hooksEnabled: false))
            {
                var files = await _db.MediaFiles.Where(x => x.IsTransient && x.UpdatedOnUtc < olderThan).ToListAsync(cancelToken);

                foreach (var file in files)
                {
                    await _mediaService.DeleteFileAsync(file, true);

                    numDeleted += 1;
                }

                await _db.SaveChangesAsync(cancelToken);

                numDeleted += await _db.Downloads.Where(x => x.IsTransient && x.UpdatedOnUtc < olderThan).BatchDeleteAsync(cancelToken);

                if (numDeleted > 0 && _db.DataProvider.CanShrink)
                {
                    try
                    {
                        await _db.DataProvider.ShrinkDatabaseAsync(cancelToken);
                    }
                    catch { }
                }
            }
        }
Example #13
0
        public override async Task OnAfterSaveCompletedAsync(IEnumerable <IHookedEntity> entries, CancellationToken cancelToken)
        {
            // Update HasDiscountsApplied property.
            var categories = entries
                             .Select(x => x.Entity)
                             .OfType <Category>()
                             .ToList();

            foreach (var categoriesChunk in categories.Slice(100))
            {
                var categoryIdsChunk = categoriesChunk
                                       .Select(x => x.Id)
                                       .ToArray();

                var appliedCategoryIds = await _db.Discounts
                                         .SelectMany(x => x.AppliedToCategories)
                                         .Where(x => categoryIdsChunk.Contains(x.Id))
                                         .Select(x => x.Id)
                                         .Distinct()
                                         .ToListAsync();

                categoriesChunk.Each(x => x.HasDiscountsApplied = appliedCategoryIds.Contains(x.Id));
            }

            await _db.SaveChangesAsync();
        }
Example #14
0
        public virtual async Task <bool> SendMailsAsync(IEnumerable <QueuedEmail> queuedEmails, CancellationToken cancelToken = default)
        {
            var result              = false;
            var saveToDisk          = ShouldSaveToDisk();
            var groupedQueuedEmails = queuedEmails.GroupBy(x => x.EmailAccountId);

            foreach (var group in groupedQueuedEmails)
            {
                var account = group.FirstOrDefault().EmailAccount;

                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }

                // Create a new connection for each account in current batch.
                await using (var client = await _mailService.ConnectAsync(account))
                {
                    // Limit email chunks to 100.
                    foreach (var batch in group.Slice(100))
                    {
                        if (cancelToken.IsCancellationRequested)
                        {
                            break;
                        }

                        result = await ProcessMailBatchAsync(batch, client, saveToDisk, cancelToken);

                        await _db.SaveChangesAsync(cancelToken);
                    }
                }
            }

            return(result);
        }
        public async Task Run(TaskExecutionContext ctx, CancellationToken cancelToken = default)
        {
            if (!_currencySettings.AutoUpdateEnabled)
            {
                return;
            }

            var exchangeRates = await _currencyService
                                .GetCurrencyLiveRatesAsync(_storeContext.CurrentStore.PrimaryExchangeRateCurrency.CurrencyCode);

            var currencyCodes = exchangeRates.Select(x => x.CurrencyCode).Distinct().ToArray();
            var currencies    = await _db.Currencies
                                .Where(x => currencyCodes.Contains(x.CurrencyCode))
                                .ToDictionaryAsync(x => x.CurrencyCode, StringComparer.OrdinalIgnoreCase);

            foreach (var exchageRate in exchangeRates)
            {
                if (currencies.TryGetValue(exchageRate.CurrencyCode, out var currency) && currency.Rate != exchageRate.Rate)
                {
                    currency.Rate = exchageRate.Rate;
                }
            }

            await _db.SaveChangesAsync(cancelToken);
        }
        /// <inheritdoc />
        public override async Task <SignInResult> PasswordSignInAsync(Customer user, string password, bool isPersistent, bool lockoutOnFailure)
        {
            if (user == null || user.Deleted)
            {
                return(SignInResult.Failed);
            }

            if (!user.Active)
            {
                return(SignInResult.NotAllowed);
            }

            if (!user.IsRegistered())
            {
                return(SignInResult.NotAllowed);
            }

            var result = await base.PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);

            if (result.Succeeded)
            {
                user.LastLoginDateUtc = DateTime.UtcNow;
                _db.TryUpdate(user);
                await _db.SaveChangesAsync();
            }

            return(result);
        }
Example #17
0
        /// <summary>
        /// Called from migration seeder and only processes product entities without MainPictureId value.
        /// </summary>
        /// <param name="db">Database context.</param>
        /// <returns>The total count of fixed and updated product entities.</returns>
        internal static async Task <int> FixProductMainPictureIds(SmartDbContext db, bool initial, DateTime?ifModifiedSinceUtc = null)
        {
            var query =
                from p in db.Products.AsNoTracking()
                where (!initial || p.MainPictureId == null) && (ifModifiedSinceUtc == null || p.UpdatedOnUtc >= ifModifiedSinceUtc.Value)
                orderby p.Id
                select new { p.Id, p.MainPictureId };

            // Key = ProductId, Value = MainPictureId
            var toUpdate = new Dictionary <int, int?>();

            // 1st pass
            var pageIndex = -1;

            while (true)
            {
                var products = await query.ToPagedList(++pageIndex, 500).LoadAsync();

                var map = await GetPoductPictureMap(db, products.Select(x => x.Id).ToArray());

                foreach (var p in products)
                {
                    int?fixedPictureId = null;
                    if (map.ContainsKey(p.Id))
                    {
                        // Product has still a pic.
                        fixedPictureId = map[p.Id].FirstOrDefault();
                    }

                    // Update only if fixed PictureId differs from current
                    if (fixedPictureId != p.MainPictureId)
                    {
                        toUpdate.Add(p.Id, fixedPictureId);
                    }
                }

                if (!products.HasNextPage)
                {
                    break;
                }
            }

            // 2nd pass.
            foreach (var chunk in toUpdate.Slice(1000))
            {
                using var transaction = await db.Database.BeginTransactionAsync();

                foreach (var kvp in chunk)
                {
                    db.Database.ExecuteSqlRaw("Update Product Set MainPictureId = {0} WHERE Id = {1}", kvp.Value, kvp.Key);
                }

                await db.SaveChangesAsync();

                await transaction.CommitAsync();
            }

            return(toUpdate.Count);
        }
        public async Task <IActionResult> AccountActivation(string token, string email)
        {
            var customer = await _userManager.FindByEmailAsync(email);

            if (customer == null)
            {
                NotifyError(T("Account.AccountActivation.InvalidEmailOrToken"));
                return(RedirectToRoute("Homepage"));
            }

            // Validate token & set user to active.
            var confirmed = await _userManager.ConfirmEmailAsync(customer, token);

            if (!confirmed.Succeeded)
            {
                NotifyError(T("Account.AccountActivation.InvalidEmailOrToken"));
                return(RedirectToRoute("HomePage"));
            }

            // If token wasn't proved invalid by ConfirmEmailAsync() a few lines above, Customer.Active was set to true & AccountActivationToken was resetted in UserStore.
            // So we better save here.
            await _db.SaveChangesAsync();

            // Send welcome message.
            await _messageFactory.SendCustomerWelcomeMessageAsync(customer, Services.WorkContext.WorkingLanguage.Id);

            ViewBag.ActivationResult = T("Account.AccountActivation.Activated");

            return(View());
        }
Example #19
0
        public virtual async Task CancelOrderAsync(Order order, bool notifyCustomer)
        {
            Guard.NotNull(order, nameof(order));

            if (!order.CanCancelOrder())
            {
                throw new SmartException(T("Order.CannotCancel"));
            }

            await SetOrderStatusAsync(order, OrderStatus.Cancelled, notifyCustomer);

            order.AddOrderNote(T("Admin.OrderNotice.OrderCancelled"));

            // Cancel recurring payments.
            var recurringPayments = await _db.RecurringPayments
                                    .ApplyStandardFilter(order.Id)
                                    .ToListAsync();

            foreach (var rp in recurringPayments)
            {
                await CancelRecurringPaymentAsync(rp);
            }

            // Adjust inventory.
            foreach (var orderItem in order.OrderItems)
            {
                await _productService.AdjustInventoryAsync(orderItem, false, orderItem.Quantity);
            }

            await _db.SaveChangesAsync();
        }
        public async Task PublishAsync(ExportDeployment deployment, ExportDeploymentContext context, CancellationToken cancellationToken)
        {
            var emailAddresses = deployment.EmailAddresses
                                 .SplitSafe(",")
                                 .Where(x => x.IsEmail())
                                 .ToArray();

            if (!emailAddresses.Any())
            {
                return;
            }

            var emailAccount = await _db.EmailAccounts.FindByIdAsync(deployment.EmailAccountId, false, cancellationToken);

            var fromEmailAddress = emailAccount.ToMailAddress();
            var files            = await context.GetDeploymentFilesAsync(cancellationToken);

            var canStreamBlob = _db.DataProvider.CanStreamBlob;
            var num           = 0;

            foreach (var emailAddress in emailAddresses)
            {
                var queuedEmail = new QueuedEmail
                {
                    From           = fromEmailAddress,
                    SendManually   = false,
                    To             = emailAddress,
                    Subject        = deployment.EmailSubject.NaIfEmpty(),
                    Body           = deployment.EmailSubject.NaIfEmpty(),
                    CreatedOnUtc   = DateTime.UtcNow,
                    EmailAccountId = deployment.EmailAccountId
                };

                foreach (var file in files)
                {
                    var name       = file.Name;
                    var attachment = new QueuedEmailAttachment
                    {
                        StorageLocation = EmailAttachmentStorageLocation.Blob,
                        Name            = name,
                        MimeType        = MimeTypes.MapNameToMimeType(name)
                    };

                    using var item = MediaStorageItem.FromFile(file);
                    await _dbMediaStorageProvider.ApplyBlobAsync(attachment, item, false);

                    queuedEmail.Attachments.Add(attachment);
                }

                _db.QueuedEmails.Add(queuedEmail);

                // Blob data could be large, so better not bulk commit here.
                num += await _db.SaveChangesAsync(cancellationToken);
            }

            context.Log.Info($"{num} email(s) created and queued for deployment.");
        }
Example #21
0
        public override async Task OnAfterSaveCompletedAsync(IEnumerable <IHookedEntity> entries, CancellationToken cancelToken)
        {
            // Update HasDiscountsApplied property.
            var categories = entries
                             .Select(x => x.Entity)
                             .OfType <Category>()
                             .ToList();

            foreach (var categoriesChunk in categories.Slice(100))
            {
                var categoryIdsChunk = categoriesChunk
                                       .Select(x => x.Id)
                                       .ToArray();

                var appliedCategoryIds = await _db.Discounts
                                         .SelectMany(x => x.AppliedToCategories)
                                         .Where(x => categoryIdsChunk.Contains(x.Id))
                                         .Select(x => x.Id)
                                         .Distinct()
                                         .ToListAsync(cancelToken);

                categoriesChunk.Each(x => x.HasDiscountsApplied = appliedCategoryIds.Contains(x.Id));
            }

            await _db.SaveChangesAsync(cancelToken);

            // Validate category hierarchy.
            var invalidCategoryIds = new HashSet <int>();
            var modifiedCategories = entries
                                     .Where(x => x.InitialState == Smartstore.Data.EntityState.Modified)
                                     .Select(x => x.Entity)
                                     .OfType <Category>()
                                     .ToList();

            foreach (var category in modifiedCategories)
            {
                var valid = await IsValidCategoryHierarchy(category.Id, category.ParentCategoryId, cancelToken);

                if (!valid)
                {
                    invalidCategoryIds.Add(category.Id);
                }
            }

            if (invalidCategoryIds.Any())
            {
                var num = await _db.Categories
                          .Where(x => invalidCategoryIds.Contains(x.Id))
                          .BatchUpdateAsync(x => new Category {
                    ParentCategoryId = 0
                }, cancelToken);
            }

            _requestCache.RemoveByPattern(CategoryService.CATEGORIES_PATTERN_KEY);
            _requestCache.RemoveByPattern(CategoryService.PRODUCTCATEGORIES_PATTERN_KEY);
        }
Example #22
0
        public async Task <IActionResult> Create(StoreModel model, bool continueEditing)
        {
            if (ModelState.IsValid)
            {
                var store = await MapperFactory.MapAsync <StoreModel, Store>(model);

                // Ensure we have "/" at the end.
                store.Url = store.Url.EnsureEndsWith("/");
                _db.Stores.Add(store);
                await _db.SaveChangesAsync();

                NotifySuccess(T("Admin.Configuration.Stores.Added"));
                return(continueEditing ? RedirectToAction("Edit", new { id = store.Id }) : RedirectToAction("List"));
            }

            await PrepareStoreModelAsync(model, null);

            return(View(model));
        }
        /// <summary>
        /// Imports all template xml files to <see cref="MessageTemplate"/> table.
        /// </summary>
        /// <param name="virtualRootPath">The virtual root path of templates to import, e.g. "~/Modules/MyModule/EmailTemplates". Default is "~/App_Data/EmailTemplates".</param>
        public async Task ImportAllAsync(Language language, string virtualRootPath = null)
        {
            var sourceTemplates = LoadAll(language, virtualRootPath);
            var dbTemplatesMap  = (await _db.MessageTemplates
                                   .ToListAsync())
                                  .ToMultimap(x => x.Name, x => x, StringComparer.OrdinalIgnoreCase);

            foreach (var source in sourceTemplates)
            {
                if (dbTemplatesMap.ContainsKey(source.Name))
                {
                    foreach (var target in dbTemplatesMap[source.Name])
                    {
                        if (source.To.HasValue())
                        {
                            target.To = source.To;
                        }
                        if (source.ReplyTo.HasValue())
                        {
                            target.ReplyTo = source.ReplyTo;
                        }
                        if (source.Subject.HasValue())
                        {
                            target.Subject = source.Subject;
                        }
                        if (source.ModelTypes.HasValue())
                        {
                            target.ModelTypes = source.ModelTypes;
                        }
                        if (source.Body.HasValue())
                        {
                            target.Body = source.Body;
                        }
                    }
                }
                else
                {
                    var template = new MessageTemplate
                    {
                        Name           = source.Name,
                        To             = source.To,
                        ReplyTo        = source.ReplyTo,
                        Subject        = source.Subject,
                        ModelTypes     = source.ModelTypes,
                        Body           = source.Body,
                        IsActive       = true,
                        EmailAccountId = (_defaultEmailAccount?.Id).GetValueOrDefault(),
                    };

                    _db.MessageTemplates.Add(template);
                }
            }

            await _db.SaveChangesAsync();
        }
Example #24
0
        public async Task <IActionResult> Create(TopicModel model, bool continueEditing)
        {
            if (ModelState.IsValid)
            {
                if (!model.IsPasswordProtected)
                {
                    model.Password = null;
                }

                // TODO: (mh) (core) Implement & use mapping extensions.
                var topic = await MapperFactory.MapAsync <TopicModel, Topic>(model);

                if (model.WidgetZone != null)
                {
                    topic.WidgetZone = string.Join(',', model.WidgetZone);
                }

                topic.CookieType = (CookieType?)model.CookieType;

                _db.Topics.Add(topic);
                await _db.SaveChangesAsync();

                var slugResult = await topic.ValidateSlugAsync(model.SeName, true);

                model.SeName = slugResult.Slug;
                await _urlService.ApplySlugAsync(slugResult, true);

                await SaveStoreMappingsAsync(topic, model.SelectedStoreIds);
                await SaveAclMappingsAsync(topic, model.SelectedCustomerRoleIds);
                await UpdateLocalesAsync(topic, model);

                AddCookieTypes(model, model.CookieType);

                await Services.EventPublisher.PublishAsync(new ModelBoundEvent(model, topic, Request.Form));

                NotifySuccess(T("Admin.ContentManagement.Topics.Updated"));
                return(continueEditing ? RedirectToAction("Edit", new { id = topic.Id }) : RedirectToAction("List"));
            }

            // If we got this far something failed. Redisplay form.
            return(View(model));
        }
Example #25
0
        protected virtual async Task AddItemToCartAsync(AddToCartContext ctx)
        {
            if (ctx.Item != null)
            {
                ctx.Customer.ShoppingCartItems.Add(ctx.Item);

                if (!ctx.ChildItems.IsNullOrEmpty())
                {
                    foreach (var childItem in ctx.ChildItems)
                    {
                        childItem.ParentItemId = ctx.Item.Id;
                    }

                    ctx.Customer.ShoppingCartItems.AddRange(ctx.ChildItems);
                }

                _db.TryUpdate(ctx.Customer);
                await _db.SaveChangesAsync();
            }
        }
Example #26
0
        public async Task <IActionResult> Category(int categoryId, CatalogSearchQuery query)
        {
            var category = await _db.Categories.FindByIdAsync(categoryId, false);

            if (category == null || category.Deleted)
            {
                return(NotFound());
            }

            // Check whether the current user has a "Manage catalog" permission.
            // It allows him to preview a category before publishing.
            if (!category.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Category.Read))
            {
                return(NotFound());
            }

            // ACL (access control list).
            if (!await _aclService.AuthorizeAsync(category))
            {
                return(NotFound());
            }

            // Store mapping.
            if (!await _storeMappingService.AuthorizeAsync(category))
            {
                return(NotFound());
            }

            var customer = Services.WorkContext.CurrentCustomer;

            // 'Continue shopping' URL.
            if (!customer.IsSystemAccount)
            {
                customer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false);
                await _db.SaveChangesAsync();
            }

            // TODO: (mh) (core) Continue CatalogController.Category()

            return(Content($"Category --> Id: {category.Id}, Name: {category.Name}"));
        }
Example #27
0
        public async Task <IActionResult> ChangeStoreScopeConfiguration(int storeid, string returnUrl = "")
        {
            var store = Services.StoreContext.GetStoreById(storeid);

            if (store != null || storeid == 0)
            {
                Services.WorkContext.CurrentCustomer.GenericAttributes.AdminAreaStoreScopeConfiguration = storeid;
                await _db.SaveChangesAsync();
            }

            return(RedirectToReferrer(returnUrl, () => RedirectToAction("Index", "Home", new { area = "Admin" })));
        }
Example #28
0
        public Task InsertTaskAsync(ITaskDescriptor task)
        {
            Guard.IsTypeOf <TaskDescriptor>(task);

            _db.TaskDescriptors.Add((TaskDescriptor)task);
            return(_db.SaveChangesAsync());
        }
        protected virtual async Task AddItemToCartAsync(AddToCartContext ctx)
        {
            Guard.NotNull(ctx, nameof(ctx));
            Guard.NotNull(ctx.Item, nameof(ctx.Item));

            var customer = ctx.Customer ?? _workContext.CurrentCustomer;

            customer.ShoppingCartItems.Add(ctx.Item);

            if (ctx.ChildItems.Any())
            {
                foreach (var childItem in ctx.ChildItems)
                {
                    childItem.ParentItemId = ctx.Item.Id;
                }

                customer.ShoppingCartItems.AddRange(ctx.ChildItems);
            }

            _db.TryUpdate(customer);
            await _db.SaveChangesAsync();
        }
Example #30
0
        public virtual async Task <Customer> CreateGuestCustomerAsync(Guid?customerGuid = null)
        {
            var customer = new Customer
            {
                CustomerGuid        = customerGuid ?? Guid.NewGuid(),
                Active              = true,
                CreatedOnUtc        = DateTime.UtcNow,
                LastActivityDateUtc = DateTime.UtcNow,
            };

            // Add to 'Guests' role
            var guestRole = await GetRoleBySystemNameAsync(SystemCustomerRoleNames.Guests);

            if (guestRole == null)
            {
                throw new SmartException("'Guests' role could not be loaded");
            }

            // Ensure that entities are saved to db in any case
            customer.CustomerRoleMappings.Add(new CustomerRoleMapping {
                CustomerId = customer.Id, CustomerRoleId = guestRole.Id
            });
            _db.Customers.Add(customer);

            await _db.SaveChangesAsync();

            var clientIdent = _webHelper.GetClientIdent();

            if (clientIdent.HasValue())
            {
                customer.GenericAttributes.ClientIdent = clientIdent;
                await _db.SaveChangesAsync();
            }

            //Logger.DebugFormat("Guest account created for anonymous visitor. Id: {0}, ClientIdent: {1}", customer.CustomerGuid, clientIdent ?? "n/a");

            return(customer);
        }