Skip to content

Commit 36e21db

Browse files
authored
fix: Add support for order search by promotion ID(s) (#478)
1 parent 7301984 commit 36e21db

File tree

9 files changed

+147
-4
lines changed

9 files changed

+147
-4
lines changed

src/VirtoCommerce.OrdersModule.Core/Model/Search/CustomerOrderSearchCriteria.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,30 @@ public string[] OrganizationIds
8989
/// Search orders with a certain product
9090
/// </summary>
9191
public string ProductId { get; set; }
92+
93+
/// <summary>
94+
/// Search orders with a certain promotion
95+
/// </summary>
96+
public string PromotionId { get; set; }
97+
98+
private string[] _promotionIds;
99+
/// <summary>
100+
/// Search orders with given promotions
101+
/// </summary>
102+
public string[] PromotionIds
103+
{
104+
get
105+
{
106+
if (_promotionIds.IsNullOrEmpty() && !string.IsNullOrEmpty(PromotionId))
107+
{
108+
_promotionIds = new[] { PromotionId };
109+
}
110+
return _promotionIds;
111+
}
112+
set
113+
{
114+
_promotionIds = value;
115+
}
116+
}
92117
}
93118
}

src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderDocumentBuilder.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public Task BuildSchemaAsync(IndexDocument schema)
5454
schema.AddFilterableString("OuterId");
5555
schema.AddFilterableString("Status");
5656
schema.AddFilterableString("Currency");
57+
schema.AddFilterableString("PromotionId");
5758

5859
schema.AddFilterableDecimal("Total");
5960
schema.AddFilterableDecimal("SubTotal");
@@ -125,26 +126,31 @@ protected virtual async Task<IndexDocument> CreateDocument(CustomerOrder order)
125126
document.AddFilterableBoolean("IsCancelled", order.IsCancelled);
126127
document.AddFilterableBoolean("IsPrototype", order.IsPrototype);
127128

129+
IndexDiscounts(order.Discounts, document);
130+
128131
foreach (var address in order.Addresses ?? Enumerable.Empty<Address>())
129132
{
130133
IndexAddress(address, document);
131134
}
132135

133136
foreach (var lineItem in order.Items ?? Enumerable.Empty<LineItem>())
134137
{
138+
IndexDiscounts(lineItem.Discounts, document);
135139
document.AddContentString(lineItem.Comment);
136140
}
137141

138142
foreach (var payment in order.InPayments ?? Enumerable.Empty<PaymentIn>())
139143
{
140144
IndexAddress(payment.BillingAddress, document);
145+
IndexDiscounts(payment.Discounts, document);
141146
document.AddContentString(payment.Number);
142147
document.AddContentString(payment.Comment);
143148
}
144149

145150
foreach (var shipment in order.Shipments ?? Enumerable.Empty<Shipment>())
146151
{
147152
IndexAddress(shipment.DeliveryAddress, document);
153+
IndexDiscounts(shipment.Discounts, document);
148154
document.AddContentString(shipment.Number);
149155
document.AddContentString(shipment.Comment);
150156

@@ -171,5 +177,16 @@ protected virtual void IndexAddress(Address address, IndexDocument document)
171177
document.AddContentString($"{address.AddressType} {address}");
172178
}
173179
}
180+
181+
protected virtual void IndexDiscounts(ICollection<VirtoCommerce.CoreModule.Core.Common.Discount> discounts, IndexDocument document)
182+
{
183+
if(discounts!=null)
184+
{
185+
foreach (var discount in discounts.Where(d => d != null && !string.IsNullOrEmpty(d.PromotionId)))
186+
{
187+
document.AddFilterableString("PromotionId", discount.PromotionId);
188+
}
189+
}
190+
}
174191
}
175192
}

src/VirtoCommerce.OrdersModule.Data/Search/Indexed/CustomerOrderSearchRequestBuilder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ protected virtual IList<IFilter> GetPermanentFilters(CustomerOrderSearchCriteria
173173
result.Add(FilterHelper.CreateTermFilter("isprototype", "false"));
174174
}
175175

176+
if (!criteria.PromotionIds.IsNullOrEmpty())
177+
{
178+
result.Add(FilterHelper.CreateTermFilter("promotionid", criteria.PromotionIds));
179+
}
180+
176181
return result;
177182
}
178183

src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderSearchService.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ protected override IQueryable<CustomerOrderEntity> BuildQuery(IRepository reposi
8181
query = query.Where(o => o.Items.Any(i => i.ProductId == criteria.ProductId));
8282
}
8383

84+
query = WithPromotionConditions(query, criteria);
85+
8486
return query;
8587
}
8688

