public IHttpActionResult DoExport(CsvExportInfo exportInfo) { var notification = new ExportNotification(CurrentPrincipal.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; _notifier.Upsert(notification); var catalog = _catalogService.GetById(exportInfo.CatalogId); if (catalog == null) { throw new NullReferenceException("catalog"); } var curencySetting = _settingsManager.GetSettingByName("VirtoCommerce.Core.General.Currencies"); var defaultCurrency = EnumUtility.SafeParse <CurrencyCodes>(curencySetting.DefaultValue, CurrencyCodes.USD); var exportJob = new CsvCatalogExportJob(); BackgroundJob.Enqueue(() => exportJob.DoExport(exportInfo.CatalogId, exportInfo.CategoryIds, exportInfo.ProductIds, exportInfo.PriceListId, exportInfo.FulfilmentCenterId, exportInfo.Currency ?? defaultCurrency, catalog.DefaultLanguage.LanguageCode, notification)); return(Ok(notification)); }
// Only public methods can be invoked in the background. (Hangfire) public async Task BackgroundExport(CsvExportInfo exportInfo, ExportNotification notifyEvent) { var currencies = await _currencyService.GetAllCurrenciesAsync(); var defaultCurrency = currencies.First(x => x.IsPrimary); exportInfo.Currency ??= defaultCurrency.Code; var catalog = await _catalogService.GetByIdsAsync(new[] { exportInfo.CatalogId }); if (catalog == null) { throw new InvalidOperationException($"Cannot get catalog with id '{exportInfo.CatalogId}'"); } Action <ExportImportProgressInfo> progressCallback = async x => { notifyEvent.InjectFrom(x); await _notifier.SendAsync(notifyEvent); }; using (var stream = new MemoryStream()) { try { exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); await _csvExporter.DoExportAsync(stream, exportInfo, progressCallback); stream.Position = 0; var fileNameTemplate = await _settingsManager.GetValueAsync(CsvModuleConstants.Settings.General.ExportFileNameTemplate.Name, CsvModuleConstants.Settings.General.ExportFileNameTemplate.DefaultValue.ToString()); var fileName = string.Format(fileNameTemplate, DateTime.UtcNow); fileName = Path.ChangeExtension(fileName, ".csv"); var blobRelativeUrl = Path.Combine("temp", fileName); //Upload result csv to blob storage using (var blobStream = _blobStorageProvider.OpenWrite(blobRelativeUrl)) { stream.CopyTo(blobStream); } //Get a download url notifyEvent.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(blobRelativeUrl); notifyEvent.Description = "Export finished"; } catch (Exception ex) { notifyEvent.Description = "Export failed"; notifyEvent.Errors.Add(ex.ExpandExceptionMessage()); } finally { notifyEvent.Finished = DateTime.UtcNow; await _notifier.SendAsync(notifyEvent); } } }
public void BackgroundExport(CsvExportInfo exportInfo, ExportNotification notifyEvent) { var curencySetting = _settingsManager.GetSettingByName("VirtoCommerce.Core.General.Currencies"); var defaultCurrency = EnumUtility.SafeParse <CurrencyCodes>(curencySetting.DefaultValue, CurrencyCodes.USD); exportInfo.Currency = exportInfo.Currency ?? defaultCurrency; var catalog = _catalogService.GetById(exportInfo.CatalogId); if (catalog == null) { throw new NullReferenceException("catalog"); } Action <ExportImportProgressInfo> progressCallback = (x) => { notifyEvent.InjectFrom(x); _notifier.Upsert(notifyEvent); }; using (var stream = new MemoryStream()) { try { exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); _csvExporter.DoExport(stream, exportInfo, progressCallback); stream.Position = 0; //Upload result csv to blob storage var uploadInfo = new UploadStreamInfo { FileName = "Catalog-" + catalog.Name + "-export.csv", FileByteStream = stream, FolderName = "temp" }; var blobKey = _blobStorageProvider.Upload(uploadInfo); //Get a download url notifyEvent.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(blobKey); notifyEvent.Description = "Export finished"; } catch (Exception ex) { notifyEvent.Description = "Export failed"; notifyEvent.Errors.Add(ex.ExpandExceptionMessage()); } finally { notifyEvent.Finished = DateTime.UtcNow; _notifier.Upsert(notifyEvent); } } }
public IHttpActionResult DoExport(CsvExportInfo exportInfo) { var notification = new ExportNotification(CurrentPrincipal.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; _notifier.Upsert(notification); BackgroundJob.Enqueue(() => BackgroundExport(exportInfo, notification)); return Ok(notification); }
// Only public methods can be invoked in the background. (Hangfire) public void BackgroundExport(CsvExportInfo exportInfo, ExportNotification notifyEvent) { var currencies = _commerceService.GetAllCurrencies(); var defaultCurrency = currencies.First(x => x.IsPrimary); exportInfo.Currency = exportInfo.Currency ?? defaultCurrency.Code; var catalog = _catalogService.GetById(exportInfo.CatalogId); if (catalog == null) { throw new NullReferenceException("catalog"); } Action <ExportImportProgressInfo> progressCallback = x => { notifyEvent.InjectFrom(x); _notifier.Upsert(notifyEvent); }; using (var stream = new MemoryStream()) { try { exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); _csvExporter.DoExport(stream, exportInfo, progressCallback); stream.Position = 0; var blobRelativeUrl = "temp/Catalog-" + catalog.Name + "-export.csv"; //Upload result csv to blob storage using (var blobStream = _blobStorageProvider.OpenWrite(blobRelativeUrl)) { stream.CopyTo(blobStream); } //Get a download url notifyEvent.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(blobRelativeUrl); notifyEvent.Description = "Export finished"; } catch (Exception ex) { notifyEvent.Description = "Export failed"; notifyEvent.Errors.Add(ex.ExpandExceptionMessage()); } finally { notifyEvent.Finished = DateTime.UtcNow; _notifier.Upsert(notifyEvent); } } }
public IHttpActionResult DoExport(CsvExportInfo exportInfo) { var notification = new ExportNotification(CurrentPrincipal.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; _notifier.Upsert(notification); BackgroundJob.Enqueue(() => BackgroundExport(exportInfo, notification)); return(Ok(notification)); }
public IHttpActionResult DoExport(CsvExportInfo exportInfo) { base.CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Export, exportInfo); var notification = new ExportNotification(CurrentPrincipal.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; _notifier.Upsert(notification); BackgroundJob.Enqueue(() => BackgroundExport(exportInfo, notification)); return Ok(notification); }
public IHttpActionResult DoExport(CsvExportInfo exportInfo) { CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Export, exportInfo); var notification = new ExportNotification(_userNameResolver.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; _notifier.Upsert(notification); BackgroundJob.Enqueue(() => BackgroundExport(exportInfo, notification)); return(Ok(notification)); }
public async Task <ActionResult <ExportNotification> > DoExport([FromBody] CsvExportInfo exportInfo) { var hasPermissions = true; if (!exportInfo.ProductIds.IsNullOrEmpty()) { var items = await _itemService.GetByIdsAsync(exportInfo.ProductIds, ItemResponseGroup.ItemInfo.ToString()); hasPermissions = await CheckCatalogPermission(items, CatalogModuleConstants.Security.Permissions.Read); } if (hasPermissions && !exportInfo.CategoryIds.IsNullOrEmpty()) { var categories = await _categoryService.GetByIdsAsync(exportInfo.CategoryIds, CategoryResponseGroup.Info.ToString()); hasPermissions = await CheckCatalogPermission(categories, CatalogModuleConstants.Security.Permissions.Read); } if (hasPermissions && !exportInfo.CatalogId.IsNullOrEmpty()) { var catalogs = await _catalogService.GetByIdsAsync(new[] { exportInfo.CatalogId }, CategoryResponseGroup.Info.ToString()); if (!catalogs.IsNullOrEmpty()) { hasPermissions = await CheckCatalogPermission(catalogs.First(), CatalogModuleConstants.Security.Permissions.Read); } } if (!hasPermissions) { return(Unauthorized()); } var notification = new ExportNotification(_userNameResolver.GetCurrentUserName()) { Title = "Catalog export task", Description = "starting export...." }; await _notifier.SendAsync(notification); BackgroundJob.Enqueue(() => BackgroundExport(exportInfo, notification)); return(Ok(notification)); }
public void CsvHeadersExportTest_DefaultConfiguration_HeadersAreSame() { using (var sw = new StringWriter()) { using (var csv = new CsvWriter(sw)) { CsvExportInfo exportInfo = new CsvExportInfo(); exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); csv.Configuration.Delimiter = exportInfo.Configuration.Delimiter; csv.Configuration.RegisterClassMap(new CsvProductMap(exportInfo.Configuration)); csv.WriteHeader <CsvProduct>(); csv.Flush(); var expected = string.Join(exportInfo.Configuration.Delimiter, exportInfo.Configuration.PropertyMaps.Select(x => x.CsvColumnName)); Assert.Equal(expected, sw.ToString()); } } }
private CsvProduct ExportAndImportProduct(CatalogProduct product) { var exportInfo = new CsvExportInfo(); using (var stream = new MemoryStream()) { var streamWriter = new StreamWriter(stream, Encoding.UTF8, 1024, true) { AutoFlush = true }; using (var csvWriter = new CsvWriter(streamWriter)) { exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); exportInfo.Configuration.PropertyCsvColumns = product.Properties.Select(x => x.Name).Distinct().ToArray(); csvWriter.Configuration.Delimiter = exportInfo.Configuration.Delimiter; csvWriter.Configuration.RegisterClassMap(new CsvProductMap(exportInfo.Configuration)); csvWriter.WriteHeader <CsvProduct>(); csvWriter.NextRecord(); var csvProduct = new CsvProduct(product, null, null, null, null); csvWriter.WriteRecord(csvProduct); csvWriter.Flush(); stream.Position = 0; } using (var reader = new CsvReader(new StreamReader(stream, Encoding.UTF8))) { reader.Configuration.Delimiter = exportInfo.Configuration.Delimiter; reader.Configuration.RegisterClassMap(new CsvProductMap(exportInfo.Configuration)); reader.Configuration.MissingFieldFound = (strings, i, arg3) => { //do nothing }; reader.Configuration.TrimOptions = TrimOptions.Trim; reader.Read(); return(reader.GetRecord <CsvProduct>()); } } }
// Only public methods can be invoked in the background. (Hangfire) public void BackgroundExport(CsvExportInfo exportInfo, ExportNotification notifyEvent) { var curencySetting = _settingsManager.GetSettingByName("VirtoCommerce.Core.General.Currencies"); var defaultCurrency = EnumUtility.SafeParse<CurrencyCodes>(curencySetting.DefaultValue, CurrencyCodes.USD); exportInfo.Currency = exportInfo.Currency ?? defaultCurrency; var catalog = _catalogService.GetById(exportInfo.CatalogId); if (catalog == null) { throw new NullReferenceException("catalog"); } Action<ExportImportProgressInfo> progressCallback = (x) => { notifyEvent.InjectFrom(x); _notifier.Upsert(notifyEvent); }; using (var stream = new MemoryStream()) { try { exportInfo.Configuration = CsvProductMappingConfiguration.GetDefaultConfiguration(); _csvExporter.DoExport(stream, exportInfo, progressCallback); stream.Position = 0; var blobRelativeUrl = "temp/Catalog-" + catalog.Name + "-export.csv"; //Upload result csv to blob storage using (var blobStream = _blobStorageProvider.OpenWrite(blobRelativeUrl)) { stream.CopyTo(blobStream); } //Get a download url notifyEvent.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(blobRelativeUrl); notifyEvent.Description = "Export finished"; } catch (Exception ex) { notifyEvent.Description = "Export failed"; notifyEvent.Errors.Add(ex.ExpandExceptionMessage()); } finally { notifyEvent.Finished = DateTime.UtcNow; _notifier.Upsert(notifyEvent); } } }
public void DoExport(Stream outStream, CsvExportInfo exportInfo, Action <ExportImportProgressInfo> progressCallback) { var prodgressInfo = new ExportImportProgressInfo { Description = "loading products..." }; var streamWriter = new StreamWriter(outStream, Encoding.UTF8, 1024, true) { AutoFlush = true }; using (var csvWriter = new CsvWriter(streamWriter)) { //Notification progressCallback(prodgressInfo); //Load all products to export var products = LoadProducts(exportInfo.CatalogId, exportInfo.CategoryIds, exportInfo.ProductIds); var allProductIds = products.Select(x => x.Id).ToArray(); //Load prices for products prodgressInfo.Description = "loading prices..."; progressCallback(prodgressInfo); var priceEvalContext = new PriceEvaluationContext { ProductIds = allProductIds, PricelistIds = exportInfo.PriceListId == null ? null : new[] { exportInfo.PriceListId }, Currency = exportInfo.Currency }; var allProductPrices = _pricingService.EvaluateProductPrices(priceEvalContext).ToList(); //Load inventories prodgressInfo.Description = "loading inventory information..."; progressCallback(prodgressInfo); var allProductInventories = _inventoryService.GetProductsInventoryInfos(allProductIds).Where(x => exportInfo.FulfilmentCenterId == null || x.FulfillmentCenterId == exportInfo.FulfilmentCenterId).ToList(); //Export configuration exportInfo.Configuration.PropertyCsvColumns = products.SelectMany(x => x.PropertyValues).Select(x => x.PropertyName).Distinct().ToArray(); csvWriter.Configuration.Delimiter = exportInfo.Configuration.Delimiter; csvWriter.Configuration.RegisterClassMap(new CsvProductMap(exportInfo.Configuration)); //Write header csvWriter.WriteHeader <CsvProduct>(); csvWriter.NextRecord(); prodgressInfo.TotalCount = products.Count; var notifyProductSizeLimit = 50; var counter = 0; //convert to dict for faster search var pricesDict = allProductPrices.GroupBy(x => x.ProductId).ToDictionary(x => x.Key, x => x.First()); var inventoriesDict = allProductInventories.GroupBy(x => x.ProductId).ToDictionary(x => x.Key, x => x.First()); foreach (var product in products) { try { var csvProducts = MakeMultipleExportProducts(product, pricesDict, inventoriesDict); csvWriter.WriteRecords(csvProducts); } catch (Exception ex) { prodgressInfo.Errors.Add(ex.ToString()); progressCallback(prodgressInfo); } //Raise notification each notifyProductSizeLimit products counter++; prodgressInfo.ProcessedCount = counter; prodgressInfo.Description = string.Format("{0} of {1} products processed", prodgressInfo.ProcessedCount, prodgressInfo.TotalCount); if (counter % notifyProductSizeLimit == 0 || counter == prodgressInfo.TotalCount) { progressCallback(prodgressInfo); } } } }