Skip to content

Commit

Permalink
VP-1639: Add API for delete lots of products or categories (#331)
Browse files Browse the repository at this point in the history
Added endpoint POST "api/catalog/listentries/delete" which receives SearchCriteria and deletes products/categories by batches.
  • Loading branch information
AliveMen authored Mar 17, 2020
1 parent ac4717a commit 0345cb4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 22 deletions.
10 changes: 4 additions & 6 deletions VirtoCommerce.CatalogModule.Web.Core/Model/SearchCriteria.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VirtoCommerce.Domain.Catalog.Model;

namespace VirtoCommerce.CatalogModule.Web.Model
Expand Down Expand Up @@ -73,7 +69,7 @@ public SearchCriteria()
public DateTime? IndexDate { get; set; }

public string PricelistId { get; set; }

public string[] PricelistIds { get; set; }

/// <summary>
Expand Down Expand Up @@ -123,6 +119,8 @@ public SearchCriteria()
public string[] VendorIds { get; set; }

public DateTime? StartDateFrom { get; set; }


public string[] ObjectIds { get; set; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
using System.Web.Http.Description;
using VirtoCommerce.CatalogModule.Web.Converters;
using VirtoCommerce.CatalogModule.Web.Security;
using VirtoCommerce.CatalogModule.Web.Services;
using VirtoCommerce.Domain.Catalog.Services;
using VirtoCommerce.Domain.Search;
using VirtoCommerce.Platform.Core.Assets;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Security;
using coreModel = VirtoCommerce.Domain.Catalog.Model;
using webModel = VirtoCommerce.CatalogModule.Web.Model;
using VirtoCommerce.CatalogModule.Web.Services;

namespace VirtoCommerce.CatalogModule.Web.Controllers.Api
{
Expand All @@ -27,6 +28,8 @@ public class CatalogModuleListEntryController : CatalogBaseController
private readonly ListEntryMover<coreModel.Category> _categoryMover;
private readonly ListEntryMover<coreModel.CatalogProduct> _productMover;

private const int DeleteBatchSize = 50;

public CatalogModuleListEntryController(
ICatalogSearchService searchService,
ICategoryService categoryService,
Expand Down Expand Up @@ -59,19 +62,8 @@ public CatalogModuleListEntryController(
[ResponseType(typeof(webModel.ListEntrySearchResult))]
public IHttpActionResult ListItemsSearch(webModel.SearchCriteria criteria)
{
var coreModelCriteria = criteria.ToCoreModel();
ApplyRestrictionsForCurrentUser(coreModelCriteria);

coreModelCriteria.WithHidden = true;

// need search in children categories if user specify keyword
if (!string.IsNullOrEmpty(coreModelCriteria.Keyword))
{
coreModelCriteria.SearchInChildren = true;
coreModelCriteria.SearchInVariations = true;
}

var result = _listEntrySearchService.Search(coreModelCriteria);
var result = SearchListEntries(criteria);

return Ok(result);
}
Expand Down Expand Up @@ -217,6 +209,100 @@ public IHttpActionResult Move(webModel.MoveInfo moveInfo)
return Ok();
}

/// <summary>
/// Bulk delete by the search criteria.
/// </summary>
/// <param name="searchCriteria"></param>
[HttpPost]
[Route("delete")]
[ResponseType(typeof(void))]
public IHttpActionResult Delete(webModel.SearchCriteria searchCriteria)
{
var idsToDelete = searchCriteria.ObjectIds?.ToList() ?? new List<string>();
var productIds = new List<string>();
var categoryIds = new List<string>();

if (idsToDelete.IsNullOrEmpty())
{
idsToDelete = GetIdsToDelete(searchCriteria);
}

if (!idsToDelete.IsNullOrEmpty())
{
idsToDelete.ProcessWithPaging(DeleteBatchSize, (ids, currentItem, totalCount) =>
{
var commonIds = ids.ToArray();
var searchProductResult = _itemService.GetByIds(commonIds, coreModel.ItemResponseGroup.None);
CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Delete, searchProductResult);
productIds.AddRange(searchProductResult.Select(x => x.Id));

var searchCategoryResult = _categoryService.GetByIds(commonIds.ToArray(), coreModel.CategoryResponseGroup.None);
CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Delete, searchCategoryResult);
categoryIds.AddRange(searchCategoryResult.Select(x => x.Id));
});

productIds.ProcessWithPaging(DeleteBatchSize, (ids, currentItem, totalCount) =>
{
_itemService.Delete(ids.ToArray());
});

categoryIds.ProcessWithPaging(DeleteBatchSize, (ids, currentItem, totalCount) =>
{
_categoryService.Delete(ids.ToArray());
});
}

return StatusCode(HttpStatusCode.NoContent);
}


private webModel.ListEntrySearchResult SearchListEntries(webModel.SearchCriteria criteria)
{
var coreModelCriteria = criteria.ToCoreModel();
ApplyRestrictionsForCurrentUser(coreModelCriteria);

coreModelCriteria.WithHidden = true;

// need search in children categories if user specify keyword
if (!string.IsNullOrEmpty(coreModelCriteria.Keyword))
{
coreModelCriteria.SearchInChildren = true;
coreModelCriteria.SearchInVariations = true;
}

return _listEntrySearchService.Search(coreModelCriteria);

}
private List<string> GetIdsToDelete(webModel.SearchCriteria searchCriteria)
{
// Any pagination for deleting should be managed at back-end.
searchCriteria.Take = DeleteBatchSize;
searchCriteria.Skip = 0;

var itemIds = new List<string>();
bool hasItems;

do
{
var searchResult = SearchListEntries(searchCriteria);
var listEntriesIds = searchResult.ListEntries
.Where(x => x.Type.EqualsInvariant(KnownDocumentTypes.Product) || x.Type.EqualsInvariant(KnownDocumentTypes.Category))
.Select(x => x.Id)
.ToArray();

hasItems = !listEntriesIds.IsNullOrEmpty();

if (hasItems)
{
itemIds.AddRange(listEntriesIds);
searchCriteria.Skip += searchCriteria.Take;
}
}
while (hasItems);

return itemIds;
}

private void InnerUpdateLinks(webModel.ListEntryLink[] links, Action<coreModel.ILinkSupport, coreModel.CategoryLink> action)
{
var changedObjects = new List<coreModel.ILinkSupport>();
Expand Down
4 changes: 2 additions & 2 deletions VirtoCommerce.CatalogModule.Web/Scripts/resources/items.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
angular.module('virtoCommerce.catalogModule')
angular.module('virtoCommerce.catalogModule')
.factory('virtoCommerce.catalogModule.items', ['$resource', function ($resource) {
return $resource('api/catalog/products/:id', null, {
remove: { method: 'DELETE', url: 'api/catalog/products' },
Expand All @@ -9,4 +9,4 @@
update: { method: 'POST' },
plenty: { method: 'POST', url: 'api/catalog/products/plenty', isArray: true }
});
}]);
}]);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ angular.module('virtoCommerce.catalogModule')
createlinks: { method: 'POST', url: 'api/catalog/listentrylinks' },
bulkcreatelinks: { method: 'POST', url: 'api/catalog/listentrylinks/bulkcreate' },
deletelinks: { method: 'POST', url: 'api/catalog/listentrylinks/delete' },
move: { method: 'POST', url: 'api/catalog/listentries/move' }
move: { method: 'POST', url: 'api/catalog/listentries/move' },
delete: { method: 'POST', url: 'api/catalog/listentries/delete' }
});
}]);

0 comments on commit 0345cb4

Please sign in to comment.