Skip to content

Commit

Permalink
Merge pull request #11 from Kentico/feat/admin_and_customer_endpoint_…
Browse files Browse the repository at this point in the history
…split

Feat/admin and customer endpoint split
  • Loading branch information
martinfbluesoftcz authored May 29, 2024
2 parents 4e3a3da + 3728285 commit c4b3144
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 29 deletions.
6 changes: 4 additions & 2 deletions docs/Usage-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ Not all cart's data can be changed, e.g. custom data (properties like ShoppingCa
via API.

### Orders
- Endpoint `api/store/order/list` for retrieving list of orders based on request (supports paging)
- Endpoint `api/store/order/list` for retrieving list of orders for current customer based on request (supports paging)
- Endpoint `api/store/order/admin/list` for retrieving list of orders (for all customers) based on request (supports paging) to display in XbyK administration (supports paging)

### Customers
- Endpoint `api/store/customer/addresses` for retrieving customer's addresses
- Endpoint `api/store/customer/addresses` for retrieving current customer's addresses
- Endpoint `api/store/customer/admin/addresses` for retrieving addresses of specific customer to display in XbyK administration

### Store site
- Endpoint `api/store/site/cultures` returns all enabled site cultures
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public async Task<IActionResult> TestSetCurrency(string currencyCode)
}

