diff --git a/src/VirtoCommerce.OrdersModule.Core/Model/Search/CustomerOrderSearchCriteria.cs b/src/VirtoCommerce.OrdersModule.Core/Model/Search/CustomerOrderSearchCriteria.cs index b25271254..8157f5830 100644 --- a/src/VirtoCommerce.OrdersModule.Core/Model/Search/CustomerOrderSearchCriteria.cs +++ b/src/VirtoCommerce.OrdersModule.Core/Model/Search/CustomerOrderSearchCriteria.cs @@ -89,5 +89,30 @@ public string[] OrganizationIds /// Search orders with a certain product /// public string ProductId { get; set; } + + /// + /// Search orders with a certain promotion + /// + public string PromotionId { get; set; } + + private string[] _promotionIds; + /// + /// Search orders with given promotions + /// + public string[] PromotionIds + { + get + { + if (_promotionIds.IsNullOrEmpty() && !string.IsNullOrEmpty(PromotionId)) + { + _promotionIds = new[] { PromotionId }; + } + return _promotionIds; + } + set + { + _promotionIds = value; + } + } } } diff --git a/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderDocumentBuilder.cs b/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderDocumentBuilder.cs index 9c9d22e33..14b4d8bb7 100644 --- a/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderDocumentBuilder.cs +++ b/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderDocumentBuilder.cs @@ -54,6 +54,7 @@ public Task BuildSchemaAsync(IndexDocument schema) schema.AddFilterableString("OuterId"); schema.AddFilterableString("Status"); schema.AddFilterableString("Currency"); + schema.AddFilterableString("PromotionId"); schema.AddFilterableDecimal("Total"); schema.AddFilterableDecimal("SubTotal"); @@ -125,6 +126,8 @@ protected virtual async Task CreateDocument(CustomerOrder order) document.AddFilterableBoolean("IsCancelled", order.IsCancelled); document.AddFilterableBoolean("IsPrototype", order.IsPrototype); + IndexDiscounts(order.Discounts, document); + foreach (var address in order.Addresses ?? Enumerable.Empty
()) { IndexAddress(address, document); @@ -132,12 +135,14 @@ protected virtual async Task CreateDocument(CustomerOrder order) foreach (var lineItem in order.Items ?? Enumerable.Empty()) { + IndexDiscounts(lineItem.Discounts, document); document.AddContentString(lineItem.Comment); } foreach (var payment in order.InPayments ?? Enumerable.Empty()) { IndexAddress(payment.BillingAddress, document); + IndexDiscounts(payment.Discounts, document); document.AddContentString(payment.Number); document.AddContentString(payment.Comment); } @@ -145,6 +150,7 @@ protected virtual async Task CreateDocument(CustomerOrder order) foreach (var shipment in order.Shipments ?? Enumerable.Empty()) { IndexAddress(shipment.DeliveryAddress, document); + IndexDiscounts(shipment.Discounts, document); document.AddContentString(shipment.Number); document.AddContentString(shipment.Comment); @@ -171,5 +177,16 @@ protected virtual void IndexAddress(Address address, IndexDocument document) document.AddContentString($"{address.AddressType} {address}"); } } + + protected virtual void IndexDiscounts(ICollection discounts, IndexDocument document) + { + if(discounts!=null) + { + foreach (var discount in discounts.Where(d => d != null && !string.IsNullOrEmpty(d.PromotionId))) + { + document.AddFilterableString("PromotionId", discount.PromotionId); + } + } + } } } diff --git a/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderSearchRequestBuilder.cs b/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderSearchRequestBuilder.cs index d4ac36b52..cb5748c1e 100644 --- a/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderSearchRequestBuilder.cs +++ b/src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderSearchRequestBuilder.cs @@ -173,6 +173,11 @@ protected virtual IList GetPermanentFilters(CustomerOrderSearchCriteria result.Add(FilterHelper.CreateTermFilter("isprototype", "false")); } + if (!criteria.PromotionIds.IsNullOrEmpty()) + { + result.Add(FilterHelper.CreateTermFilter("promotionid", criteria.PromotionIds)); + } + return result; } diff --git a/src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderSearchService.cs b/src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderSearchService.cs index 1dbcedb9d..2ca9dfa45 100644 --- a/src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderSearchService.cs +++ b/src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderSearchService.cs @@ -81,6 +81,8 @@ protected override IQueryable BuildQuery(IRepository reposi query = query.Where(o => o.Items.Any(i => i.ProductId == criteria.ProductId)); } + query = WithPromotionConditions(query, criteria); + return query; } @@ -175,5 +177,21 @@ private static IQueryable WithSubscriptionConditions(IQuery return query; } + + private static IQueryable WithPromotionConditions(IQueryable query, CustomerOrderSearchCriteria criteria) + { + if (!criteria.PromotionIds.IsNullOrEmpty()) + { + // Check if any discount in the order, shipments, payments, or line items has the promotion ID + query = query.Where(o => + (o.Discounts != null && o.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId))) || + (o.Shipments != null && o.Shipments.Any(s => s.Discounts != null && s.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId)))) || + (o.InPayments != null && o.InPayments.Any(p => p.Discounts != null && p.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId)))) || + (o.Items != null && o.Items.Any(i => i.Discounts != null && i.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId)))) + ); + } + + return query; + } } } diff --git a/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.js b/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.js new file mode 100644 index 000000000..3bc3fe427 --- /dev/null +++ b/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.js @@ -0,0 +1,21 @@ +angular.module('virtoCommerce.orderModule') + .controller('virtoCommerce.orderModule.operationDiscountsController', [ + '$scope', + 'platformWebApp.uiGridHelper', + function ($scope, uiGridHelper) { + var blade = $scope.blade; + + blade.title = 'orders.blades.customerOrder-item-discounts.title'; + blade.headIcon = 'fa fa-area-chart'; + + $scope.setGridOptions = function (gridOptions) { + uiGridHelper.initialize($scope, gridOptions, function (gridApi) { + $scope.gridApi = gridApi; + }); + }; + + blade.isLoading = false; + } + ]); + + diff --git a/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.tpl.html b/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.tpl.html new file mode 100644 index 000000000..1fdfdb8a5 --- /dev/null +++ b/src/VirtoCommerce.OrdersModule.Web/Scripts/blades/operation-discounts.tpl.html @@ -0,0 +1,25 @@ +
+
+
+
+
+
+
{{ 'orders.blades.customerOrder-item-discounts.descr.no-discounts' | translate }}
+
+
+
+ + + + diff --git a/src/VirtoCommerce.OrdersModule.Web/Scripts/order.js b/src/VirtoCommerce.OrdersModule.Web/Scripts/order.js index 967b7a40f..923b3e8b8 100644 --- a/src/VirtoCommerce.OrdersModule.Web/Scripts/order.js +++ b/src/VirtoCommerce.OrdersModule.Web/Scripts/order.js @@ -851,11 +851,14 @@ angular.module(moduleName, [ } }); - var customerOrderItemDiscountWidget = { - controller: 'virtoCommerce.orderModule.customerOrderItemDiscountWidgetController', - template: 'Modules/$(VirtoCommerce.Orders)/Scripts/widgets/customerOrder-item-discounts-widget.tpl.html' + var operationDiscountsWidget = { + controller: 'virtoCommerce.orderModule.operationDiscountWidgetController', + template: 'Modules/$(VirtoCommerce.Orders)/Scripts/widgets/operation-discounts-widget.tpl.html' }; - widgetService.registerWidget(customerOrderItemDiscountWidget, 'customerOrderItemDetailWidgets'); + widgetService.registerWidget(operationDiscountsWidget, 'customerOrderDetailWidgets'); + widgetService.registerWidget(operationDiscountsWidget, 'paymentDetailWidgets'); + widgetService.registerWidget(operationDiscountsWidget, 'shipmentDetailWidgets'); + widgetService.registerWidget(operationDiscountsWidget, 'customerOrderItemDetailWidgets'); var customerOrderItemConfigurationWidget = { controller: 'virtoCommerce.orderModule.customerOrderItemConfigurationWidgetController', diff --git a/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.js b/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.js new file mode 100644 index 000000000..284f629b0 --- /dev/null +++ b/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.js @@ -0,0 +1,21 @@ +angular.module('virtoCommerce.orderModule') + .controller('virtoCommerce.orderModule.operationDiscountWidgetController', [ + '$scope', + 'platformWebApp.bladeNavigationService', + function ($scope, bladeNavigationService) { + var blade = $scope.blade; + + $scope.openBlade = function () { + var newBlade = { + id: "operationDiscounts", + controller: 'virtoCommerce.orderModule.operationDiscountsController', + template: 'Modules/$(VirtoCommerce.Orders)/Scripts/blades/operation-discounts.tpl.html', + currentEntity: blade.currentEntity, + }; + + bladeNavigationService.showBlade(newBlade, blade); + }; + } + ]); + + diff --git a/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.tpl.html b/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.tpl.html new file mode 100644 index 000000000..feced26cc --- /dev/null +++ b/src/VirtoCommerce.OrdersModule.Web/Scripts/widgets/operation-discounts-widget.tpl.html @@ -0,0 +1,8 @@ +
+
+
{{(blade.currentEntity.discounts || []).length | number:0}}
+
{{ 'orders.widgets.customerOrder-item-discounts.title' | translate }}
+
+
+ +