public static int DeleteAll <T>(this IRepository <T> rs, Expression <Func <T, bool> > predicate = null, bool cascade = false) where T : BaseEntity { var count = 0; using (var scope = new DbContextScope(ctx: rs.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false, autoCommit: false)) { var query = rs.Table; if (predicate != null) { query = query.Where(predicate); } if (cascade) { var records = query.ToList(); foreach (var chunk in records.Slice(500)) { rs.DeleteRange(chunk.ToList()); count += rs.Context.SaveChanges(); } } else { var ids = query.Select(x => new { Id = x.Id }).ToList(); foreach (var chunk in ids.Slice(500)) { rs.DeleteRange(chunk.Select(x => x.Id)); count += rs.Context.SaveChanges(); } } } return(count); }
public void CalculateFutureSchedules(IEnumerable<ScheduleTask> tasks, bool isAppStart = false) { Guard.ArgumentNotNull(() => tasks); using (var scope = new DbContextScope(autoCommit: false)) { var now = DateTime.UtcNow; foreach (var task in tasks) { task.NextRunUtc = GetNextSchedule(task); if (isAppStart) { task.ProgressPercent = null; task.ProgressMessage = null; if (task.LastEndUtc.GetValueOrDefault() < task.LastStartUtc) { task.LastEndUtc = task.LastStartUtc; task.LastError = T("Admin.System.ScheduleTasks.AbnormalAbort"); } } this.UpdateTask(task); } scope.Commit(); } }
public void Migrate(IEnumerable<SettingEntry> entries) { Guard.ArgumentNotNull(() => entries); if (!entries.Any()) return; using (var scope = new DbContextScope(_ctx, autoDetectChanges: false)) { var toDelete = new List<Setting>(); var toAdd = new List<Setting>(); // First perform DELETE actions foreach (var entry in entries.Where(x => x.Value == null)) { bool isPattern = entry.KeyIsGroup; if (!HasSettings(entry.Key, isPattern)) continue; // nothing to delete var db = GetSettings(entry.Key, isPattern); _settings.RemoveRange(db); } _ctx.SaveChanges(); // 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 (HasSettings(entry.Key, false)) continue; // skip existing (we don't perform updates) _settings.Add(new Setting { Name = entry.Key, Value = entry.Value, StoreId = 0 }); } _ctx.SaveChanges(); } }
public void Generate(UrlHelper urlHelper, Stream stream) { using (var scope = new DbContextScope(autoDetectChanges: false, forceNoTracking: true)) { _writer = new XmlTextWriter(stream, Encoding.UTF8); _writer.Formatting = Formatting.Indented; _writer.WriteStartDocument(); _writer.WriteStartElement("urlset"); _writer.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"); _writer.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); _writer.WriteAttributeString("xsi:schemaLocation", "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"); GenerateUrlNodes(urlHelper); _writer.WriteEndElement(); _writer.Close(); } }
public void Execute(TaskExecutionContext ctx) { // delete all media records which are in transient state since at least 3 hours var olderThan = DateTime.UtcNow.AddHours(-3); // delete Downloads _downloadRepository.DeleteAll(x => x.IsTransient && x.UpdatedOnUtc < olderThan); // delete Pictures var autoCommit = _pictureRepository.AutoCommitEnabled; _pictureRepository.AutoCommitEnabled = false; try { using (var scope = new DbContextScope(autoDetectChanges: false, validateOnSave: false, hooksEnabled: false)) { var pictures = _pictureRepository.Where(x => x.IsTransient && x.UpdatedOnUtc < olderThan).ToList(); foreach (var picture in pictures) { _pictureService.DeletePicture(picture); } _pictureRepository.Context.SaveChanges(); if (DataSettings.Current.IsSqlServer) { try { _pictureRepository.Context.ExecuteSqlCommand("DBCC SHRINKDATABASE(0)", true); } catch { } } } } finally { _pictureRepository.AutoCommitEnabled = autoCommit; } }
public virtual void DeleteThemeVariables(string themeName, int storeId) { Guard.ArgumentNotEmpty(themeName, "themeName"); var query = from v in _rsVariables.Table where v.StoreId == storeId && v.Theme.Equals(themeName, StringComparison.OrdinalIgnoreCase) select v; if (query.Any()) { using (var scope = new DbContextScope(ctx: _rsVariables.Context, autoCommit: false)) { query.Each(v => { _rsVariables.Delete(v); _eventPublisher.EntityDeleted(v); }); _cacheManager.Remove(THEMEVARS_BY_THEME_KEY.FormatInvariant(themeName, storeId)); _rsVariables.Context.SaveChanges(); } } }
public virtual IEnumerable<WidgetRouteInfo> GetWidgets(string widgetZone, object model) { string actionName; string controllerName; RouteValueDictionary routeValues; var storeId = _storeContext.CurrentStore.Id; #region Plugin Widgets var widgets = _widgetService.LoadActiveWidgetsByWidgetZone(widgetZone, storeId); foreach (var widget in widgets) { widget.Value.GetDisplayWidgetRoute(widgetZone, model, storeId, out actionName, out controllerName, out routeValues); if (actionName.HasValue() && controllerName.HasValue()) { yield return new WidgetRouteInfo { ActionName = actionName, ControllerName = controllerName, RouteValues = routeValues }; } } #endregion #region Topic Widgets // add special "topic widgets" to the list var allTopicsCacheKey = string.Format(ModelCacheEventConsumer.TOPIC_WIDGET_ALL_MODEL_KEY, storeId, _workContext.WorkingLanguage.Id); // get topic widgets from STATIC cache var topicWidgets = _services.Cache.Get(allTopicsCacheKey, () => { using (var scope = new DbContextScope(forceNoTracking: true)) { var allTopicWidgets = _topicService.GetAllTopics(storeId).Where(x => x.RenderAsWidget).ToList(); var stubs = allTopicWidgets .Select(t => new TopicWidgetStub { Id = t.Id, Bordered = t.WidgetBordered, WrapContent = !t.WidgetWrapContent.HasValue || t.WidgetWrapContent.Value, ShowTitle = t.WidgetShowTitle, SystemName = t.SystemName.SanitizeHtmlId(), Title = t.GetLocalized(x => t.Title), TitleTag = t.TitleTag, Body = t.GetLocalized(x => t.Body), WidgetZones = t.GetWidgetZones().ToArray(), Priority = t.Priority }) .OrderBy(t => t.Priority) .ToList(); return stubs; } }); var byZoneTopicsCacheKey = "SmartStore.TopicWidgets.ZoneMapped"; // save widgets to zones map in request cache var topicsByZone = _cacheManager.Get(byZoneTopicsCacheKey, () => { var map = new Multimap<string, WidgetRouteInfo>(); foreach (var widget in topicWidgets) { var zones = widget.WidgetZones; if (zones != null && zones.Any()) { foreach (var zone in zones.Select(x => x.ToLower())) { var routeInfo = new WidgetRouteInfo { ControllerName = "Topic", ActionName = "TopicWidget", RouteValues = new RouteValueDictionary() { {"Namespaces", "SmartStore.Web.Controllers"}, {"area", null}, {"widgetZone", zone}, {"model", new TopicWidgetModel { Id = widget.Id, SystemName = widget.SystemName, WrapContent = widget.WrapContent, ShowTitle = widget.ShowTitle, IsBordered = widget.Bordered, Title = String.IsNullOrEmpty(widget.Title) ? "div" : widget.Title, TitleTag = widget.TitleTag ?? "h3", Html = widget.Body } } } }; map.Add(zone, routeInfo); } } } return map; #region Obsolete //var result = from t in topicWidgets // where t.WidgetZones.Contains(widgetZone, StringComparer.InvariantCultureIgnoreCase) // orderby t.Priority // select new WidgetRouteInfo // { // ControllerName = "Topic", // ActionName = "TopicWidget", // RouteValues = new RouteValueDictionary() // { // {"Namespaces", "SmartStore.Web.Controllers"}, // {"area", null}, // {"widgetZone", widgetZone}, // {"model", new TopicWidgetModel // { // Id = t.Id, // SystemName = t.SystemName, // ShowTitle = t.ShowTitle, // IsBordered = t.Bordered, // Title = t.Title, // Html = t.Body // } } // } // }; //return result.ToList(); #endregion }); if (topicsByZone.ContainsKey(widgetZone.ToLower())) { var zoneWidgets = topicsByZone[widgetZone.ToLower()]; foreach (var topicWidget in zoneWidgets) { yield return topicWidget; } } #endregion #region Request scoped widgets (provided by IWidgetProvider) var requestScopedWidgets = _widgetProvider.GetWidgets(widgetZone); if (requestScopedWidgets != null) { foreach (var widget in requestScopedWidgets) { yield return widget; } } #endregion }
public void Flush() { if (_entries.Count == 0) return; string ipAddress = ""; string pageUrl = ""; string referrerUrl = ""; var currentCustomer = _workContext.CurrentCustomer; try { ipAddress = _webHelper.GetCurrentIpAddress(); pageUrl = _webHelper.GetThisPageUrl(true); referrerUrl = _webHelper.GetUrlReferrer(); } catch { } using (var scope = new DbContextScope(autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { foreach (var context in _entries) { if (context.ShortMessage.IsEmpty() && context.FullMessage.IsEmpty()) continue; Log log = null; try { string shortMessage = context.ShortMessage.NaIfEmpty(); string fullMessage = context.FullMessage.EmptyNull(); string contentHash = null; if (context.HashNotFullMessage || context.HashIpAddress) { contentHash = (shortMessage + (context.HashNotFullMessage ? "" : fullMessage) + (context.HashIpAddress ? ipAddress.EmptyNull() : "") ).Hash(Encoding.Unicode, true); } else { contentHash = (shortMessage + fullMessage).Hash(Encoding.Unicode, true); } log = _logRepository.Table.OrderByDescending(x => x.CreatedOnUtc).FirstOrDefault(x => x.ContentHash == contentHash); if (log == null) { log = new Log { Frequency = 1, LogLevel = context.LogLevel, ShortMessage = shortMessage, FullMessage = fullMessage, IpAddress = ipAddress, Customer = context.Customer ?? currentCustomer, PageUrl = pageUrl, ReferrerUrl = referrerUrl, CreatedOnUtc = DateTime.UtcNow, ContentHash = contentHash }; _logRepository.Insert(log); } else { if (log.Frequency < 2147483647) log.Frequency = log.Frequency + 1; log.LogLevel = context.LogLevel; log.IpAddress = ipAddress; log.Customer = context.Customer ?? currentCustomer; log.PageUrl = pageUrl; log.ReferrerUrl = referrerUrl; log.UpdatedOnUtc = DateTime.UtcNow; _logRepository.Update(log); } } catch (Exception ex) { ex.Dump(); } } try { // FIRE! _logRepository.Context.SaveChanges(); } catch { } } _entries.Clear(); }
public ActionResult EntityPicker(EntityPickerModel model, FormCollection form) { model.PageSize = 48; // _commonSettings.EntityPickerPageSize; model.PublishedString = T("Common.Published"); model.UnpublishedString = T("Common.Unpublished"); try { var disableIf = model.DisableIf.SplitSafe(",").Select(x => x.ToLower().Trim()).ToList(); var disableIds = model.DisableIds.SplitSafe(",").Select(x => x.ToInt()).ToList(); using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, proxyCreation: true, validateOnSave: false, forceNoTracking: true)) { if (model.Entity.IsCaseInsensitiveEqual("product")) { #region Product model.SearchTerm = model.ProductName.TrimSafe(); var hasPermission = _services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog); var storeLocation = _services.WebHelper.GetStoreLocation(false); var disableIfNotSimpleProduct = disableIf.Contains("notsimpleproduct"); var labelTextGrouped = T("Admin.Catalog.Products.ProductType.GroupedProduct.Label").Text; var labelTextBundled = T("Admin.Catalog.Products.ProductType.BundledProduct.Label").Text; var sku = T("Products.Sku").Text; var searchContext = new ProductSearchContext { CategoryIds = (model.CategoryId == 0 ? null : new List<int> { model.CategoryId }), ManufacturerId = model.ManufacturerId, StoreId = model.StoreId, Keywords = model.SearchTerm, ProductType = model.ProductTypeId > 0 ? (ProductType?)model.ProductTypeId : null, SearchSku = !_catalogSettings.SuppressSkuSearch, ShowHidden = hasPermission }; var query = _productService.Value.PrepareProductSearchQuery(searchContext, x => new { x.Id, x.Sku, x.Name, x.Published, x.ProductTypeId }); query = from x in query group x by x.Id into grp orderby grp.Key select grp.FirstOrDefault(); var products = query .OrderBy(x => x.Name) .Skip(model.PageIndex * model.PageSize) .Take(model.PageSize) .ToList(); var productIds = products.Select(x => x.Id).ToArray(); var pictures = _productService.Value.GetProductPicturesByProductIds(productIds, true); model.SearchResult = products .Select(x => { var item = new EntityPickerModel.SearchResultModel { Id = x.Id, ReturnValue = (model.ReturnField.IsCaseInsensitiveEqual("sku") ? x.Sku : x.Id.ToString()), Title = x.Name, Summary = x.Sku, SummaryTitle = "{0}: {1}".FormatInvariant(sku, x.Sku.NaIfEmpty()), Published = (hasPermission ? x.Published : (bool?)null) }; if (disableIfNotSimpleProduct) { item.Disable = (x.ProductTypeId != (int)ProductType.SimpleProduct); } if (!item.Disable && disableIds.Contains(x.Id)) { item.Disable = true; } if (x.ProductTypeId == (int)ProductType.GroupedProduct) { item.LabelText = labelTextGrouped; item.LabelClassName = "label-success"; } else if (x.ProductTypeId == (int)ProductType.BundledProduct) { item.LabelText = labelTextBundled; item.LabelClassName = "label-info"; } var productPicture = pictures.FirstOrDefault(y => y.Key == x.Id); if (productPicture.Value != null) { var picture = productPicture.Value.FirstOrDefault(); if (picture != null) { item.ImageUrl = _pictureService.Value.GetPictureUrl(picture.Picture, _mediaSettings.Value.ProductThumbPictureSizeOnProductDetailsPage, !_catalogSettings.HideProductDefaultPictures, storeLocation); } } return item; }) .ToList(); #endregion } } } catch (Exception exception) { NotifyError(exception.ToAllMessages()); } return PartialView("EntityPickerList", model); }
public ActionResult PdfPackagingSlips(bool all, string selectedIds = null) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) return AccessDeniedView(); if (!all && selectedIds.IsEmpty()) { NotifyInfo(_localizationService.GetResource("Admin.Common.ExportNoData")); return RedirectToReferrer(); } IList<Shipment> shipments; using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, forceNoTracking: true)) { if (all) { shipments = _shipmentService.GetAllShipments(null, null, null, 0, int.MaxValue); } else { var ids = selectedIds.ToIntArray(); shipments = _shipmentService.GetShipmentsByIds(ids); } } if (shipments.Count == 0) { NotifyInfo(_localizationService.GetResource("Admin.Common.ExportNoData")); return RedirectToReferrer(); } if (shipments.Count > 500) { NotifyWarning(_localizationService.GetResource("Admin.Common.ExportToPdf.TooManyItems")); return RedirectToReferrer(); } string pdfFileName = "PackagingSlips.pdf"; if (shipments.Count == 1) { pdfFileName = "PackagingSlip-{0}.pdf".FormatInvariant(shipments[0].Id); } var model = shipments.Select(x => PrepareShipmentModel(x, true, true)).ToList(); // TODO: (mc) this is bad for multi-document processing, where orders can originate from different stores. var storeId = model[0].StoreId; var routeValues = new RouteValueDictionary(new { storeId = storeId, area = "" }); var pdfSettings = _services.Settings.LoadSetting<PdfSettings>(storeId); var settings = new PdfConvertSettings { Size = pdfSettings.LetterPageSizeEnabled ? PdfPageSize.Letter : PdfPageSize.A4, Margins = new PdfPageMargins { Top = 35, Bottom = 35 }, Page = new PdfViewContent("ShipmentDetails.Print", model, this.ControllerContext), Header = new PdfRouteContent("PdfReceiptHeader", "Common", routeValues, this.ControllerContext), Footer = new PdfRouteContent("PdfReceiptFooter", "Common", routeValues, this.ControllerContext) }; return new PdfResult(_pdfConverter, settings) { FileName = pdfFileName }; }
public ImportResult ImportSubscribers(Stream stream) { Guard.ArgumentNotNull(() => stream); var result = new ImportResult(); var toAdd = new List<NewsLetterSubscription>(); var toUpdate = new List<NewsLetterSubscription>(); using (var scope = new DbContextScope(ctx: _context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { using (var reader = new StreamReader(stream)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.IsEmpty()) { continue; } string[] tmp = line.Split(','); var email = ""; bool isActive = true; int storeId = 0; // parse if (tmp.Length == 1) { // "email" only email = tmp[0].Trim(); } else if (tmp.Length == 2) { // "email" and "active" fields specified email = tmp[0].Trim(); isActive = Boolean.Parse(tmp[1].Trim()); } else if (tmp.Length == 3) { email = tmp[0].Trim(); isActive = Boolean.Parse(tmp[1].Trim()); storeId = int.Parse(tmp[2].Trim()); } else { throw new SmartException("Wrong file format (expected comma separated entries 'Email' and optionally 'IsActive')"); } result.TotalRecords++; if (email.Length > 255) { result.AddWarning("The emal address '{0}' exceeds the maximun allowed length of 255.".FormatInvariant(email)); continue; } if (!email.IsEmail()) { result.AddWarning("'{0}' is not a valid email address.".FormatInvariant(email)); continue; } if (storeId == 0) { storeId = _storeService.GetAllStores().First().Id; } // import var subscription = (from nls in _subscriptionRepository.Table where nls.Email == email && nls.StoreId == storeId orderby nls.Id select nls).FirstOrDefault(); if (subscription != null) { subscription.Active = isActive; toUpdate.Add(subscription); result.ModifiedRecords++; } else { subscription = new NewsLetterSubscription { Active = isActive, CreatedOnUtc = DateTime.UtcNow, Email = email, NewsLetterSubscriptionGuid = Guid.NewGuid(), StoreId = storeId }; toAdd.Add(subscription); result.NewRecords++; } } } // insert new subscribers _subscriptionRepository.AutoCommitEnabled = true; _subscriptionRepository.InsertRange(toAdd, 500); toAdd.Clear(); // update modified subscribers _subscriptionRepository.AutoCommitEnabled = null; toUpdate.Each(x => { _subscriptionRepository.Update(x); }); _subscriptionRepository.Context.SaveChanges(); toUpdate.Clear(); } return result; }
/// <summary> /// Create a copy of product with all depended data /// </summary> /// <param name="product">The product</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>Product entity</returns> public virtual Product CopyProduct(Product product, string newName, bool isPublished, bool copyImages, bool copyAssociatedProducts = true) { if (product == null) throw new ArgumentNullException("product"); if (String.IsNullOrEmpty(newName)) throw new ArgumentException("Product name is required"); Product productCopy = null; var utcNow = DateTime.UtcNow; // product download & sample download int downloadId = 0; int? sampleDownloadId = null; if (product.IsDownload) { var download = _downloadService.GetDownloadById(product.DownloadId); if (download != null) { var downloadCopy = new Download { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = download.UseDownloadUrl, DownloadUrl = download.DownloadUrl, DownloadBinary = download.DownloadBinary, ContentType = download.ContentType, Filename = download.Filename, Extension = download.Extension, IsNew = download.IsNew, }; _downloadService.InsertDownload(downloadCopy); downloadId = downloadCopy.Id; } if (product.HasSampleDownload) { var sampleDownload = _downloadService.GetDownloadById(product.SampleDownloadId.GetValueOrDefault()); if (sampleDownload != null) { var sampleDownloadCopy = new Download { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = sampleDownload.UseDownloadUrl, DownloadUrl = sampleDownload.DownloadUrl, DownloadBinary = sampleDownload.DownloadBinary, ContentType = sampleDownload.ContentType, Filename = sampleDownload.Filename, Extension = sampleDownload.Extension, IsNew = sampleDownload.IsNew }; _downloadService.InsertDownload(sampleDownloadCopy); sampleDownloadId = sampleDownloadCopy.Id; } } } // product productCopy = new Product { ProductTypeId = product.ProductTypeId, ParentGroupedProductId = product.ParentGroupedProductId, VisibleIndividually = product.VisibleIndividually, Name = newName, ShortDescription = product.ShortDescription, FullDescription = product.FullDescription, ProductTemplateId = product.ProductTemplateId, AdminComment = product.AdminComment, ShowOnHomePage = product.ShowOnHomePage, HomePageDisplayOrder = product.HomePageDisplayOrder, MetaKeywords = product.MetaKeywords, MetaDescription = product.MetaDescription, MetaTitle = product.MetaTitle, AllowCustomerReviews = product.AllowCustomerReviews, LimitedToStores = product.LimitedToStores, Sku = product.Sku, ManufacturerPartNumber = product.ManufacturerPartNumber, Gtin = product.Gtin, IsGiftCard = product.IsGiftCard, GiftCardType = product.GiftCardType, RequireOtherProducts = product.RequireOtherProducts, RequiredProductIds = product.RequiredProductIds, AutomaticallyAddRequiredProducts = product.AutomaticallyAddRequiredProducts, IsDownload = product.IsDownload, DownloadId = downloadId, UnlimitedDownloads = product.UnlimitedDownloads, MaxNumberOfDownloads = product.MaxNumberOfDownloads, DownloadExpirationDays = product.DownloadExpirationDays, DownloadActivationType = product.DownloadActivationType, HasSampleDownload = product.HasSampleDownload, SampleDownloadId = sampleDownloadId, HasUserAgreement = product.HasUserAgreement, UserAgreementText = product.UserAgreementText, IsRecurring = product.IsRecurring, RecurringCycleLength = product.RecurringCycleLength, RecurringCyclePeriod = product.RecurringCyclePeriod, RecurringTotalCycles = product.RecurringTotalCycles, IsShipEnabled = product.IsShipEnabled, IsFreeShipping = product.IsFreeShipping, AdditionalShippingCharge = product.AdditionalShippingCharge, IsEsd = product.IsEsd, IsTaxExempt = product.IsTaxExempt, TaxCategoryId = product.TaxCategoryId, ManageInventoryMethod = product.ManageInventoryMethod, StockQuantity = product.StockQuantity, DisplayStockAvailability = product.DisplayStockAvailability, DisplayStockQuantity = product.DisplayStockQuantity, MinStockQuantity = product.MinStockQuantity, LowStockActivityId = product.LowStockActivityId, NotifyAdminForQuantityBelow = product.NotifyAdminForQuantityBelow, BackorderMode = product.BackorderMode, AllowBackInStockSubscriptions = product.AllowBackInStockSubscriptions, OrderMinimumQuantity = product.OrderMinimumQuantity, OrderMaximumQuantity = product.OrderMaximumQuantity, AllowedQuantities = product.AllowedQuantities, DisableBuyButton = product.DisableBuyButton, DisableWishlistButton = product.DisableWishlistButton, AvailableForPreOrder = product.AvailableForPreOrder, CallForPrice = product.CallForPrice, Price = product.Price, OldPrice = product.OldPrice, ProductCost = product.ProductCost, SpecialPrice = product.SpecialPrice, SpecialPriceStartDateTimeUtc = product.SpecialPriceStartDateTimeUtc, SpecialPriceEndDateTimeUtc = product.SpecialPriceEndDateTimeUtc, CustomerEntersPrice = product.CustomerEntersPrice, MinimumCustomerEnteredPrice = product.MinimumCustomerEnteredPrice, MaximumCustomerEnteredPrice = product.MaximumCustomerEnteredPrice, LowestAttributeCombinationPrice = product.LowestAttributeCombinationPrice, Weight = product.Weight, Length = product.Length, Width = product.Width, Height = product.Height, AvailableStartDateTimeUtc = product.AvailableStartDateTimeUtc, AvailableEndDateTimeUtc = product.AvailableEndDateTimeUtc, DisplayOrder = product.DisplayOrder, Published = isPublished, Deleted = product.Deleted, CreatedOnUtc = utcNow, UpdatedOnUtc = utcNow, DeliveryTimeId = product.DeliveryTimeId, QuantityUnitId = product.QuantityUnitId, BasePriceEnabled = product.BasePriceEnabled, BasePriceMeasureUnit = product.BasePriceMeasureUnit, BasePriceAmount = product.BasePriceAmount, BasePriceBaseAmount = product.BasePriceBaseAmount, BundleTitleText = product.BundleTitleText, BundlePerItemShipping = product.BundlePerItemShipping, BundlePerItemPricing = product.BundlePerItemPricing, BundlePerItemShoppingCart = product.BundlePerItemShoppingCart }; _productService.InsertProduct(productCopy); //search engine name _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", productCopy.Name, true), 0); var languages = _languageService.GetAllLanguages(true); //localization foreach (var lang in languages) { var name = product.GetLocalized(x => x.Name, lang.Id, false, false); if (!String.IsNullOrEmpty(name)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.Name, name, lang.Id); var shortDescription = product.GetLocalized(x => x.ShortDescription, lang.Id, false, false); if (!String.IsNullOrEmpty(shortDescription)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.ShortDescription, shortDescription, lang.Id); var fullDescription = product.GetLocalized(x => x.FullDescription, lang.Id, false, false); if (!String.IsNullOrEmpty(fullDescription)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.FullDescription, fullDescription, lang.Id); var metaKeywords = product.GetLocalized(x => x.MetaKeywords, lang.Id, false, false); if (!String.IsNullOrEmpty(metaKeywords)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaKeywords, metaKeywords, lang.Id); var metaDescription = product.GetLocalized(x => x.MetaDescription, lang.Id, false, false); if (!String.IsNullOrEmpty(metaDescription)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaDescription, metaDescription, lang.Id); var metaTitle = product.GetLocalized(x => x.MetaTitle, lang.Id, false, false); if (!String.IsNullOrEmpty(metaTitle)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaTitle, metaTitle, lang.Id); var bundleTitleText = product.GetLocalized(x => x.BundleTitleText, lang.Id, false, false); if (!String.IsNullOrEmpty(bundleTitleText)) _localizedEntityService.SaveLocalizedValue(productCopy, x => x.BundleTitleText, bundleTitleText, lang.Id); //search engine name _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", name, false), lang.Id); } // product pictures if (copyImages) { foreach (var productPicture in product.ProductPictures) { var picture = productPicture.Picture; var pictureCopy = _pictureService.InsertPicture( _pictureService.LoadPictureBinary(picture), picture.MimeType, _pictureService.GetPictureSeName(newName), true, false, false); _productService.InsertProductPicture(new ProductPicture { ProductId = productCopy.Id, PictureId = pictureCopy.Id, DisplayOrder = productPicture.DisplayOrder }); } } // product <-> categories mappings foreach (var productCategory in product.ProductCategories) { var productCategoryCopy = new ProductCategory { ProductId = productCopy.Id, CategoryId = productCategory.CategoryId, IsFeaturedProduct = productCategory.IsFeaturedProduct, DisplayOrder = productCategory.DisplayOrder }; _categoryService.InsertProductCategory(productCategoryCopy); } // product <-> manufacturers mappings foreach (var productManufacturers in product.ProductManufacturers) { var productManufacturerCopy = new ProductManufacturer { ProductId = productCopy.Id, ManufacturerId = productManufacturers.ManufacturerId, IsFeaturedProduct = productManufacturers.IsFeaturedProduct, DisplayOrder = productManufacturers.DisplayOrder }; _manufacturerService.InsertProductManufacturer(productManufacturerCopy); } // product <-> releated products mappings foreach (var relatedProduct in _productService.GetRelatedProductsByProductId1(product.Id, true)) { _productService.InsertRelatedProduct(new RelatedProduct { ProductId1 = productCopy.Id, ProductId2 = relatedProduct.ProductId2, DisplayOrder = relatedProduct.DisplayOrder }); } // product <-> cross sells mappings foreach (var csProduct in _productService.GetCrossSellProductsByProductId1(product.Id, true)) { _productService.InsertCrossSellProduct(new CrossSellProduct { ProductId1 = productCopy.Id, ProductId2 = csProduct.ProductId2, }); } // product specifications foreach (var productSpecificationAttribute in product.ProductSpecificationAttributes) { var psaCopy = new ProductSpecificationAttribute { ProductId = productCopy.Id, SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId, AllowFiltering = productSpecificationAttribute.AllowFiltering, ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage, DisplayOrder = productSpecificationAttribute.DisplayOrder }; _specificationAttributeService.InsertProductSpecificationAttribute(psaCopy); } //store mapping var selectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(product); foreach (var id in selectedStoreIds) { _storeMappingService.InsertStoreMapping(productCopy, id); } // product <-> attributes mappings var associatedAttributes = new Dictionary<int, int>(); var associatedAttributeValues = new Dictionary<int, int>(); foreach (var productVariantAttribute in _productAttributeService.GetProductVariantAttributesByProductId(product.Id)) { var productVariantAttributeCopy = new ProductVariantAttribute { ProductId = productCopy.Id, ProductAttributeId = productVariantAttribute.ProductAttributeId, TextPrompt = productVariantAttribute.TextPrompt, IsRequired = productVariantAttribute.IsRequired, AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId, DisplayOrder = productVariantAttribute.DisplayOrder }; _productAttributeService.InsertProductVariantAttribute(productVariantAttributeCopy); //save associated value (used for combinations copying) associatedAttributes.Add(productVariantAttribute.Id, productVariantAttributeCopy.Id); // product variant attribute values var productVariantAttributeValues = _productAttributeService.GetProductVariantAttributeValues(productVariantAttribute.Id); foreach (var productVariantAttributeValue in productVariantAttributeValues) { var pvavCopy = new ProductVariantAttributeValue { ProductVariantAttributeId = productVariantAttributeCopy.Id, Name = productVariantAttributeValue.Name, ColorSquaresRgb = productVariantAttributeValue.ColorSquaresRgb, PriceAdjustment = productVariantAttributeValue.PriceAdjustment, WeightAdjustment = productVariantAttributeValue.WeightAdjustment, IsPreSelected = productVariantAttributeValue.IsPreSelected, DisplayOrder = productVariantAttributeValue.DisplayOrder, ValueTypeId = productVariantAttributeValue.ValueTypeId, LinkedProductId = productVariantAttributeValue.LinkedProductId, Quantity = productVariantAttributeValue.Quantity, }; _productAttributeService.InsertProductVariantAttributeValue(pvavCopy); //save associated value (used for combinations copying) associatedAttributeValues.Add(productVariantAttributeValue.Id, pvavCopy.Id); //localization foreach (var lang in languages) { var name = productVariantAttributeValue.GetLocalized(x => x.Name, lang.Id, false, false); if (!String.IsNullOrEmpty(name)) _localizedEntityService.SaveLocalizedValue(pvavCopy, x => x.Name, name, lang.Id); } } } // attribute combinations using (var scope = new DbContextScope(lazyLoading: false, forceNoTracking: false)) { scope.LoadCollection(product, (Product p) => p.ProductVariantAttributeCombinations); } foreach (var combination in product.ProductVariantAttributeCombinations) { //generate new AttributesXml according to new value IDs string newAttributesXml = ""; var parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml); foreach (var oldPva in parsedProductVariantAttributes) { if (associatedAttributes.ContainsKey(oldPva.Id)) { int newPvaId = associatedAttributes[oldPva.Id]; var newPva = _productAttributeService.GetProductVariantAttributeById(newPvaId); if (newPva != null) { var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id); foreach (var oldPvaValueStr in oldPvaValuesStr) { if (newPva.ShouldHaveValues()) { //attribute values int oldPvaValue = int.Parse(oldPvaValueStr); if (associatedAttributeValues.ContainsKey(oldPvaValue)) { int newPvavId = associatedAttributeValues[oldPvaValue]; var newPvav = _productAttributeService.GetProductVariantAttributeValueById(newPvavId); if (newPvav != null) { newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, newPvav.Id.ToString()); } } } else { //just a text newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, oldPvaValueStr); } } } } } var combinationCopy = new ProductVariantAttributeCombination { ProductId = productCopy.Id, AttributesXml = newAttributesXml, StockQuantity = combination.StockQuantity, AllowOutOfStockOrders = combination.AllowOutOfStockOrders, // SmartStore extension Sku = combination.Sku, Gtin = combination.Gtin, ManufacturerPartNumber = combination.ManufacturerPartNumber, Price = combination.Price, AssignedPictureIds = copyImages ? combination.AssignedPictureIds : null, Length = combination.Length, Width = combination.Width, Height = combination.Height, BasePriceAmount = combination.BasePriceAmount, BasePriceBaseAmount = combination.BasePriceBaseAmount, DeliveryTimeId = combination.DeliveryTimeId, QuantityUnitId = combination.QuantityUnitId, IsActive = combination.IsActive //IsDefaultCombination = combination.IsDefaultCombination }; _productAttributeService.InsertProductVariantAttributeCombination(combinationCopy); } // tier prices foreach (var tierPrice in product.TierPrices) { _productService.InsertTierPrice(new TierPrice { ProductId = productCopy.Id, StoreId = tierPrice.StoreId, CustomerRoleId = tierPrice.CustomerRoleId, Quantity = tierPrice.Quantity, Price = tierPrice.Price }); } // product <-> discounts mapping foreach (var discount in product.AppliedDiscounts) { productCopy.AppliedDiscounts.Add(discount); _productService.UpdateProduct(productCopy); } // update "HasTierPrices" and "HasDiscountsApplied" properties _productService.UpdateHasTierPricesProperty(productCopy); _productService.UpdateLowestAttributeCombinationPriceProperty(productCopy); _productService.UpdateHasDiscountsApplied(productCopy); // associated products if (copyAssociatedProducts && product.ProductType != ProductType.BundledProduct) { var searchContext = new ProductSearchContext { OrderBy = ProductSortingEnum.Position, ParentGroupedProductId = product.Id, PageSize = int.MaxValue, ShowHidden = true }; string copyOf = _localizationService.GetResource("Admin.Common.CopyOf"); var associatedProducts = _productService.SearchProducts(searchContext); foreach (var associatedProduct in associatedProducts) { var associatedProductCopy = CopyProduct(associatedProduct, string.Format("{0} {1}", copyOf, associatedProduct.Name), isPublished, copyImages, false); associatedProductCopy.ParentGroupedProductId = productCopy.Id; _productService.UpdateProduct(productCopy); } } // bundled products var bundledItems = _productService.GetBundleItems(product.Id, true); foreach (var bundleItem in bundledItems) { var newBundleItem = bundleItem.Item.Clone(); newBundleItem.BundleProductId = productCopy.Id; newBundleItem.CreatedOnUtc = utcNow; newBundleItem.UpdatedOnUtc = utcNow; _productService.InsertBundleItem(newBundleItem); foreach (var itemFilter in bundleItem.Item.AttributeFilters) { var newItemFilter = itemFilter.Clone(); newItemFilter.BundleItemId = newBundleItem.Id; _productAttributeService.InsertProductBundleItemAttributeFilter(newItemFilter); } } return productCopy; }
public virtual int SaveThemeVariables(string themeName, int storeId, IDictionary<string, object> variables) { Guard.ArgumentNotEmpty(themeName, "themeName"); Guard.Against<ArgumentException>(!_themeRegistry.ThemeManifestExists(themeName), "The theme '{0}' does not exist in the registry.".FormatInvariant(themeName)); Guard.ArgumentNotNull(variables, "variables"); if (!variables.Any()) return 0; var count = 0; var infos = _themeRegistry.GetThemeManifest(themeName).Variables; using (var scope = new DbContextScope(ctx: _rsVariables.Context, autoCommit: false)) { var unsavedVars = new List<string>(); var savedThemeVars = _rsVariables.Table.Where(v => v.StoreId == storeId && v.Theme.Equals(themeName, StringComparison.OrdinalIgnoreCase)).ToList(); bool touched = false; foreach (var v in variables) { ThemeVariableInfo info; if (!infos.TryGetValue(v.Key, out info)) { // var not specified in metadata so don't save // TODO: (MC) delete from db also if it exists continue; } var value = v.Value == null ? string.Empty : v.Value.ToString(); var savedThemeVar = savedThemeVars.FirstOrDefault(x => x.Name == v.Key); if (savedThemeVar != null) { if (value.IsEmpty() || String.Equals(info.DefaultValue, value, StringComparison.CurrentCultureIgnoreCase)) { // it's either null or the default value, so delete _rsVariables.Delete(savedThemeVar); _eventPublisher.EntityDeleted(savedThemeVar); touched = true; count++; } else { // update entity if (!savedThemeVar.Value.Equals(value, StringComparison.OrdinalIgnoreCase)) { savedThemeVar.Value = value; _eventPublisher.EntityUpdated(savedThemeVar); touched = true; count++; } } } else { if (value.HasValue() && !String.Equals(info.DefaultValue, value, StringComparison.CurrentCultureIgnoreCase)) { // insert entity (only when not default value) unsavedVars.Add(v.Key); savedThemeVar = new ThemeVariable { Theme = themeName, Name = v.Key, Value = value, StoreId = storeId }; _rsVariables.Insert(savedThemeVar); _eventPublisher.EntityInserted(savedThemeVar); touched = true; count++; } } } if (touched) { _rsVariables.Context.SaveChanges(); } } return count; }
public virtual void InheritStoresIntoChildren(int categoryId, bool touchProductsWithMultipleCategories = false, bool touchExistingAcls = false, bool categoriesOnly = false) { var category = GetCategoryById(categoryId); var subcategories = GetAllCategoriesByParentCategoryId(categoryId, true); var context = new ProductSearchContext { PageSize = int.MaxValue , ShowHidden = true }; context.CategoryIds.AddRange(subcategories.Select(x => x.Id)); context.CategoryIds.Add(categoryId); var products = _productService.SearchProducts(context); var allStores = _storeService.GetAllStores(); var categoryStoreMappings = _storeMappingService.GetStoresIdsWithAccess(category); using (var scope = new DbContextScope(ctx: _storeMappingRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { _storeMappingRepository.AutoCommitEnabled = false; foreach (var subcategory in subcategories) { if (subcategory.LimitedToStores != category.LimitedToStores) { subcategory.LimitedToStores = category.LimitedToStores; _categoryRepository.Update(subcategory); } var existingStoreMappingsRecords = _storeMappingService.GetStoreMappings(subcategory).ToDictionary(x => x.StoreId); foreach (var store in allStores) { if (categoryStoreMappings.Contains(store.Id)) { if (!existingStoreMappingsRecords.ContainsKey(store.Id)) { _storeMappingRepository.Insert(new StoreMapping { StoreId = store.Id, EntityId = subcategory.Id, EntityName = "Category" }); } } else { StoreMapping storeMappingToDelete; if (existingStoreMappingsRecords.TryGetValue(store.Id, out storeMappingToDelete)) { _storeMappingRepository.Delete(storeMappingToDelete); } } } } _storeMappingRepository.Context.SaveChanges(); foreach (var product in products) { if (product.LimitedToStores != category.LimitedToStores) { product.LimitedToStores = category.LimitedToStores; _productRepository.Update(product); } var existingStoreMappingsRecords = _storeMappingService.GetStoreMappings(product).ToDictionary(x => x.StoreId); foreach (var store in allStores) { if (categoryStoreMappings.Contains(store.Id)) { if (!existingStoreMappingsRecords.ContainsKey(store.Id)) { _storeMappingRepository.Insert(new StoreMapping { StoreId = store.Id, EntityId = product.Id, EntityName = "Product" }); } } else { StoreMapping storeMappingToDelete; if (existingStoreMappingsRecords.TryGetValue(store.Id, out storeMappingToDelete)) { _storeMappingRepository.Delete(storeMappingToDelete); } } } } _storeMappingRepository.Context.SaveChanges(); } }
/// <summary> /// Writes a single product /// </summary> /// <param name="writer">The XML writer</param> /// <param name="product">The product</param> /// <param name="context">Context objects</param> public virtual void WriteProductToXml(XmlWriter writer, Product product, XmlExportContext context) { var culture = CultureInfo.InvariantCulture; var productTemplate = context.ProductTemplates.FirstOrDefault(x => x.Id == product.ProductTemplateId); writer.Write("Id", product.Id.ToString()); writer.Write("Name", product.Name); writer.Write("SeName", product.GetSeName(0, true, false)); writer.Write("ShortDescription", product.ShortDescription, null, true); writer.Write("FullDescription", product.FullDescription, null, true); writer.Write("AdminComment", product.AdminComment); writer.Write("ProductTemplateId", product.ProductTemplateId.ToString()); writer.Write("ProductTemplateViewPath", productTemplate == null ? "" : productTemplate.ViewPath); writer.Write("ShowOnHomePage", product.ShowOnHomePage.ToString()); writer.Write("HomePageDisplayOrder", product.HomePageDisplayOrder.ToString()); writer.Write("MetaKeywords", product.MetaKeywords); writer.Write("MetaDescription", product.MetaDescription); writer.Write("MetaTitle", product.MetaTitle); writer.Write("AllowCustomerReviews", product.AllowCustomerReviews.ToString()); writer.Write("ApprovedRatingSum", product.ApprovedRatingSum.ToString()); writer.Write("NotApprovedRatingSum", product.NotApprovedRatingSum.ToString()); writer.Write("ApprovedTotalReviews", product.ApprovedTotalReviews.ToString()); writer.Write("NotApprovedTotalReviews", product.NotApprovedTotalReviews.ToString()); writer.Write("Published", product.Published.ToString()); writer.Write("CreatedOnUtc", product.CreatedOnUtc.ToString(culture)); writer.Write("UpdatedOnUtc", product.UpdatedOnUtc.ToString(culture)); writer.Write("SubjectToAcl", product.SubjectToAcl.ToString()); writer.Write("LimitedToStores", product.LimitedToStores.ToString()); writer.Write("ProductTypeId", product.ProductTypeId.ToString()); writer.Write("ParentGroupedProductId", product.ParentGroupedProductId.ToString()); writer.Write("Sku", product.Sku); writer.Write("ManufacturerPartNumber", product.ManufacturerPartNumber); writer.Write("Gtin", product.Gtin); writer.Write("IsGiftCard", product.IsGiftCard.ToString()); writer.Write("GiftCardTypeId", product.GiftCardTypeId.ToString()); writer.Write("RequireOtherProducts", product.RequireOtherProducts.ToString()); writer.Write("RequiredProductIds", product.RequiredProductIds); writer.Write("AutomaticallyAddRequiredProducts", product.AutomaticallyAddRequiredProducts.ToString()); writer.Write("IsDownload", product.IsDownload.ToString()); writer.Write("DownloadId", product.DownloadId.ToString()); writer.Write("UnlimitedDownloads", product.UnlimitedDownloads.ToString()); writer.Write("MaxNumberOfDownloads", product.MaxNumberOfDownloads.ToString()); writer.Write("DownloadExpirationDays", product.DownloadExpirationDays.HasValue ? product.DownloadExpirationDays.ToString() : ""); writer.Write("DownloadActivationType", product.DownloadActivationType.ToString()); writer.Write("HasSampleDownload", product.HasSampleDownload.ToString()); writer.Write("SampleDownloadId", product.SampleDownloadId.ToString()); writer.Write("HasUserAgreement", product.HasUserAgreement.ToString()); writer.Write("UserAgreementText", product.UserAgreementText); writer.Write("IsRecurring", product.IsRecurring.ToString()); writer.Write("RecurringCycleLength", product.RecurringCycleLength.ToString()); writer.Write("RecurringCyclePeriodId", product.RecurringCyclePeriodId.ToString()); writer.Write("RecurringTotalCycles", product.RecurringTotalCycles.ToString()); writer.Write("IsShipEnabled", product.IsShipEnabled.ToString()); writer.Write("IsFreeShipping", product.IsFreeShipping.ToString()); writer.Write("AdditionalShippingCharge", product.AdditionalShippingCharge.ToString(culture)); writer.Write("IsTaxExempt", product.IsTaxExempt.ToString()); writer.Write("TaxCategoryId", product.TaxCategoryId.ToString()); writer.Write("ManageInventoryMethodId", product.ManageInventoryMethodId.ToString()); writer.Write("StockQuantity", product.StockQuantity.ToString()); writer.Write("DisplayStockAvailability", product.DisplayStockAvailability.ToString()); writer.Write("DisplayStockQuantity", product.DisplayStockQuantity.ToString()); writer.Write("MinStockQuantity", product.MinStockQuantity.ToString()); writer.Write("LowStockActivityId", product.LowStockActivityId.ToString()); writer.Write("NotifyAdminForQuantityBelow", product.NotifyAdminForQuantityBelow.ToString()); writer.Write("BackorderModeId", product.BackorderModeId.ToString()); writer.Write("AllowBackInStockSubscriptions", product.AllowBackInStockSubscriptions.ToString()); writer.Write("OrderMinimumQuantity", product.OrderMinimumQuantity.ToString()); writer.Write("OrderMaximumQuantity", product.OrderMaximumQuantity.ToString()); writer.Write("AllowedQuantities", product.AllowedQuantities); writer.Write("DisableBuyButton", product.DisableBuyButton.ToString()); writer.Write("DisableWishlistButton", product.DisableWishlistButton.ToString()); writer.Write("AvailableForPreOrder", product.AvailableForPreOrder.ToString()); writer.Write("CallForPrice", product.CallForPrice.ToString()); writer.Write("Price", product.Price.ToString(culture)); writer.Write("OldPrice", product.OldPrice.ToString(culture)); writer.Write("ProductCost", product.ProductCost.ToString(culture)); writer.Write("SpecialPrice", product.SpecialPrice.HasValue ? product.SpecialPrice.Value.ToString(culture) : ""); writer.Write("SpecialPriceStartDateTimeUtc", product.SpecialPriceStartDateTimeUtc.HasValue ? product.SpecialPriceStartDateTimeUtc.Value.ToString(culture) : ""); writer.Write("SpecialPriceEndDateTimeUtc", product.SpecialPriceEndDateTimeUtc.HasValue ? product.SpecialPriceEndDateTimeUtc.Value.ToString(culture) : ""); writer.Write("CustomerEntersPrice", product.CustomerEntersPrice.ToString()); writer.Write("MinimumCustomerEnteredPrice", product.MinimumCustomerEnteredPrice.ToString(culture)); writer.Write("MaximumCustomerEnteredPrice", product.MaximumCustomerEnteredPrice.ToString(culture)); writer.Write("HasTierPrices", product.HasTierPrices.ToString()); writer.Write("HasDiscountsApplied", product.HasDiscountsApplied.ToString()); writer.Write("Weight", product.Weight.ToString(culture)); writer.Write("Length", product.Length.ToString(culture)); writer.Write("Width", product.Width.ToString(culture)); writer.Write("Height", product.Height.ToString(culture)); writer.Write("AvailableStartDateTimeUtc", product.AvailableStartDateTimeUtc.HasValue ? product.AvailableStartDateTimeUtc.Value.ToString(culture) : ""); writer.Write("AvailableEndDateTimeUtc", product.AvailableEndDateTimeUtc.HasValue ? product.AvailableEndDateTimeUtc.Value.ToString(culture) : ""); writer.Write("BasePriceEnabled", product.BasePriceEnabled.ToString()); writer.Write("BasePriceMeasureUnit", product.BasePriceMeasureUnit); writer.Write("BasePriceAmount", product.BasePriceAmount.HasValue ? product.BasePriceAmount.Value.ToString(culture) : ""); writer.Write("BasePriceBaseAmount", product.BasePriceBaseAmount.HasValue ? product.BasePriceBaseAmount.Value.ToString() : ""); writer.Write("VisibleIndividually", product.VisibleIndividually.ToString()); writer.Write("DisplayOrder", product.DisplayOrder.ToString()); writer.Write("BundleTitleText", product.BundleTitleText); writer.Write("BundlePerItemPricing", product.BundlePerItemPricing.ToString()); writer.Write("BundlePerItemShipping", product.BundlePerItemShipping.ToString()); writer.Write("BundlePerItemShoppingCart", product.BundlePerItemShoppingCart.ToString()); writer.Write("LowestAttributeCombinationPrice", product.LowestAttributeCombinationPrice.HasValue ? product.LowestAttributeCombinationPrice.Value.ToString(culture) : ""); writer.Write("IsEsd", product.IsEsd.ToString()); WriteLocalized(writer, context, lang => { writer.Write("Name", product.GetLocalized(x => x.Name, lang.Id, false, false), lang); writer.Write("SeName", product.GetSeName(lang.Id, false, false), lang); writer.Write("ShortDescription", product.GetLocalized(x => x.ShortDescription, lang.Id, false, false), lang, true); writer.Write("FullDescription", product.GetLocalized(x => x.FullDescription, lang.Id, false, false), lang, true); writer.Write("MetaKeywords", product.GetLocalized(x => x.MetaKeywords, lang.Id, false, false), lang); writer.Write("MetaDescription", product.GetLocalized(x => x.MetaDescription, lang.Id, false, false), lang); writer.Write("MetaTitle", product.GetLocalized(x => x.MetaTitle, lang.Id, false, false), lang); writer.Write("BundleTitleText", product.GetLocalized(x => x.BundleTitleText, lang.Id, false, false), lang); }); if (product.DeliveryTime != null) { writer.WriteStartElement("DeliveryTime"); writer.Write("Id", product.DeliveryTime.Id.ToString()); writer.Write("Name", product.DeliveryTime.Name); writer.Write("DisplayLocale", product.DeliveryTime.DisplayLocale); writer.Write("ColorHexValue", product.DeliveryTime.ColorHexValue); writer.Write("DisplayOrder", product.DeliveryTime.DisplayOrder.ToString()); WriteLocalized(writer, context, lang => { writer.Write("Name", product.DeliveryTime.GetLocalized(x => x.Name, lang.Id, false, false), lang); }); writer.WriteEndElement(); } WriteQuantityUnit(writer, context, product.QuantityUnit); writer.WriteStartElement("ProductTags"); foreach (var tag in product.ProductTags) { writer.WriteStartElement("ProductTag"); writer.Write("Id", tag.Id.ToString()); writer.Write("Name", tag.Name); WriteLocalized(writer, context, lang => { writer.Write("Name", tag.GetLocalized(x => x.Name, lang.Id, false, false), lang); }); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("ProductDiscounts"); foreach (var discount in product.AppliedDiscounts) { writer.WriteStartElement("ProductDiscount"); writer.Write("DiscountId", discount.Id.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("TierPrices"); foreach (var tierPrice in product.TierPrices) { writer.WriteStartElement("TierPrice"); writer.Write("Id", tierPrice.Id.ToString()); writer.Write("StoreId", tierPrice.StoreId.ToString()); writer.Write("CustomerRoleId", tierPrice.CustomerRoleId.HasValue ? tierPrice.CustomerRoleId.ToString() : "0"); writer.Write("Quantity", tierPrice.Quantity.ToString()); writer.Write("Price", tierPrice.Price.ToString(culture)); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("ProductAttributes"); foreach (var pva in product.ProductVariantAttributes.OrderBy(x => x.DisplayOrder)) { writer.WriteStartElement("ProductAttribute"); writer.Write("Id", pva.Id.ToString()); writer.Write("TextPrompt", pva.TextPrompt); writer.Write("IsRequired", pva.IsRequired.ToString()); writer.Write("AttributeControlTypeId", pva.AttributeControlTypeId.ToString()); writer.Write("DisplayOrder", pva.DisplayOrder.ToString()); writer.WriteStartElement("Attribute"); writer.Write("Id", pva.ProductAttribute.Id.ToString()); writer.Write("Alias", pva.ProductAttribute.Alias); writer.Write("Name", pva.ProductAttribute.Name); writer.Write("Description", pva.ProductAttribute.Description); WriteLocalized(writer, context, lang => { writer.Write("Name", pva.ProductAttribute.GetLocalized(x => x.Name, lang.Id, false, false), lang); writer.Write("Description", pva.ProductAttribute.GetLocalized(x => x.Description, lang.Id, false, false), lang); }); writer.WriteEndElement(); // Attribute writer.WriteStartElement("AttributeValues"); foreach (var value in pva.ProductVariantAttributeValues.OrderBy(x => x.DisplayOrder)) { writer.WriteStartElement("AttributeValue"); writer.Write("Id", value.Id.ToString()); writer.Write("Alias", value.Alias); writer.Write("Name", value.Name); writer.Write("ColorSquaresRgb", value.ColorSquaresRgb); writer.Write("PriceAdjustment", value.PriceAdjustment.ToString(culture)); writer.Write("WeightAdjustment", value.WeightAdjustment.ToString(culture)); writer.Write("IsPreSelected", value.IsPreSelected.ToString()); writer.Write("DisplayOrder", value.DisplayOrder.ToString()); writer.Write("ValueTypeId", value.ValueTypeId.ToString()); writer.Write("LinkedProductId", value.LinkedProductId.ToString()); writer.Write("Quantity", value.Quantity.ToString()); WriteLocalized(writer, context, lang => { writer.Write("Name", value.GetLocalized(x => x.Name, lang.Id, false, false), lang); }); writer.WriteEndElement(); // AttributeValue } writer.WriteEndElement(); // AttributeValues writer.WriteEndElement(); // ProductAttribute } writer.WriteEndElement(); // ProductAttributes using (var scope = new DbContextScope(proxyCreation: false, forceNoTracking: true)) { var allCombinations = product.ProductVariantAttributeCombinations; writer.WriteStartElement("ProductAttributeCombinations"); foreach (var combination in allCombinations) { writer.WriteStartElement("ProductAttributeCombination"); writer.Write("Id", combination.Id.ToString()); writer.Write("StockQuantity", combination.StockQuantity.ToString()); writer.Write("AllowOutOfStockOrders", combination.AllowOutOfStockOrders.ToString()); writer.Write("AttributesXml", combination.AttributesXml, null, true); writer.Write("Sku", combination.Sku); writer.Write("Gtin", combination.Gtin); writer.Write("ManufacturerPartNumber", combination.ManufacturerPartNumber); writer.Write("Price", combination.Price.HasValue ? combination.Price.Value.ToString(culture) : ""); writer.Write("Length", combination.Length.HasValue ? combination.Length.Value.ToString(culture) : ""); writer.Write("Width", combination.Width.HasValue ? combination.Width.Value.ToString(culture) : ""); writer.Write("Height", combination.Height.HasValue ? combination.Height.Value.ToString(culture) : ""); writer.Write("BasePriceAmount", combination.BasePriceAmount.HasValue ? combination.BasePriceAmount.Value.ToString(culture) : ""); writer.Write("BasePriceBaseAmount", combination.BasePriceBaseAmount.HasValue ? combination.BasePriceBaseAmount.Value.ToString() : ""); writer.Write("DeliveryTimeId", combination.DeliveryTimeId.HasValue ? combination.DeliveryTimeId.Value.ToString() : ""); writer.Write("IsActive", combination.IsActive.ToString()); WriteQuantityUnit(writer, context, combination.QuantityUnit); writer.WriteStartElement("Pictures"); foreach (int pictureId in combination.GetAssignedPictureIds()) { WritePicture(writer, context, _pictureService.GetPictureById(pictureId), _mediaSettings.ProductThumbPictureSize, _mediaSettings.ProductDetailsPictureSize); } writer.WriteEndElement(); // Pictures writer.WriteEndElement(); // ProductAttributeCombination } writer.WriteEndElement(); // ProductAttributeCombinations } writer.WriteStartElement("ProductPictures"); foreach (var productPicture in product.ProductPictures.OrderBy(x => x.DisplayOrder)) { writer.WriteStartElement("ProductPicture"); writer.Write("Id", productPicture.Id.ToString()); writer.Write("DisplayOrder", productPicture.DisplayOrder.ToString()); WritePicture(writer, context, productPicture.Picture, _mediaSettings.ProductThumbPictureSize, _mediaSettings.ProductDetailsPictureSize); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("ProductCategories"); var productCategories = _categoryService.GetProductCategoriesByProductId(product.Id); if (productCategories != null) { foreach (var productCategory in productCategories.OrderBy(x => x.DisplayOrder)) { var category = productCategory.Category; writer.WriteStartElement("ProductCategory"); writer.Write("IsFeaturedProduct", productCategory.IsFeaturedProduct.ToString()); writer.Write("DisplayOrder", productCategory.DisplayOrder.ToString()); writer.WriteStartElement("Category"); writer.Write("Id", category.Id.ToString()); writer.Write("Name", category.Name); writer.Write("FullName", category.FullName); writer.Write("Description", category.Description); writer.Write("BottomDescription", category.BottomDescription); writer.Write("CategoryTemplateId", category.CategoryTemplateId.ToString()); writer.Write("MetaKeywords", category.MetaKeywords); writer.Write("MetaDescription", category.MetaDescription); writer.Write("MetaTitle", category.MetaTitle); writer.Write("SeName", category.GetSeName(0)); writer.Write("ParentCategoryId", category.ParentCategoryId.ToString()); writer.Write("PageSize", category.PageSize.ToString()); writer.Write("AllowCustomersToSelectPageSize", category.AllowCustomersToSelectPageSize.ToString()); writer.Write("PageSizeOptions", category.PageSizeOptions); writer.Write("PriceRanges", category.PriceRanges); writer.Write("ShowOnHomePage", category.ShowOnHomePage.ToString()); writer.Write("HasDiscountsApplied", category.HasDiscountsApplied.ToString()); writer.Write("Published", category.Published.ToString()); writer.Write("Deleted", category.Deleted.ToString()); writer.Write("DisplayOrder", category.DisplayOrder.ToString()); writer.Write("CreatedOnUtc", category.CreatedOnUtc.ToString(culture)); writer.Write("UpdatedOnUtc", category.UpdatedOnUtc.ToString(culture)); writer.Write("SubjectToAcl", category.SubjectToAcl.ToString()); writer.Write("LimitedToStores", category.LimitedToStores.ToString()); writer.Write("Alias", category.Alias); writer.Write("DefaultViewMode", category.DefaultViewMode); WritePicture(writer, context, category.Picture, _mediaSettings.CategoryThumbPictureSize, _mediaSettings.CategoryThumbPictureSize); WriteLocalized(writer, context, lang => { writer.Write("Name", category.GetLocalized(x => x.Name, lang.Id, false, false), lang); writer.Write("FullName", category.GetLocalized(x => x.FullName, lang.Id, false, false), lang); writer.Write("Description", category.GetLocalized(x => x.Description, lang.Id, false, false), lang); writer.Write("BottomDescription", category.GetLocalized(x => x.BottomDescription, lang.Id, false, false), lang); writer.Write("MetaKeywords", category.GetLocalized(x => x.MetaKeywords, lang.Id, false, false), lang); writer.Write("MetaDescription", category.GetLocalized(x => x.MetaDescription, lang.Id, false, false), lang); writer.Write("MetaTitle", category.GetLocalized(x => x.MetaTitle, lang.Id, false, false), lang); writer.Write("SeName", category.GetSeName(lang.Id, false, false)); }); writer.WriteEndElement(); writer.WriteEndElement(); } } writer.WriteEndElement(); writer.WriteStartElement("ProductManufacturers"); var productManufacturers = _manufacturerService.GetProductManufacturersByProductId(product.Id); if (productManufacturers != null) { foreach (var productManufacturer in productManufacturers.OrderBy(x => x.DisplayOrder)) { var manu = productManufacturer.Manufacturer; writer.WriteStartElement("ProductManufacturer"); writer.Write("Id", productManufacturer.Id.ToString()); writer.Write("IsFeaturedProduct", productManufacturer.IsFeaturedProduct.ToString()); writer.Write("DisplayOrder", productManufacturer.DisplayOrder.ToString()); writer.WriteStartElement("Manufacturer"); writer.Write("Id", manu.Id.ToString()); writer.Write("Name", manu.Name); writer.Write("SeName", manu.GetSeName(0, true, false)); writer.Write("Description", manu.Description); writer.Write("MetaKeywords", manu.MetaKeywords); writer.Write("MetaDescription", manu.MetaDescription); writer.Write("MetaTitle", manu.MetaTitle); WritePicture(writer, context, manu.Picture, _mediaSettings.ManufacturerThumbPictureSize, _mediaSettings.ManufacturerThumbPictureSize); WriteLocalized(writer, context, lang => { writer.Write("Name", manu.GetLocalized(x => x.Name, lang.Id, false, false), lang); writer.Write("SeName", manu.GetSeName(lang.Id, false, false), lang); writer.Write("Description", manu.GetLocalized(x => x.Description, lang.Id, false, false), lang); writer.Write("MetaKeywords", manu.GetLocalized(x => x.MetaKeywords, lang.Id, false, false), lang); writer.Write("MetaDescription", manu.GetLocalized(x => x.MetaDescription, lang.Id, false, false), lang); writer.Write("MetaTitle", manu.GetLocalized(x => x.MetaTitle, lang.Id, false, false), lang); }); writer.WriteEndElement(); writer.WriteEndElement(); } } writer.WriteEndElement(); writer.WriteStartElement("ProductSpecificationAttributes"); foreach (var pca in product.ProductSpecificationAttributes.OrderBy(x => x.DisplayOrder)) { writer.WriteStartElement("ProductSpecificationAttribute"); writer.Write("Id", pca.Id.ToString()); writer.Write("AllowFiltering", pca.AllowFiltering.ToString()); writer.Write("ShowOnProductPage", pca.ShowOnProductPage.ToString()); writer.Write("DisplayOrder", pca.DisplayOrder.ToString()); writer.WriteStartElement("SpecificationAttributeOption"); writer.Write("Id", pca.SpecificationAttributeOption.Id.ToString()); writer.Write("DisplayOrder", pca.SpecificationAttributeOption.DisplayOrder.ToString()); writer.Write("Name", pca.SpecificationAttributeOption.Name); WriteLocalized(writer, context, lang => { writer.Write("Name", pca.SpecificationAttributeOption.GetLocalized(x => x.Name, lang.Id, false, false), lang); }); writer.WriteStartElement("SpecificationAttribute"); writer.Write("Id", pca.SpecificationAttributeOption.SpecificationAttribute.Id.ToString()); writer.Write("DisplayOrder", pca.SpecificationAttributeOption.SpecificationAttribute.DisplayOrder.ToString()); writer.Write("Name", pca.SpecificationAttributeOption.SpecificationAttribute.Name); WriteLocalized(writer, context, lang => { writer.Write("Name", pca.SpecificationAttributeOption.SpecificationAttribute.GetLocalized(x => x.Name, lang.Id, false, false), lang); }); writer.WriteEndElement(); // SpecificationAttribute writer.WriteEndElement(); // SpecificationAttributeOption writer.WriteEndElement(); // ProductSpecificationAttribute } writer.WriteEndElement(); writer.WriteStartElement("ProductBundleItems"); var bundleItems = _productService.GetBundleItems(product.Id, true); foreach (var bundleItem in bundleItems.Select(x => x.Item).OrderBy(x => x.DisplayOrder)) { writer.WriteStartElement("ProductBundleItem"); writer.Write("ProductId", bundleItem.ProductId.ToString()); writer.Write("BundleProductId", bundleItem.BundleProductId.ToString()); writer.Write("Quantity", bundleItem.Quantity.ToString()); writer.Write("Discount", bundleItem.Discount.HasValue ? bundleItem.Discount.Value.ToString(culture) : ""); writer.Write("DiscountPercentage", bundleItem.DiscountPercentage.ToString()); writer.Write("Name", bundleItem.GetLocalizedName()); writer.Write("ShortDescription", bundleItem.ShortDescription); writer.Write("FilterAttributes", bundleItem.FilterAttributes.ToString()); writer.Write("HideThumbnail", bundleItem.HideThumbnail.ToString()); writer.Write("Visible", bundleItem.Visible.ToString()); writer.Write("Published", bundleItem.Published.ToString()); writer.Write("DisplayOrder", bundleItem.DisplayOrder.ToString()); writer.Write("CreatedOnUtc", bundleItem.CreatedOnUtc.ToString(culture)); writer.Write("UpdatedOnUtc", bundleItem.UpdatedOnUtc.ToString(culture)); writer.WriteEndElement(); } writer.WriteEndElement(); }
public void Migrate(IEnumerable<LocaleResourceEntry> entries, bool updateTouchedResources = false) { Guard.ArgumentNotNull(() => entries); if (!entries.Any() || !_languages.Any()) return; using (var scope = new DbContextScope(_ctx, autoDetectChanges: false)) { var langMap = _languages.ToDictionarySafe(x => x.UniqueSeoCode.EmptyNull().ToLower()); var toDelete = new List<LocaleStringResource>(); var toUpdate = new List<LocaleStringResource>(); var toAdd = new List<LocaleStringResource>(); // remove all entries with invalid lang identifier var invalidEntries = entries.Where(x => x.Lang != null && !langMap.ContainsKey(x.Lang.ToLower())); if (invalidEntries.Any()) { entries = entries.Except(invalidEntries); } foreach (var lang in langMap) { foreach (var entry in entries.Where(x => x.Lang == null || langMap[x.Lang.ToLower()].Id == lang.Value.Id)) { bool isLocal; var db = GetResource(entry.Key, lang.Value.Id, toAdd, out isLocal); if (db == null && entry.Value.HasValue() && !entry.UpdateOnly) { // ADD action toAdd.Add(new LocaleStringResource { LanguageId = lang.Value.Id, ResourceName = entry.Key, ResourceValue = entry.Value }); } if (db == null) continue; if (entry.Value == null) { // DELETE action if (isLocal) toAdd.Remove(db); else toDelete.Add(db); } else { if (isLocal) { db.ResourceValue = entry.Value; continue; } // UPDATE action if (updateTouchedResources || !db.IsTouched.GetValueOrDefault()) { db.ResourceValue = entry.Value; toUpdate.Add(db); if (toDelete.Contains(db)) toDelete.Remove(db); } } } } // add new resources to context _resources.AddRange(toAdd); // remove deleted resources _resources.RemoveRange(toDelete); // update modified resources toUpdate.Each(x => _ctx.Entry(x).State = System.Data.Entity.EntityState.Modified); // save now int affectedRows = _ctx.SaveChanges(); } }
public void Execute(ImportExecuteContext context) { var utcNow = DateTime.UtcNow; var currentStoreId = _services.StoreContext.CurrentStore.Id; using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { var segmenter = context.DataSegmenter; context.Result.TotalRecords = segmenter.TotalRows; while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) { var batch = segmenter.GetCurrentBatch<NewsLetterSubscription>(); // Perf: detach all entities _subscriptionRepository.Context.DetachEntities<NewsLetterSubscription>(false); context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); foreach (var row in batch) { try { var active = true; var email = row.GetDataValue<string>("Email"); var storeId = row.GetDataValue<int>("StoreId"); if (storeId == 0) { storeId = currentStoreId; } if (row.HasDataValue("Active") && row.TryGetDataValue("Active", out active)) { } else { active = true; // default } if (email.IsEmpty()) { context.Result.AddWarning("Skipped empty email address", row.GetRowInfo(), "Email"); continue; } if (email.Length > 255) { context.Result.AddWarning("Skipped email address '{0}'. It exceeds the maximum allowed length of 255".FormatInvariant(email), row.GetRowInfo(), "Email"); continue; } if (!email.IsEmail()) { context.Result.AddWarning("Skipped invalid email address '{0}'".FormatInvariant(email), row.GetRowInfo(), "Email"); continue; } NewsLetterSubscription subscription = null; foreach (var keyName in context.KeyFieldNames) { switch (keyName) { case "Email": subscription = _subscriptionRepository.Table .OrderBy(x => x.Id) .FirstOrDefault(x => x.Email == email && x.StoreId == storeId); break; } if (subscription != null) break; } if (subscription == null) { if (context.UpdateOnly) { ++context.Result.SkippedRecords; continue; } subscription = new NewsLetterSubscription { Active = active, CreatedOnUtc = utcNow, Email = email, NewsLetterSubscriptionGuid = Guid.NewGuid(), StoreId = storeId }; _subscriptionRepository.Insert(subscription); context.Result.NewRecords++; } else { subscription.Active = active; _subscriptionRepository.Update(subscription); context.Result.ModifiedRecords++; } } catch (Exception exception) { context.Result.AddError(exception.ToAllMessages(), row.GetRowInfo()); } } // for _subscriptionRepository.Context.SaveChanges(); } // while } }
public ActionResult PrintMany(string ids = null, bool pdf = false) { if (!_services.Permissions.Authorize(StandardPermissionProvider.ManageOrders)) return new HttpUnauthorizedResult(); IList<Order> orders; using (var scope = new DbContextScope(_services.DbContext, autoDetectChanges: false, forceNoTracking: true)) { if (ids != null) { int[] intIds = ids.ToIntArray(); orders = _orderService.GetOrdersByIds(intIds); } else { orders = _orderService.SearchOrders(0, 0, null, null, null, null, null, null, null, null, 0, int.MaxValue); } } if (orders.Count == 0) { NotifyInfo(T("Admin.Common.ExportNoData")); return RedirectToReferrer(); } if (orders.Count > 500) { NotifyWarning(T("Admin.Common.ExportToPdf.TooManyItems")); return RedirectToReferrer(); } var listModel = orders.Select(x => PrepareOrderDetailsModel(x)).ToList(); return PrintCore(listModel, pdf, "orders.pdf"); }
private void ExportCoreOuter(DataExporterContext ctx) { if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled) return; var logPath = ctx.Request.Profile.GetExportLogPath(); var zipPath = ctx.Request.Profile.GetExportZipPath(); FileSystemHelper.Delete(logPath); FileSystemHelper.Delete(zipPath); FileSystemHelper.ClearDirectory(ctx.FolderContent, false); using (var logger = new TraceLogger(logPath)) { try { ctx.Log = logger; ctx.ExecuteContext.Log = logger; ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo"); if (!ctx.Request.Provider.IsValid()) throw new SmartException("Export aborted because the export provider is not valid."); if (!HasPermission(ctx)) throw new SmartException("You do not have permission to perform the selected export."); foreach (var item in ctx.Request.CustomData) { ctx.ExecuteContext.CustomProperties.Add(item.Key, item.Value); } if (ctx.Request.Profile.ProviderConfigData.HasValue()) { var configInfo = ctx.Request.Provider.Value.ConfigurationInfo; if (configInfo != null) { ctx.ExecuteContext.ConfigurationData = XmlHelper.Deserialize(ctx.Request.Profile.ProviderConfigData, configInfo.ModelType); } } // lazyLoading: false, proxyCreation: false impossible. how to identify all properties of all data levels of all entities // that require manual resolving for now and for future? fragile, susceptible to faults (e.g. price calculation)... using (var scope = new DbContextScope(_dbContext, autoDetectChanges: false, proxyCreation: true, validateOnSave: false, forceNoTracking: true)) { ctx.DeliveryTimes = _deliveryTimeService.Value.GetAllDeliveryTimes().ToDictionary(x => x.Id); ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id); ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id, x => x.ViewPath); ctx.CategoryTemplates = _categoryTemplateService.Value.GetAllCategoryTemplates().ToDictionary(x => x.Id, x => x.ViewPath); if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Product) { var allCategories = _categoryService.Value.GetAllCategories(showHidden: true, applyNavigationFilters: false); ctx.Categories = allCategories.ToDictionary(x => x.Id); } if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Order) { ctx.Countries = _countryService.Value.GetAllCountries(true).ToDictionary(x => x.Id, x => x); } if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Customer) { var subscriptionEmails = _subscriptionRepository.Value.TableUntracked .Where(x => x.Active) .Select(x => x.Email) .Distinct() .ToList(); ctx.NewsletterSubscriptions = new HashSet<string>(subscriptionEmails, StringComparer.OrdinalIgnoreCase); } var stores = Init(ctx); ctx.ExecuteContext.Language = ToDynamic(ctx, ctx.ContextLanguage); ctx.ExecuteContext.Customer = ToDynamic(ctx, ctx.ContextCustomer); ctx.ExecuteContext.Currency = ToDynamic(ctx, ctx.ContextCurrency); stores.ForEach(x => ExportCoreInner(ctx, x)); } if (!ctx.IsPreview && ctx.ExecuteContext.Abort != DataExchangeAbortion.Hard) { if (ctx.IsFileBasedExport) { if (ctx.Request.Profile.CreateZipArchive) { ZipFile.CreateFromDirectory(ctx.FolderContent, zipPath, CompressionLevel.Fastest, false); } if (ctx.Request.Profile.Deployments.Any(x => x.Enabled)) { SetProgress(ctx, T("Common.Publishing")); var allDeploymentsSucceeded = Deploy(ctx, zipPath); if (allDeploymentsSucceeded && ctx.Request.Profile.Cleanup) { logger.Information("Cleaning up export folder"); FileSystemHelper.ClearDirectory(ctx.FolderContent, false); } } } if (ctx.Request.Profile.EmailAccountId != 0 && ctx.Request.Profile.CompletedEmailAddresses.HasValue()) { SendCompletionEmail(ctx, zipPath); } else if (ctx.Request.Profile.IsSystemProfile && !ctx.Supports(ExportFeatures.CanOmitCompletionMail)) { SendCompletionEmail(ctx, zipPath); } } } catch (Exception exception) { logger.ErrorsAll(exception); ctx.Result.LastError = exception.ToString(); } finally { try { if (!ctx.IsPreview && ctx.Request.Profile.Id != 0) { ctx.Request.Profile.ResultInfo = XmlHelper.Serialize(ctx.Result); _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile); } } catch (Exception exception) { logger.ErrorsAll(exception); } DetachAllEntitiesAndClear(ctx); try { ctx.NewsletterSubscriptions.Clear(); ctx.ProductTemplates.Clear(); ctx.CategoryTemplates.Clear(); ctx.Countries.Clear(); ctx.Languages.Clear(); ctx.QuantityUnits.Clear(); ctx.DeliveryTimes.Clear(); ctx.CategoryPathes.Clear(); ctx.Categories.Clear(); ctx.Stores.Clear(); ctx.Request.CustomData.Clear(); ctx.ExecuteContext.CustomProperties.Clear(); ctx.ExecuteContext.Log = null; ctx.Log = null; } catch (Exception exception) { logger.ErrorsAll(exception); } } } if (ctx.IsPreview || ctx.ExecuteContext.Abort == DataExchangeAbortion.Hard) return; // post process order entities if (ctx.EntityIdsLoaded.Any() && ctx.Request.Provider.Value.EntityType == ExportEntityType.Order && ctx.Projection.OrderStatusChange != ExportOrderStatusChange.None) { using (var logger = new TraceLogger(logPath)) { try { int? orderStatusId = null; if (ctx.Projection.OrderStatusChange == ExportOrderStatusChange.Processing) orderStatusId = (int)OrderStatus.Processing; else if (ctx.Projection.OrderStatusChange == ExportOrderStatusChange.Complete) orderStatusId = (int)OrderStatus.Complete; using (var scope = new DbContextScope(_dbContext, false, null, false, false, false, false)) { foreach (var chunk in ctx.EntityIdsLoaded.Chunk()) { var entities = _orderRepository.Value.Table.Where(x => chunk.Contains(x.Id)).ToList(); entities.ForEach(x => x.OrderStatusId = (orderStatusId ?? x.OrderStatusId)); _dbContext.SaveChanges(); } } logger.Information("Updated order status for {0} order(s).".FormatInvariant(ctx.EntityIdsLoaded.Count())); } catch (Exception exception) { logger.ErrorsAll(exception); ctx.Result.LastError = exception.ToString(); } } } }
/// <summary> /// Import products from XLSX file /// </summary> /// <param name="stream">Stream</param> public virtual ImportResult ImportProductsFromExcel( Stream stream, CancellationToken cancellationToken, IProgress<ImportProgressInfo> progress = null) { Guard.ArgumentNotNull(() => stream); var result = new ImportResult(); int saved = 0; if (progress != null) progress.Report(new ImportProgressInfo { ElapsedTime = TimeSpan.Zero }); using (var scope = new DbContextScope(ctx: _rsProduct.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { try { using (var segmenter = new DataSegmenter<Product>(stream)) { result.TotalRecords = segmenter.TotalRows; while (segmenter.ReadNextBatch() && !cancellationToken.IsCancellationRequested) { var batch = segmenter.CurrentBatch; // Perf: detach all entities _rsProduct.Context.DetachAll(false); // Update progress for calling thread if (progress != null) { progress.Report(new ImportProgressInfo { TotalRecords = result.TotalRecords, TotalProcessed = segmenter.CurrentSegmentFirstRowIndex - 1, NewRecords = result.NewRecords, ModifiedRecords = result.ModifiedRecords, ElapsedTime = DateTime.UtcNow - result.StartDateUtc, TotalWarnings = result.Messages.Count(x => x.MessageType == ImportMessageType.Warning), TotalErrors = result.Messages.Count(x => x.MessageType == ImportMessageType.Error), }); } // =========================================================================== // 1.) Import products // =========================================================================== try { saved = ProcessProducts(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessProducts"); } // reduce batch to saved (valid) products. // No need to perform import operations on errored products. batch = batch.Where(x => x.Entity != null && !x.IsTransient).AsReadOnly(); // update result object result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); // =========================================================================== // 2.) Import SEO Slugs // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, // as Slugs are going to be validated against existing ones in DB. // =========================================================================== if (batch.Any(x => x.IsNew || (x.ContainsKey("SeName") || x.NameChanged))) { try { _rsProduct.Context.AutoDetectChangesEnabled = true; ProcessSlugs(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessSeoSlugs"); } finally { _rsProduct.Context.AutoDetectChangesEnabled = false; } } // =========================================================================== // 3.) Import Localizations // =========================================================================== try { ProcessLocalizations(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessLocalizations"); } // =========================================================================== // 4.) Import product category mappings // =========================================================================== if (batch.Any(x => x.ContainsKey("CategoryIds"))) { try { ProcessProductCategories(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessProductCategories"); } } // =========================================================================== // 5.) Import product manufacturer mappings // =========================================================================== if (batch.Any(x => x.ContainsKey("ManufacturerIds"))) { try { ProcessProductManufacturers(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessProductManufacturers"); } } // =========================================================================== // 6.) Import product picture mappings // =========================================================================== if (batch.Any(x => x.ContainsKey("Picture1") || x.ContainsKey("Picture2") || x.ContainsKey("Picture3"))) { try { ProcessProductPictures(batch, result); } catch (Exception ex) { result.AddError(ex, segmenter.CurrentSegment, "ProcessProductPictures"); } } } } } catch (Exception ex) { result.AddError(ex, null, "ReadFile"); } } result.EndDateUtc = DateTime.UtcNow; if (cancellationToken.IsCancellationRequested) { result.Cancelled = true; result.AddInfo("Import task was cancelled by user"); } return result; }
/// <summary> /// Install permissions /// </summary> /// <param name="permissionProvider">Permission provider</param> public virtual void InstallPermissions(IPermissionProvider permissionProvider) { using (var scope = new DbContextScope(_permissionRecordRepository.Context, autoDetectChanges: false, autoCommit: false)) { //install new permissions var permissions = permissionProvider.GetPermissions(); foreach (var permission in permissions) { var permission1 = GetPermissionRecordBySystemName(permission.SystemName); if (permission1 == null) { //new permission (install it) permission1 = new PermissionRecord() { Name = permission.Name, SystemName = permission.SystemName, Category = permission.Category, }; // default customer role mappings var defaultPermissions = permissionProvider.GetDefaultPermissions(); foreach (var defaultPermission in defaultPermissions) { var customerRole = _customerService.GetCustomerRoleBySystemName(defaultPermission.CustomerRoleSystemName); if (customerRole == null) { //new role (save it) customerRole = new CustomerRole() { Name = defaultPermission.CustomerRoleSystemName, Active = true, SystemName = defaultPermission.CustomerRoleSystemName }; _customerService.InsertCustomerRole(customerRole); } var defaultMappingProvided = (from p in defaultPermission.PermissionRecords where p.SystemName == permission1.SystemName select p).Any(); var mappingExists = (from p in customerRole.PermissionRecords where p.SystemName == permission1.SystemName select p).Any(); if (defaultMappingProvided && !mappingExists) { permission1.CustomerRoles.Add(customerRole); } } //save new permission InsertPermissionRecord(permission1); } } scope.Commit(); } }
public virtual void InheritAclIntoChildren(int categoryId, bool touchProductsWithMultipleCategories = false, bool touchExistingAcls = false, bool categoriesOnly = false) { var category = GetCategoryById(categoryId); var subcategories = GetAllCategoriesByParentCategoryId(categoryId, true); var context = new ProductSearchContext { PageSize = int.MaxValue, ShowHidden = true }; context.CategoryIds.AddRange(subcategories.Select(x => x.Id)); context.CategoryIds.Add(categoryId); var products = _productService.SearchProducts(context); var allCustomerRoles = _customerService.GetAllCustomerRoles(true); var categoryCustomerRoles = _aclService.GetCustomerRoleIdsWithAccess(category); using (var scope = new DbContextScope(ctx: _aclRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { _aclRepository.AutoCommitEnabled = false; foreach (var subcategory in subcategories) { if (subcategory.SubjectToAcl != category.SubjectToAcl) { subcategory.SubjectToAcl = category.SubjectToAcl; _categoryRepository.Update(subcategory); } var existingAclRecords = _aclService.GetAclRecords(subcategory).ToDictionary(x => x.CustomerRoleId); foreach (var customerRole in allCustomerRoles) { if (categoryCustomerRoles.Contains(customerRole.Id)) { if (!existingAclRecords.ContainsKey(customerRole.Id)) { _aclRepository.Insert(new AclRecord { CustomerRole = customerRole, CustomerRoleId = customerRole.Id, EntityId = subcategory.Id, EntityName = "Category" }); } } else { AclRecord aclRecordToDelete; if (existingAclRecords.TryGetValue(customerRole.Id, out aclRecordToDelete)) { _aclRepository.Delete(aclRecordToDelete); } } } } _aclRepository.Context.SaveChanges(); foreach (var product in products) { if (product.SubjectToAcl != category.SubjectToAcl) { product.SubjectToAcl = category.SubjectToAcl; _productRepository.Update(product); } var existingAclRecords = _aclService.GetAclRecords(product).ToDictionary(x => x.CustomerRoleId); foreach (var customerRole in allCustomerRoles) { if (categoryCustomerRoles.Contains(customerRole.Id)) { if (!existingAclRecords.ContainsKey(customerRole.Id)) { _aclRepository.Insert(new AclRecord { CustomerRole = customerRole, CustomerRoleId = customerRole.Id, EntityId = product.Id, EntityName = "Product" }); } } else { AclRecord aclRecordToDelete; if (existingAclRecords.TryGetValue(customerRole.Id, out aclRecordToDelete)) { _aclRepository.Delete(aclRecordToDelete); } } } } _aclRepository.Context.SaveChanges(); } }
public void StartCreatingFeeds(Func<FeedFileCreationContext, bool> createFeed, string secondFileName = null) { try { using (var scope = new DbContextScope(autoDetectChanges: false, validateOnSave: false, forceNoTracking: true)) { _cachedPathes = null; _cachedCategories = null; var storeService = _ctx.Resolve<IStoreService>(); var stores = new List<Store>(); if (BaseSettings.StoreId != 0) { var storeById = storeService.GetStoreById(BaseSettings.StoreId); if (storeById != null) stores.Add(storeById); } if (stores.Count == 0) { stores.AddRange(storeService.GetAllStores()); } var context = new FeedFileCreationContext { StoreCount = stores.Count, Progress = new Progress<FeedFileCreationProgress>(x => { AsyncState.Current.Set(x, SystemName); }) }; foreach (var store in stores) { var feedFile = GetFeedFileByStore(store, secondFileName); if (feedFile != null) { FileSystemHelper.Delete(feedFile.FileTempPath); if (secondFileName.HasValue()) FileSystemHelper.Delete(feedFile.CustomProperties["SecondFileTempPath"] as string); using (var stream = new FileStream(feedFile.FileTempPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) using (var logger = new TraceLogger(feedFile.LogPath)) { context.Stream = stream; context.Logger = logger; context.Store = store; context.FeedFileUrl = feedFile.FileUrl; if (secondFileName.HasValue()) context.SecondFilePath = feedFile.CustomProperties["SecondFileTempPath"] as string; if (!createFeed(context)) break; } FileSystemHelper.Copy(feedFile.FileTempPath, feedFile.FilePath); if (secondFileName.HasValue()) FileSystemHelper.Copy(context.SecondFilePath, feedFile.CustomProperties["SecondFilePath"] as string); } } } } finally { AsyncState.Current.Remove<FeedFileCreationProgress>(SystemName); } }
protected int MovePictures(bool toDb) { // long running operation, therefore some code chunks are redundant here in order to boost performance // a list of ALL file paths that were either deleted or created var affectedFiles = new List<string>(1000); var ctx = _pictureRepository.Context; var failed = false; int i = 0; using (var scope = new DbContextScope(ctx: ctx, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false)) { using (var tx = ctx.BeginTransaction()) { // we are about to process data in chunks but want to commit ALL at once when ALL chunks have been processed successfully. try { int pageIndex = 0; IPagedList<Picture> pictures = null; do { if (pictures != null) { // detach all entities from previous page to save memory ctx.DetachEntities(pictures); // breathe pictures.Clear(); pictures = null; } // load max 500 picture entities at once pictures = this.GetPictures(pageIndex, 500); pageIndex++; foreach (var picture in pictures) { string filePath = null; if (!toDb) { if (picture.PictureBinary != null && picture.PictureBinary.Length > 0) { // save picture as file SavePictureInFile(picture.Id, picture.PictureBinary, picture.MimeType, out filePath); } // remove picture binary from DB picture.PictureBinary = new byte[0]; } else { // load picture binary from file and set in DB var picBinary = LoadPictureFromFile(picture.Id, picture.MimeType, out filePath); if (picBinary.Length > 0) { picture.PictureBinary = picBinary; } } // remember file path: we must be able to rollback IO operations on transaction failure if (filePath.HasValue()) { affectedFiles.Add(filePath); //picture.IsNew = true; } // explicitly attach modified entity to context, because we disabled AutoCommit picture.UpdatedOnUtc = DateTime.UtcNow; _pictureRepository.Update(picture); i++; } // save the current batch to DB ctx.SaveChanges(); } while (pictures.HasNextPage); // FIRE! tx.Commit(); } catch (Exception ex) { failed = true; tx.Rollback(); _settingService.SetSetting<bool>("Media.Images.StoreInDB", !toDb); _notifier.Error(ex.Message); _logger.Error(ex); } } } if (affectedFiles.Count > 0) { if ((toDb && !failed) || (!toDb && failed)) { // FS > DB sucessful OR DB > FS failed: delete all physical files // run a background task for the deletion of files (fire & forget) Task.Factory.StartNew(state => { var files = state as string[]; foreach (var path in files) { if (File.Exists(path)) File.Delete(path); } }, affectedFiles.ToArray()).ConfigureAwait(false); } // shrink database (only when DB > FS and success) if (!toDb && !failed) { ctx.ShrinkDatabase(); } } return i; }
protected override void Import(ImportExecuteContext context) { var srcToDestId = new Dictionary<int, ImportProductMapping>(); var templateViewPaths = _productTemplateService.GetAllProductTemplates().ToDictionarySafe(x => x.ViewPath, x => x.Id); using (var scope = new DbContextScope(ctx: _productRepository.Context, autoDetectChanges: false, proxyCreation: false, validateOnSave: false)) { var segmenter = context.DataSegmenter; Initialize(context); while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) { var batch = segmenter.GetCurrentBatch<Product>(); // Perf: detach all entities _productRepository.Context.DetachAll(false); context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows); // =========================================================================== // 1.) Import products // =========================================================================== try { ProcessProducts(context, batch, templateViewPaths, srcToDestId); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProducts"); } // reduce batch to saved (valid) products. // No need to perform import operations on errored products. batch = batch.Where(x => x.Entity != null && !x.IsTransient).ToArray(); // update result object context.Result.NewRecords += batch.Count(x => x.IsNew && !x.IsTransient); context.Result.ModifiedRecords += batch.Count(x => !x.IsNew && !x.IsTransient); // =========================================================================== // 2.) Import SEO Slugs // IMPORTANT: Unlike with Products AutoCommitEnabled must be TRUE, // as Slugs are going to be validated against existing ones in DB. // =========================================================================== if (segmenter.HasColumn("SeName", true) || batch.Any(x => x.IsNew || x.NameChanged)) { try { _productRepository.Context.AutoDetectChangesEnabled = true; ProcessSlugs(context, batch, typeof(Product).Name); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessSlugs"); } finally { _productRepository.Context.AutoDetectChangesEnabled = false; } } // =========================================================================== // 3.) Import StoreMappings // =========================================================================== if (segmenter.HasColumn("StoreIds")) { try { ProcessStoreMappings(context, batch); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessStoreMappings"); } } // =========================================================================== // 4.) Import Localizations // =========================================================================== try { ProcessLocalizations(context, batch, _localizableProperties); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessLocalizations"); } // =========================================================================== // 5.) Import product category mappings // =========================================================================== if (segmenter.HasColumn("CategoryIds")) { try { ProcessProductCategories(context, batch); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductCategories"); } } // =========================================================================== // 6.) Import product manufacturer mappings // =========================================================================== if (segmenter.HasColumn("ManufacturerIds")) { try { ProcessProductManufacturers(context, batch); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductManufacturers"); } } // =========================================================================== // 7.) Import product picture mappings // =========================================================================== if (segmenter.HasColumn("ImageUrls")) { try { ProcessProductPictures(context, batch); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessProductPictures"); } } } // =========================================================================== // 8.) Map parent id of inserted products // =========================================================================== if (srcToDestId.Any() && segmenter.HasColumn("Id") && segmenter.HasColumn("ParentGroupedProductId") && !segmenter.IsIgnored("ParentGroupedProductId")) { segmenter.Reset(); while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch()) { var batch = segmenter.GetCurrentBatch<Product>(); _productRepository.Context.DetachAll(false); try { ProcessProductMappings(context, batch, srcToDestId); } catch (Exception exception) { context.Result.AddError(exception, segmenter.CurrentSegment, "ProcessParentMappings"); } } } } }