public async Task<JsonResult> TestOrders([FromServices] IOrderService orderService)
=> Json(await orderService.GetOrderList(new OrderListRequest { Page = 1, PageSize = 10, OrderBy = "OrderID DESC" }));
=> Json(await orderService.GetCurrentCustomerOrderList(new OrderListRequest { Page = 1, PageSize = 10, OrderBy = "OrderID DESC" }));
}
#endif
4 changes: 2 additions & 2 deletions examples/DancingGoat-K13Ecommerce/Services/CheckoutService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public async Task<DeliveryDetailsViewModel> PrepareDeliveryDetailsViewModel(Cust
customer ??= new CustomerViewModel(await shoppingService.GetCustomerOrCreateFromAuthenticatedUser(cartDetails.Customer));

var addresses = (cartDetails.Customer != null)
? await customerService.GetCustomerAddresses(cartDetails.Customer.CustomerId)
? await customerService.GetCurrentCustomerAddresses()
: Enumerable.Empty<KAddress>();

var billingAddresses = new SelectList(addresses, nameof(KAddress.AddressId), nameof(KAddress.AddressName));
Expand Down Expand Up @@ -114,7 +114,7 @@ public async Task<bool> IsStateValid(int countryId, int? stateId)

public async Task<KAddress> GetAddress(int customerId, int addressId) =>
customerId > 0 && addressId > 0
? (await customerService.GetCustomerAddresses(customerId)).FirstOrDefault(a => a.AddressId == addressId)
? (await customerService.GetCurrentCustomerAddresses()).FirstOrDefault(a => a.AddressId == addressId)
: null;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ namespace Kentico.Xperience.K13Ecommerce.Customers;
internal class CustomerService(IKenticoStoreApiClient apiClient) : ICustomerService
{
/// <inheritdoc/>
public async Task<ICollection<KAddress>> GetCustomerAddresses(int customerId) =>
await apiClient.CustomerAddressesAsync(customerId);
public async Task<ICollection<KAddress>> GetCurrentCustomerAddresses() =>
await apiClient.CurrentCustomerAddressesAsync();


/// <inheritdoc/>
public async Task<ICollection<KAddress>> GetAdminCustomerAddresses(int customerId) =>
await apiClient.AdminCustomerAddressesAsync(customerId);
}
13 changes: 9 additions & 4 deletions src/Kentico.Xperience.K13Ecommerce/Customers/ICustomerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ namespace Kentico.Xperience.K13Ecommerce.Customers;
public interface ICustomerService
{
/// <summary>
/// Get list of addresses for given customer.
/// Get list of addresses for current customer.
/// </summary>
Task<ICollection<KAddress>> GetCurrentCustomerAddresses();


/// <summary>
/// Get list of addresses for customer with specified ID to display in XByK administration.
/// </summary>
/// <param name="customerId">Customer ID.</param>
/// <returns></returns>
Task<ICollection<KAddress>> GetCustomerAddresses(int customerId);
/// <param name="customerId">Customer ID.</param>
Task<ICollection<KAddress>> GetAdminCustomerAddresses(int customerId);
}
12 changes: 10 additions & 2 deletions src/Kentico.Xperience.K13Ecommerce/Orders/IOrderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ namespace Kentico.Xperience.K13Ecommerce.Orders;
public interface IOrderService
{
/// <summary>
/// Get orders based on parameters.
/// Get orders based on parameters for current customer.
/// </summary>
/// <param name="request">Request parameters for order listing.</param>
/// <returns>Paged list of orders.</returns>
Task<OrderListResponse> GetOrderList(OrderListRequest request);
Task<OrderListResponse> GetCurrentCustomerOrderList(OrderListRequest request);


/// <summary>
/// Get orders based on parameters to display in XbyK administration (for all customers).
/// </summary>
/// <param name="request">Request parameters for order listing.</param>
/// <returns>Paged list of orders.</returns>
Task<OrderListResponse> GetAdminOrderList(OrderListRequest request);
}
9 changes: 7 additions & 2 deletions src/Kentico.Xperience.K13Ecommerce/Orders/OrderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ namespace Kentico.Xperience.K13Ecommerce.Orders;
internal class OrderService(IKenticoStoreApiClient storeApiClient) : IOrderService
{
/// <inheritdoc/>
public async Task<OrderListResponse> GetOrderList(OrderListRequest request)
=> await storeApiClient.OrderListAsync(request.Page, request.PageSize, request.OrderBy);
public async Task<OrderListResponse> GetCurrentCustomerOrderList(OrderListRequest request)
=> await storeApiClient.CurrentCustomerOrderListAsync(request.Page, request.PageSize, request.OrderBy);


///<inheritdoc/>
public async Task<OrderListResponse> GetAdminOrderList(OrderListRequest request)
=> await storeApiClient.AdminOrderListAsync(request.Page, request.PageSize, request.OrderBy);
}
102 changes: 97 additions & 5 deletions src/Kentico.Xperience.K13Ecommerce/StoreApi/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,47 @@
"tags": [
"Customer"
],
"summary": "Endpoint for customer addresses.",
"operationId": "CustomerAddresses",
"summary": "Endpoint for current customer addresses.",
"operationId": "CurrentCustomerAddresses",
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/KAddress"
}
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
}
}
},
"/api/store/customer/admin/addresses": {
"get": {
"tags": [
"Customer"
],
"summary": "Endpoint for given customer addresses to display in XbyK administration.",
"operationId": "AdminCustomerAddresses",
"parameters": [
{
"name": "customerId",
"in": "query",
"description": "",
"description": "Customer ID",
"required": true,
"schema": {
"type": "integer",
Expand Down Expand Up @@ -182,8 +216,66 @@
"tags": [
"Order"
],
"summary": "Endpoint for getting list of orders based on request.",
"operationId": "OrderList",
"summary": "Endpoint for getting list of current customer's orders based on request.",
"operationId": "CurrentCustomerOrderList",
"parameters": [
{
"name": "Page",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "PageSize",
"in": "query",
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer",
"format": "int32"
}
},
{
"name": "OrderBy",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OrderListResponse"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
}
}
},
"/api/store/order/admin/list": {
"get": {
"tags": [
"Order"
],
"summary": "Endpoint for getting list of orders based on request to display in XbyK administration.",
"operationId": "AdminOrderList",
"parameters": [
{
"name": "Page",
Expand Down
29 changes: 24 additions & 5 deletions src/Kentico.Xperience.StoreApi/Customers/CustomerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,39 @@ public class CustomerController : ControllerBase
{
private readonly IAddressInfoProvider addressInfoProvider;
private readonly IMapper mapper;
private readonly IShoppingService shoppingService;

public CustomerController(IAddressInfoProvider addressInfoProvider, IMapper mapper)
public CustomerController(IAddressInfoProvider addressInfoProvider, IMapper mapper, IShoppingService shoppingService)
{
this.addressInfoProvider = addressInfoProvider;
this.mapper = mapper;
this.shoppingService = shoppingService;
}

/// <summary>
/// Endpoint for customer addresses.
/// Endpoint for current customer addresses.
/// </summary>
/// <param name="customerId"></param>
/// <returns></returns>
[HttpGet("addresses", Name = nameof(CustomerAddresses))]
public ActionResult<IEnumerable<KAddress>> CustomerAddresses([FromQuery][Required] int customerId)
[HttpGet("addresses", Name = nameof(CurrentCustomerAddresses))]
public ActionResult<IEnumerable<KAddress>> CurrentCustomerAddresses()
{
var cart = shoppingService.GetCurrentShoppingCart();
if (cart.Customer is null)
{
return Ok(Enumerable.Empty<KAddress>());
}
var addresses = mapper.Map<IEnumerable<KAddress>>(addressInfoProvider.GetByCustomer(cart.Customer.CustomerID));
return Ok(addresses);
}


/// <summary>
/// Endpoint for given customer addresses to display in XbyK administration.
/// </summary>
/// <param name="customerId">Customer ID</param>
/// <returns></returns>
[HttpGet("admin/addresses", Name = nameof(AdminCustomerAddresses))]
public ActionResult<IEnumerable<KAddress>> AdminCustomerAddresses([FromQuery][Required] int customerId)
{
var addresses = mapper.Map<IEnumerable<KAddress>>(addressInfoProvider.GetByCustomer(customerId));
return Ok(addresses);
Expand Down
56 changes: 52 additions & 4 deletions src/Kentico.Xperience.StoreApi/Orders/OrderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,69 @@ public class OrderController : ControllerBase
private readonly IOrderInfoProvider orderInfoProvider;
private readonly IMapper mapper;
private readonly ISiteService siteService;
private readonly IShoppingService shoppingService;

public OrderController(IOrderInfoProvider orderInfoProvider, IMapper mapper, ISiteService siteService)
public OrderController(
IOrderInfoProvider orderInfoProvider,
IMapper mapper,
ISiteService siteService,
IShoppingService shoppingService)
{
this.orderInfoProvider = orderInfoProvider;
this.mapper = mapper;
this.siteService = siteService;
this.shoppingService = shoppingService;
}

/// <summary>
/// Endpoint for getting list of orders based on request.
/// Endpoint for getting list of current customer's orders based on request.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("list", Name = nameof(OrderList))]
public async Task<ActionResult<OrderListResponse>> OrderList([FromQuery] OrderListRequest request)
[HttpGet("list", Name = nameof(CurrentCustomerOrderList))]
public async Task<ActionResult<OrderListResponse>> CurrentCustomerOrderList([FromQuery] OrderListRequest request)
{
int page = request.Page > 0 ? request.Page - 1 : 0;
if (string.IsNullOrWhiteSpace(request.OrderBy))
{
request.OrderBy = $"{nameof(OrderInfo.OrderDate)} DESC";
}

var cart = shoppingService.GetCurrentShoppingCart();
if (cart.Customer is null)
{
return Ok(new OrderListResponse
{
Orders = Enumerable.Empty<KOrder>(),
MaxPage = 1,
Page = 1
});
}

var orderQuery = orderInfoProvider.Get()
.WhereEquals(nameof(OrderInfo.OrderCustomerID), cart.Customer.CustomerID)
.OnSite(siteService.CurrentSite.SiteID)
.Page(page, request.PageSize)
.OrderBy(request.OrderBy);

var orders = mapper.Map<IEnumerable<KOrder>>(await orderQuery.GetEnumerableTypedResultAsync());

return Ok(new OrderListResponse
{
Orders = orders,
Page = page + 1,
MaxPage = (orderQuery.TotalRecords / request.PageSize) + 1
});
}


/// <summary>
/// Endpoint for getting list of orders based on request to display in XbyK administration.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("admin/list", Name = nameof(AdminOrderList))]
public async Task<ActionResult<OrderListResponse>> AdminOrderList([FromQuery] OrderListRequest request)
{
int page = request.Page > 0 ? request.Page - 1 : 0;
if (string.IsNullOrWhiteSpace(request.OrderBy))
Expand Down

0 comments on commit c4b3144

Please sign in to comment.