@@ -175,5 +177,21 @@ private static IQueryable<CustomerOrderEntity> WithSubscriptionConditions(IQuery
175177

176178
return query;
177179
}
180+
181+
private static IQueryable<CustomerOrderEntity> WithPromotionConditions(IQueryable<CustomerOrderEntity> query, CustomerOrderSearchCriteria criteria)
182+
{
183+
if (!criteria.PromotionIds.IsNullOrEmpty())
184+
{
185+
// Check if any discount in the order, shipments, payments, or line items has the promotion ID
186+
query = query.Where(o =>
187+
(o.Discounts != null && o.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId))) ||
188+
(o.Shipments != null && o.Shipments.Any(s => s.Discounts != null && s.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId)))) ||
189+
(o.InPayments != null && o.InPayments.Any(p => p.Discounts != null && p.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId)))) ||
190+
(o.Items != null && o.Items.Any(i => i.Discounts != null && i.Discounts.Any(d => criteria.PromotionIds.Contains(d.PromotionId))))
191+
);
192+
}
193+
194+
return query;
195+
}
178196
}
179197
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
angular.module('virtoCommerce.orderModule')
2+
.controller('virtoCommerce.orderModule.operationDiscountsController', [
3+
'$scope',
4+
'platformWebApp.uiGridHelper',
5+
function ($scope, uiGridHelper) {
6+
var blade = $scope.blade;
7+
8+
blade.title = 'orders.blades.customerOrder-item-discounts.title';
9+
blade.headIcon = 'fa fa-area-chart';
10+
11+
$scope.setGridOptions = function (gridOptions) {
12+
uiGridHelper.initialize($scope, gridOptions, function (gridApi) {
13+
$scope.gridApi = gridApi;
14+
});
15+
};
16+
17+
blade.isLoading = false;
18+
}
19+
]);
20+
21+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<div class="blade-content __medium-wide">
2+
<div class="blade-inner">
3+
<div class="inner-block" ng-init="setGridOptions({
4+
rowTemplate: 'discounts-list.row.html',
5+
data: 'blade.currentEntity.discounts',
6+
enableSorting: false,
7+
columnDefs: [
8+
{ name: 'name', displayName: 'orders.blades.customerOrder-item-discounts.labels.name'},
9+
{ name: 'coupon', displayName: 'orders.blades.customerOrder-item-discounts.labels.coupon' },
10+
{ name: 'discountAmount', displayName: 'orders.blades.customerOrder-item-discounts.labels.discountAmount' },
11+
{ name: 'currency', displayName: 'orders.blades.customerOrder-item-discounts.labels.currency' }
12+
]})">
13+
<div class="table-wrapper" ng-if="(blade.currentEntity.discounts || []).length" style="margin: 0 -21px 0;">
14+
<div ui-grid="gridOptions" ui-grid-auto-resize ui-grid-save-state ui-grid-resize-columns ui-grid-move-columns ui-grid-pinning ui-grid-height></div>
15+
</div>
16+
<div class="note" ng-if="!(blade.currentEntity.discounts || []).length">{{ 'orders.blades.customerOrder-item-discounts.descr.no-discounts' | translate }}</div>
17+
</div>
18+
</div>
19+
</div>
20+
21+
<script type="text/ng-template" id="discounts-list.row.html">
22+
<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'" class="ui-grid-cell" ng-class="{'ui-grid-row-header-cell': col.isRowHeader, '__hovered': grid.appScope.contextMenuEntity === row.entity}" role="{{col.isRowHeader ? 'rowheader' : 'gridcell' }}" ui-grid-cell></div>
23+
</script>
24+
25+

src/VirtoCommerce.OrdersModule.Web/Scripts/order.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,11 +851,14 @@ angular.module(moduleName, [
851851
}
852852
});
853853

854-
var customerOrderItemDiscountWidget = {
855-
controller: 'virtoCommerce.orderModule.customerOrderItemDiscountWidgetController',
856-
template: 'Modules/$(VirtoCommerce.Orders)/Scripts/widgets/customerOrder-item-discounts-widget.tpl.html'
854+
var operationDiscountsWidget = {
855+
controller: 'virtoCommerce.orderModule.operationDiscountWidgetController',
856+
template: 'Modules/$(VirtoCommerce.Orders)/Scripts/widgets/operation-discounts-widget.tpl.html'
857857
};
858-
widgetService.registerWidget(customerOrderItemDiscountWidget, 'customerOrderItemDetailWidgets');
858+
widgetService.registerWidget(operationDiscountsWidget, 'customerOrderDetailWidgets');
859+
widgetService.registerWidget(operationDiscountsWidget, 'paymentDetailWidgets');
860+
widgetService.registerWidget(operationDiscountsWidget, 'shipmentDetailWidgets');
861+
widgetService.registerWidget(operationDiscountsWidget, 'customerOrderItemDetailWidgets');
859862

860863
var customerOrderItemConfigurationWidget = {
861864
controller: 'virtoCommerce.orderModule.customerOrderItemConfigurationWidgetController',
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
angular.module('virtoCommerce.orderModule')
2+
.controller('virtoCommerce.orderModule.operationDiscountWidgetController', [
3+
'$scope',
4+
'platformWebApp.bladeNavigationService',
5+
function ($scope, bladeNavigationService) {
6+
var blade = $scope.blade;
7+
8+
$scope.openBlade = function () {
9+
var newBlade = {
10+
id: "operationDiscounts",
11+
controller: 'virtoCommerce.orderModule.operationDiscountsController',
12+
template: 'Modules/$(VirtoCommerce.Orders)/Scripts/blades/operation-discounts.tpl.html',
13+
currentEntity: blade.currentEntity,
14+
};
15+
16+
bladeNavigationService.showBlade(newBlade, blade);
17+
};
18+
}
19+
]);
20+
21+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="gridster-cnt" ng-click="openBlade()">
2+
<div class="cnt-inner">
3+
<div class="list-count">{{(blade.currentEntity.discounts || []).length | number:0}}</div>
4+
<div class="list-t">{{ 'orders.widgets.customerOrder-item-discounts.title' | translate }}</div>
5+
</div>
6+
</div>
7+
8+

0 commit comments

Comments
 (0)