All order flow goes through Purchase BFF API. Also some refactorings.
This commit is contained in:
parent
2a81a080ba
commit
b0d4ae5a72
@ -235,6 +235,7 @@ services:
|
|||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- urls__basket=http://basket.api
|
- urls__basket=http://basket.api
|
||||||
- urls__catalog=http://catalog.api
|
- urls__catalog=http://catalog.api
|
||||||
|
- urls__orders=http://ordering.api
|
||||||
- urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
- urls__identity=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5110.
|
||||||
ports:
|
ports:
|
||||||
- "5120:80"
|
- "5120:80"
|
||||||
|
@ -15,10 +15,16 @@ namespace PurchaseBff.Config
|
|||||||
public class BasketOperations
|
public class BasketOperations
|
||||||
{
|
{
|
||||||
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
||||||
public static string UpdateBasket() => $"/api/v1/basket";
|
public static string UpdateBasket() => "/api/v1/basket";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrdersOperations
|
||||||
|
{
|
||||||
|
public static string GetOrderDraft() => "/api/v1/orders/draft";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Basket { get; set; }
|
public string Basket { get; set; }
|
||||||
public string Catalog { get; set; }
|
public string Catalog { get; set; }
|
||||||
|
public string Orders { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,9 @@ namespace PurchaseBff.Controllers
|
|||||||
|
|
||||||
// Step 1: Get the item from catalog
|
// Step 1: Get the item from catalog
|
||||||
var item = await _catalog.GetCatalogItem(data.CatalogItemId);
|
var item = await _catalog.GetCatalogItem(data.CatalogItemId);
|
||||||
|
|
||||||
|
//item.PictureUri =
|
||||||
|
|
||||||
// Step 2: Get current basket status
|
// Step 2: Get current basket status
|
||||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
|
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
|
||||||
// Step 3: Merge current status with new product
|
// Step 3: Merge current status with new product
|
||||||
|
@ -13,9 +13,11 @@ namespace PurchaseBff.Controllers
|
|||||||
public class OrderController : Controller
|
public class OrderController : Controller
|
||||||
{
|
{
|
||||||
private readonly IBasketService _basketService;
|
private readonly IBasketService _basketService;
|
||||||
public OrderController(IBasketService basketService)
|
private readonly IOrderApiClient _orderClient;
|
||||||
|
public OrderController(IBasketService basketService, IOrderApiClient orderClient)
|
||||||
{
|
{
|
||||||
_basketService = basketService;
|
_basketService = basketService;
|
||||||
|
_orderClient = orderClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("draft/{basketId}")]
|
[Route("draft/{basketId}")]
|
||||||
@ -33,8 +35,8 @@ namespace PurchaseBff.Controllers
|
|||||||
return BadRequest($"No basket found for id {basketId}");
|
return BadRequest($"No basket found for id {basketId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var order = _basketService.MapBasketToOrder(basket, isDraft: true);
|
var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket);
|
||||||
return Ok(order);
|
return Ok(orderDraft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,31 +44,6 @@ namespace PurchaseBff.Services
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderData MapBasketToOrder(BasketData basket, bool isDraft)
|
|
||||||
{
|
|
||||||
var order = new OrderData
|
|
||||||
{
|
|
||||||
Total = 0,
|
|
||||||
IsDraft = isDraft
|
|
||||||
};
|
|
||||||
|
|
||||||
basket.Items.ForEach(x =>
|
|
||||||
{
|
|
||||||
order.OrderItems.Add(new OrderItemData()
|
|
||||||
{
|
|
||||||
ProductId = int.Parse(x.ProductId),
|
|
||||||
|
|
||||||
PictureUrl = x.PictureUrl,
|
|
||||||
ProductName = x.ProductName,
|
|
||||||
Units = x.Quantity,
|
|
||||||
UnitPrice = x.UnitPrice
|
|
||||||
});
|
|
||||||
order.Total += (x.Quantity * x.UnitPrice);
|
|
||||||
});
|
|
||||||
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<string> GetUserTokenAsync()
|
async Task<string> GetUserTokenAsync()
|
||||||
{
|
{
|
||||||
var context = _httpContextAccessor.HttpContext;
|
var context = _httpContextAccessor.HttpContext;
|
||||||
|
@ -11,6 +11,5 @@ namespace PurchaseBff.Services
|
|||||||
Task<BasketData> GetById(string id);
|
Task<BasketData> GetById(string id);
|
||||||
Task Update(BasketData currentBasket);
|
Task Update(BasketData currentBasket);
|
||||||
|
|
||||||
OrderData MapBasketToOrder(BasketData basket, bool isDraft);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/BFFs/PurchaseBff/Services/IOrderApiClient.cs
Normal file
13
src/BFFs/PurchaseBff/Services/IOrderApiClient.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using PurchaseBff.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PurchaseBff.Services
|
||||||
|
{
|
||||||
|
public interface IOrderApiClient
|
||||||
|
{
|
||||||
|
Task<OrderData> GetOrderDraftFromBasket(BasketData basket);
|
||||||
|
}
|
||||||
|
}
|
37
src/BFFs/PurchaseBff/Services/OrderApiClient.cs
Normal file
37
src/BFFs/PurchaseBff/Services/OrderApiClient.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PurchaseBff.Config;
|
||||||
|
using PurchaseBff.Models;
|
||||||
|
|
||||||
|
namespace PurchaseBff.Services
|
||||||
|
{
|
||||||
|
public class OrderApiClient : IOrderApiClient
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IHttpClient _apiClient;
|
||||||
|
private readonly ILogger<OrderApiClient> _logger;
|
||||||
|
private readonly UrlsConfig _urls;
|
||||||
|
|
||||||
|
public OrderApiClient(IHttpClient httpClient, ILogger<OrderApiClient> logger, IOptionsSnapshot<UrlsConfig> config)
|
||||||
|
{
|
||||||
|
_apiClient = httpClient;
|
||||||
|
_logger = logger;
|
||||||
|
_urls = config.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<OrderData> GetOrderDraftFromBasket(BasketData basket)
|
||||||
|
{
|
||||||
|
var url = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
|
||||||
|
var response = await _apiClient.PostAsync<BasketData>(url, basket);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
return JsonConvert.DeserializeObject<OrderData>(jsonResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ namespace PurchaseBff
|
|||||||
services.AddSingleton<IHttpClient, StandardHttpClient>();
|
services.AddSingleton<IHttpClient, StandardHttpClient>();
|
||||||
services.AddTransient<ICatalogService, CatalogService>();
|
services.AddTransient<ICatalogService, CatalogService>();
|
||||||
services.AddTransient<IBasketService, BasketService>();
|
services.AddTransient<IBasketService, BasketService>();
|
||||||
|
services.AddTransient<IOrderApiClient, OrderApiClient>();
|
||||||
|
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
services.Configure<UrlsConfig>(Configuration.GetSection("urls"));
|
services.Configure<UrlsConfig>(Configuration.GetSection("urls"));
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"urls": {
|
"urls": {
|
||||||
"basket": "http://localhost:55105",
|
"basket": "http://localhost:55105",
|
||||||
"catalog": "http://localhost:55101",
|
"catalog": "http://localhost:55101",
|
||||||
"identity": "http://localhost:55105"
|
"orders": "http://localhost:55102",
|
||||||
|
"identity": "http://localhost:55105"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:57622/",
|
"applicationUrl": "http://localhost:50920/",
|
||||||
"sslPort": 0
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -66,6 +66,11 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
var item = await _catalogContext.CatalogItems.SingleOrDefaultAsync(ci => ci.Id == id);
|
var item = await _catalogContext.CatalogItems.SingleOrDefaultAsync(ci => ci.Id == id);
|
||||||
|
|
||||||
|
var baseUri = _settings.PicBaseUrl;
|
||||||
|
var azureStorageEnabled = _settings.AzureStorageEnabled;
|
||||||
|
item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
return Ok(item);
|
return Ok(item);
|
||||||
@ -244,13 +249,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
|||||||
private List<CatalogItem> ChangeUriPlaceholder(List<CatalogItem> items)
|
private List<CatalogItem> ChangeUriPlaceholder(List<CatalogItem> items)
|
||||||
{
|
{
|
||||||
var baseUri = _settings.PicBaseUrl;
|
var baseUri = _settings.PicBaseUrl;
|
||||||
|
var azureStorageEnabled = _settings.AzureStorageEnabled;
|
||||||
|
|
||||||
items.ForEach(catalogItem =>
|
foreach (var item in items)
|
||||||
{
|
{
|
||||||
catalogItem.PictureUri = _settings.AzureStorageEnabled
|
item.FillProductUrl(baseUri, azureStorageEnabled: azureStorageEnabled);
|
||||||
? baseUri + catalogItem.PictureFileName
|
}
|
||||||
: baseUri.Replace("[0]", catalogItem.Id.ToString());
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model
|
||||||
|
{
|
||||||
|
public static class CatalogItemExtensions
|
||||||
|
{
|
||||||
|
public static void FillProductUrl(this CatalogItem item, string picBaseUrl, bool azureStorageEnabled)
|
||||||
|
{
|
||||||
|
item.PictureUri = azureStorageEnabled
|
||||||
|
? picBaseUrl + item.PictureFileName
|
||||||
|
: picBaseUrl.Replace("[0]", item.Id.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using Ordering.API.Application.Models;
|
using Ordering.API.Application.Models;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||||
{
|
{
|
||||||
@ -68,7 +69,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
|||||||
string cardNumber, string cardHolderName, DateTime cardExpiration,
|
string cardNumber, string cardHolderName, DateTime cardExpiration,
|
||||||
string cardSecurityNumber, int cardTypeId) : this()
|
string cardSecurityNumber, int cardTypeId) : this()
|
||||||
{
|
{
|
||||||
_orderItems = MapToOrderItems(basketItems);
|
_orderItems = basketItems.ToOrderItemsDTO().ToList();
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
City = city;
|
City = city;
|
||||||
Street = street;
|
Street = street;
|
||||||
@ -83,20 +84,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
|||||||
CardExpiration = cardExpiration;
|
CardExpiration = cardExpiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<OrderItemDTO> MapToOrderItems(List<BasketItem> basketItems)
|
|
||||||
{
|
|
||||||
var result = new List<OrderItemDTO>();
|
|
||||||
basketItems.ForEach((item) => {
|
|
||||||
result.Add(new OrderItemDTO() {
|
|
||||||
ProductId = int.TryParse(item.ProductId, out int id) ? id : -1,
|
|
||||||
ProductName = item.ProductName,
|
|
||||||
PictureUrl = item.PictureUrl,
|
|
||||||
UnitPrice = item.UnitPrice,
|
|
||||||
Units = item.Quantity
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OrderItemDTO
|
public class OrderItemDTO
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||||
|
using Ordering.API.Application.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||||
|
|
||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||||
|
{
|
||||||
|
public class CreateOrderDraftCommand : IRequest<OrderDraftDTO>
|
||||||
|
{
|
||||||
|
|
||||||
|
public string BuyerId { get; private set; }
|
||||||
|
|
||||||
|
public IEnumerable<BasketItem> Items { get; private set; }
|
||||||
|
|
||||||
|
public CreateOrderDraftCommand(string buyerId, IEnumerable<BasketItem> items)
|
||||||
|
{
|
||||||
|
BuyerId = buyerId;
|
||||||
|
Items = items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
|
||||||
|
{
|
||||||
|
using Domain.AggregatesModel.OrderAggregate;
|
||||||
|
using global::Ordering.API.Application.Models;
|
||||||
|
using MediatR;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||||
|
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||||
|
|
||||||
|
// Regular CommandHandler
|
||||||
|
public class CreateOrderDraftCommandHandler
|
||||||
|
: IRequestHandler<CreateOrderDraftCommand, OrderDraftDTO>
|
||||||
|
{
|
||||||
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
private readonly IIdentityService _identityService;
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
// Using DI to inject infrastructure persistence Repositories
|
||||||
|
public CreateOrderDraftCommandHandler(IMediator mediator, IIdentityService identityService)
|
||||||
|
{
|
||||||
|
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
|
||||||
|
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<OrderDraftDTO> Handle(CreateOrderDraftCommand message, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
|
||||||
|
var order = Order.NewDraft();
|
||||||
|
var orderItems = message.Items.Select(i => i.ToOrderItemDTO());
|
||||||
|
foreach (var item in orderItems)
|
||||||
|
{
|
||||||
|
order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, item.Units);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(OrderDraftDTO.FromOrder(order));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class OrderDraftDTO
|
||||||
|
{
|
||||||
|
public IEnumerable<OrderItemDTO> OrderItems { get; set; }
|
||||||
|
public decimal Total { get; set; }
|
||||||
|
|
||||||
|
public static OrderDraftDTO FromOrder(Order order)
|
||||||
|
{
|
||||||
|
return new OrderDraftDTO()
|
||||||
|
{
|
||||||
|
OrderItems = order.OrderItems.Select(oi => new OrderItemDTO
|
||||||
|
{
|
||||||
|
Discount = oi.GetCurrentDiscount(),
|
||||||
|
ProductId = oi.ProductId,
|
||||||
|
UnitPrice = oi.GetUnitPrice(),
|
||||||
|
PictureUrl = oi.GetPictureUri(),
|
||||||
|
Units = oi.GetUnits(),
|
||||||
|
ProductName = oi.GetOrderItemProductName()
|
||||||
|
}),
|
||||||
|
Total = order.GetTotal()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
|
|||||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
|
||||||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
|
||||||
using Ordering.API.Application.Commands;
|
using Ordering.API.Application.Commands;
|
||||||
|
using Ordering.API.Application.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -101,6 +102,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
|||||||
|
|
||||||
return Ok(cardTypes);
|
return Ok(cardTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("draft")]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand)
|
||||||
|
{
|
||||||
|
var draft = await _mediator.Send(createOrderDraftCommand);
|
||||||
|
return Ok(draft);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
|
||||||
|
|
||||||
|
namespace Ordering.API.Application.Models
|
||||||
|
{
|
||||||
|
public static class BasketItemExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<OrderItemDTO> ToOrderItemsDTO(this IEnumerable<BasketItem> basketItems)
|
||||||
|
{
|
||||||
|
foreach (var item in basketItems)
|
||||||
|
{
|
||||||
|
yield return item.ToOrderItemDTO();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OrderItemDTO ToOrderItemDTO(this BasketItem item)
|
||||||
|
{
|
||||||
|
return new OrderItemDTO()
|
||||||
|
{
|
||||||
|
ProductId = int.TryParse(item.ProductId, out int id) ? id : -1,
|
||||||
|
ProductName = item.ProductName,
|
||||||
|
PictureUrl = item.PictureUrl,
|
||||||
|
UnitPrice = item.UnitPrice,
|
||||||
|
Units = item.Quantity
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:5102/",
|
"applicationUrl": "http://localhost:55102/",
|
||||||
"sslPort": 0
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"Microsoft.eShopOnContainers.Services.Ordering.API": {
|
"Microsoft.eShopOnContainers.Services.Ordering.API": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "http://localhost:5000/api/environmentInfo/machinename",
|
"launchUrl": "http://localhost:55102/",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
|
|
||||||
private string _description;
|
private string _description;
|
||||||
|
|
||||||
|
|
||||||
|
// Draft orders have this set to true. Currently we don't check anywhere the draft status of an Order, but we could do it if needed
|
||||||
|
private bool _isDraft;
|
||||||
|
|
||||||
// DDD Patterns comment
|
// DDD Patterns comment
|
||||||
// Using a private collection field, better for DDD Aggregate's encapsulation
|
// Using a private collection field, better for DDD Aggregate's encapsulation
|
||||||
// so OrderItems cannot be added from "outside the AggregateRoot" directly to the collection,
|
// so OrderItems cannot be added from "outside the AggregateRoot" directly to the collection,
|
||||||
@ -34,12 +38,21 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
|
|
||||||
private int? _paymentMethodId;
|
private int? _paymentMethodId;
|
||||||
|
|
||||||
protected Order() { _orderItems = new List<OrderItem>(); }
|
public static Order NewDraft()
|
||||||
|
{
|
||||||
|
var order = new Order();
|
||||||
|
order._isDraft = true;
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Order() {
|
||||||
|
_orderItems = new List<OrderItem>();
|
||||||
|
_isDraft = false;
|
||||||
|
}
|
||||||
|
|
||||||
public Order(string userId, Address address, int cardTypeId, string cardNumber, string cardSecurityNumber,
|
public Order(string userId, Address address, int cardTypeId, string cardNumber, string cardSecurityNumber,
|
||||||
string cardHolderName, DateTime cardExpiration, int? buyerId = null, int? paymentMethodId = null)
|
string cardHolderName, DateTime cardExpiration, int? buyerId = null, int? paymentMethodId = null) : this()
|
||||||
{
|
{
|
||||||
_orderItems = new List<OrderItem>();
|
|
||||||
_buyerId = buyerId;
|
_buyerId = buyerId;
|
||||||
_paymentMethodId = paymentMethodId;
|
_paymentMethodId = paymentMethodId;
|
||||||
_orderStatusId = OrderStatus.Submitted.Id;
|
_orderStatusId = OrderStatus.Submitted.Id;
|
||||||
@ -92,12 +105,12 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void SetAwaitingValidationStatus()
|
public void SetAwaitingValidationStatus()
|
||||||
{
|
{
|
||||||
if (_orderStatusId == OrderStatus.Submitted.Id)
|
if (_orderStatusId == OrderStatus.Submitted.Id)
|
||||||
{
|
{
|
||||||
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
|
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
|
||||||
_orderStatusId = OrderStatus.AwaitingValidation.Id;
|
_orderStatusId = OrderStatus.AwaitingValidation.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStockConfirmedStatus()
|
public void SetStockConfirmedStatus()
|
||||||
@ -108,7 +121,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
|
|
||||||
_orderStatusId = OrderStatus.StockConfirmed.Id;
|
_orderStatusId = OrderStatus.StockConfirmed.Id;
|
||||||
_description = "All the items were confirmed with available stock.";
|
_description = "All the items were confirmed with available stock.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPaidStatus()
|
public void SetPaidStatus()
|
||||||
@ -119,7 +132,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
|
|
||||||
_orderStatusId = OrderStatus.Paid.Id;
|
_orderStatusId = OrderStatus.Paid.Id;
|
||||||
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
|
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetShippedStatus()
|
public void SetShippedStatus()
|
||||||
@ -157,13 +170,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
|
|
||||||
var itemsStockRejectedDescription = string.Join(", ", itemsStockRejectedProductNames);
|
var itemsStockRejectedDescription = string.Join(", ", itemsStockRejectedProductNames);
|
||||||
_description = $"The product items don't have stock: ({itemsStockRejectedDescription}).";
|
_description = $"The product items don't have stock: ({itemsStockRejectedDescription}).";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber,
|
private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber,
|
||||||
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
|
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
|
||||||
{
|
{
|
||||||
var orderStartedDomainEvent = new OrderStartedDomainEvent(this, userId, cardTypeId,
|
var orderStartedDomainEvent = new OrderStartedDomainEvent(this, userId, cardTypeId,
|
||||||
cardNumber, cardSecurityNumber,
|
cardNumber, cardSecurityNumber,
|
||||||
cardHolderName, cardExpiration);
|
cardHolderName, cardExpiration);
|
||||||
|
|
||||||
|
@ -41,13 +41,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
_pictureUrl = PictureUrl;
|
_pictureUrl = PictureUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPictureUri(string pictureUri)
|
public string GetPictureUri() => _pictureUrl;
|
||||||
{
|
|
||||||
if (!String.IsNullOrWhiteSpace(pictureUri))
|
|
||||||
{
|
|
||||||
_pictureUrl = pictureUri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public decimal GetCurrentDiscount()
|
public decimal GetCurrentDiscount()
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:57625/",
|
"applicationUrl": "http://localhost:50921/",
|
||||||
"sslPort": 0
|
"sslPort": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user