diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingDto.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingDto.cs new file mode 100644 index 00000000..bbb6db56 --- /dev/null +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingDto.cs @@ -0,0 +1,12 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EShopOnAbp.OrderingService.OrderItems +{ + public class TopSellingDto : EntityDto + { + public string ProductName { get; set; } + public string PictureUrl { get; set; } + public int Units { get; set; } + } +} diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingInput.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingInput.cs new file mode 100644 index 00000000..43bfc299 --- /dev/null +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderItems/TopSellingInput.cs @@ -0,0 +1,7 @@ +namespace EShopOnAbp.OrderingService.OrderItems +{ + public class TopSellingInput + { + public string Filter { get; set; } + } +} diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderingServiceRemoteServiceConsts.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderingServiceRemoteServiceConsts.cs index ca7531ee..8680b2a2 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderingServiceRemoteServiceConsts.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/OrderingServiceRemoteServiceConsts.cs @@ -1,7 +1,8 @@ namespace EShopOnAbp.OrderingService { - public class OrderingServiceRemoteServiceConsts + public static class OrderingServiceRemoteServiceConsts { public const string RemoteServiceName = "Ordering"; + public const int Top10 = 10; } } diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/Orders/IOrderAppService.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/Orders/IOrderAppService.cs index 90dd07f2..187bd82e 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/Orders/IOrderAppService.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application.Contracts/Orders/IOrderAppService.cs @@ -1,4 +1,5 @@ -using System; +using EShopOnAbp.OrderingService.OrderItems; +using System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; @@ -16,5 +17,6 @@ public interface IOrderAppService : IApplicationService Task SetAsCancelledAsync(Guid id, SetAsCancelledDto input); Task SetAsShippedAsync(Guid id); Task> GetListPagedAsync(PagedAndSortedResultRequestDto input); + Task> GetTopSellingAsync(TopSellingInput input); } \ No newline at end of file diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application/OrderingServiceApplicationAutoMapperProfile.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application/OrderingServiceApplicationAutoMapperProfile.cs index 2153beb2..2746a0a8 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Application/OrderingServiceApplicationAutoMapperProfile.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application/OrderingServiceApplicationAutoMapperProfile.cs @@ -1,5 +1,6 @@ using AutoMapper; using EShopOnAbp.OrderingService.Orders; +using EShopOnAbp.OrderingService.OrderItems; using Volo.Abp.AutoMapper; namespace EShopOnAbp.OrderingService @@ -12,7 +13,8 @@ namespace EShopOnAbp.OrderingService CreateMap(); CreateMap(); - + CreateMap (); + CreateMap() .Ignore(q => q.Address) .Ignore(q => q.Items) diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs b/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs index 213aac33..6eac463f 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Application/Orders/OrderAppService.cs @@ -1,4 +1,5 @@ using EShopOnAbp.OrderingService.Localization; +using EShopOnAbp.OrderingService.OrderItems; using EShopOnAbp.OrderingService.Orders.Specifications; using EShopOnAbp.OrderingService.Permissions; using Microsoft.AspNetCore.Authorization; @@ -43,7 +44,7 @@ public class OrderAppService : ApplicationService, IOrderAppService return CreateOrderDtoMapping(orders); } - //[Authorize(OrderingServicePermissions.Orders.Default)] + [Authorize(OrderingServicePermissions.Orders.Default)] public async Task> GetOrdersAsync(GetOrdersInput input) { ISpecification specification = SpecificationFactory.Create(input.Filter); @@ -70,6 +71,13 @@ public class OrderAppService : ApplicationService, IOrderAppService ); } + public async Task> GetTopSellingAsync(TopSellingInput input) + { + ISpecification specification = SpecificationFactory.Create(input.Filter); + var orderItems = await _orderRepository.GetTopSelling(specification, true); + return ObjectMapper.Map, List>(orderItems); + } + public async Task GetByOrderNoAsync(int orderNo) { var order = await _orderRepository.GetByOrderNoAsync(orderNo); diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain/Orders/IOrderRepository.cs b/services/ordering/src/EShopOnAbp.OrderingService.Domain/Orders/IOrderRepository.cs index c031ea4f..cdec07a6 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Domain/Orders/IOrderRepository.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain/Orders/IOrderRepository.cs @@ -20,6 +20,11 @@ public interface IOrderRepository : IRepository bool includeDetails = true, CancellationToken cancellationToken = default); + Task> GetTopSelling( + ISpecification spec, + bool includeDetails = true, + CancellationToken cancellationToken = default); + Task GetByOrderNoAsync(int orderNo, bool includeDetails = true, CancellationToken cancellationToken = default); diff --git a/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/EShopOnAbp.OrderingService.EntityFrameworkCore.csproj b/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/EShopOnAbp.OrderingService.EntityFrameworkCore.csproj index 169c680b..26d3ea23 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/EShopOnAbp.OrderingService.EntityFrameworkCore.csproj +++ b/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/EShopOnAbp.OrderingService.EntityFrameworkCore.csproj @@ -9,6 +9,7 @@ + diff --git a/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/Orders/EfCoreOrderRepository.cs b/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/Orders/EfCoreOrderRepository.cs index c1fbe930..28974037 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/Orders/EfCoreOrderRepository.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.EntityFrameworkCore/Orders/EfCoreOrderRepository.cs @@ -54,6 +54,24 @@ public class EfCoreOrderRepository : EfCoreRepository> GetTopSelling( + ISpecification spec, + bool includeDetails = true, + CancellationToken cancellationToken = default) + { + return (await (await GetDbSetAsync()) + .IncludeDetails(includeDetails) + .Where(spec.ToExpression()) + .SelectMany(oi => oi.OrderItems) + .GroupBy(p => p.ProductCode) + .OrderByDescending(o => o.Sum(p => p.Units)) + .Select(o => o.ToList()) + .ToListAsync()) + .SelectMany(t => t) + .Take(OrderingServiceRemoteServiceConsts.Top10) + .ToList(); + } + public async Task GetByOrderNoAsync( int orderNo, bool includeDetails = true, diff --git a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/OrderClientProxy.Generated.cs b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/OrderClientProxy.Generated.cs index f51841db..f4ddeb66 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/OrderClientProxy.Generated.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/OrderClientProxy.Generated.cs @@ -8,6 +8,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Client.ClientProxying; using EShopOnAbp.OrderingService.Orders; using System.Collections.Generic; +using EShopOnAbp.OrderingService.OrderItems; // ReSharper disable once CheckNamespace namespace EShopOnAbp.OrderingService.Orders.ClientProxies; @@ -48,6 +49,14 @@ public partial class OrderClientProxy : ClientProxyBase, IOrde }); } + public virtual async Task> GetTopSellingAsync(TopSellingInput input) + { + return await RequestAsync>(nameof(GetTopSellingAsync), new ClientProxyRequestTypeValue + { + { typeof(TopSellingInput), input } + }); + } + public virtual async Task GetByOrderNoAsync(int orderNo) { return await RequestAsync(nameof(GetByOrderNoAsync), new ClientProxyRequestTypeValue diff --git a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/ordering-generate-proxy.json b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/ordering-generate-proxy.json index f437165f..21aa866b 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/ordering-generate-proxy.json +++ b/services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Client/ClientProxies/ordering-generate-proxy.json @@ -195,6 +195,43 @@ "allowAnonymous": false, "implementFrom": "EShopOnAbp.OrderingService.Orders.IOrderAppService" }, + "GetTopSellingAsyncByInput": { + "uniqueName": "GetTopSellingAsyncByInput", + "name": "GetTopSellingAsync", + "httpMethod": "GET", + "url": "api/ordering/order/top-selling", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "EShopOnAbp.OrderingService.OrderItems.TopSellingInput, EShopOnAbp.OrderingService.Application.Contracts", + "type": "EShopOnAbp.OrderingService.OrderItems.TopSellingInput", + "typeSimple": "EShopOnAbp.OrderingService.OrderItems.TopSellingInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "Filter", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "System.Collections.Generic.List", + "typeSimple": "[EShopOnAbp.OrderingService.OrderItems.TopSellingDto]" + }, + "allowAnonymous": null, + "implementFrom": "EShopOnAbp.OrderingService.Orders.IOrderAppService" + }, "GetByOrderNoAsyncByOrderNo": { "uniqueName": "GetByOrderNoAsyncByOrderNo", "name": "GetByOrderNoAsync", diff --git a/services/ordering/test/EShopOnAbp.OrderingService.Application.Tests/Orders/OrderApplication_Tests.cs b/services/ordering/test/EShopOnAbp.OrderingService.Application.Tests/Orders/OrderApplication_Tests.cs index 2d581037..5adf2e5e 100644 --- a/services/ordering/test/EShopOnAbp.OrderingService.Application.Tests/Orders/OrderApplication_Tests.cs +++ b/services/ordering/test/EShopOnAbp.OrderingService.Application.Tests/Orders/OrderApplication_Tests.cs @@ -66,15 +66,6 @@ public class OrderApplication_Tests : OrderingServiceApplicationTestBase var myOrder = await _orderAppService.GetByOrderNoAsync(placedOrder.OrderNo); myOrder.ShouldNotBeNull(); - - var cancelledMyOrder = await _orderAppService.SetAsCancelledAsync(placedOrder.Id, new SetAsCancelledDto() - { - OrderStatusId = OrderStatus.Shipped.Id, - }); - //TODO - temp value - it should be Shipped - cancelledMyOrder.OrderStatus.ShouldBe(OrderStatus.Placed.ToString()); - - // Get all orders var orders = await _orderAppService.GetOrdersAsync(new GetOrdersInput() {