This commit is contained in:
espent1004 2020-01-19 22:41:44 +01:00
parent f1328f721e
commit c3f6bf3698
27 changed files with 516 additions and 38 deletions

View File

@ -68,6 +68,8 @@ services:
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- AzureServiceBusEnabled=False - AzureServiceBusEnabled=False
- ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sql.data;Database=Microsoft.eShopOnContainers.Services.TenantADb;User Id=sa;Password=Pass@word}
ports: ports:
- "5116:80" - "5116:80"

View File

@ -48,6 +48,8 @@ services:
build: build:
context: . context: .
dockerfile: src/Services/TenantCustomisations/TenantACustomisations/Dockerfile dockerfile: src/Services/TenantCustomisations/TenantACustomisations/Dockerfile
depends_on:
- sql.data
catalog.api: catalog.api:
image: ${REGISTRY:-eshop}/catalog.api:${PLATFORM:-linux}-${TAG:-latest} image: ${REGISTRY:-eshop}/catalog.api:${PLATFORM:-linux}-${TAG:-latest}

View File

@ -12,6 +12,7 @@ using RabbitMQ.Client;
using RabbitMQ.Client.Events; using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions; using RabbitMQ.Client.Exceptions;
using System; using System;
using System.Diagnostics;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -280,6 +281,10 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ
else else
{ {
var handler = scope.ResolveOptional(subscription.HandlerType); var handler = scope.ResolveOptional(subscription.HandlerType);
if (eventName.Equals("OrderStatusChangedToSubmittedIntegrationEvent") || eventName.Equals("UserCheckoutAcceptedIntegrationEvent"))
{
Debug.WriteLine("Here");
}
if (handler == null) continue; if (handler == null) continue;
var eventType = _subsManager.GetEventTypeByName(eventName); var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType); var integrationEvent = JsonConvert.DeserializeObject(message, eventType);

View File

@ -12,7 +12,7 @@ using System;
namespace Ordering.API.Application.IntegrationEvents.EventHandling namespace Ordering.API.Application.IntegrationEvents.EventHandling
{ {
public class UserCheckoutAcceptedIntegrationEventHandler : AbstractIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>, IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent> public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>
{ {
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly IEventBus _eventBus; private readonly IEventBus _eventBus;
@ -20,7 +20,7 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
public UserCheckoutAcceptedIntegrationEventHandler( public UserCheckoutAcceptedIntegrationEventHandler(
IMediator mediator, IMediator mediator,
ILogger<UserCheckoutAcceptedIntegrationEventHandler> logger, IEventBus eventBus) : base(eventBus) ILogger<UserCheckoutAcceptedIntegrationEventHandler> logger, IEventBus eventBus)
{ {
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger)); _logger = logger ?? throw new ArgumentNullException(nameof(logger));
@ -42,9 +42,9 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
{ {
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event);
var customised = await CheckIfCustomised(@event); //var customised = await CheckIfCustomised(@event);
if (!customised) //if (!customised)
{ //{
var result = false; var result = false;
if (@event.RequestId != Guid.Empty) if (@event.RequestId != Guid.Empty)
@ -81,7 +81,7 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
{ {
_logger.LogWarning("Invalid IntegrationEvent - RequestId is missing - {@IntegrationEvent}", @event); _logger.LogWarning("Invalid IntegrationEvent - RequestId is missing - {@IntegrationEvent}", @event);
} }
} //}
} }
} }
} }

View File

@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TenantACustomisations.Database;
using TenantACustomisations.ExternalServices;
namespace TenantACustomisations.Controllers namespace TenantACustomisations.Controllers
{ {
@ -10,11 +13,21 @@ namespace TenantACustomisations.Controllers
[ApiController] [ApiController]
public class ValuesController : ControllerBase public class ValuesController : ControllerBase
{ {
private readonly TenantAContext _context;
public ValuesController(TenantAContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
// GET api/values // GET api/values
[HttpGet] [HttpGet]
public ActionResult<IEnumerable<string>> Get() public async Task<ActionResult<IEnumerable<ShippingInformation>>> GetShippingInformation()
{ {
return new string[] { "value1", "value2" }; return await _context.ShippingInformation.ToListAsync();
} }
// GET api/values/5 // GET api/values/5

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TenantACustomisations.ExternalServices;
namespace TenantACustomisations.Database
{
public class DbInitializer
{
public void Initialize(TenantAContext context)
{
context.Database.EnsureCreated();
if (context.ShippingInformation.Any())
{
return;
}
ShippingInformation shippingInformation = new ShippingInformation();
shippingInformation.ShippingTime = DateTime.Today;
shippingInformation.ArrivalTime = DateTime.Today.AddDays(2);
shippingInformation.FragilityLevel = Fragility.Medium;
shippingInformation.PriorityLevel = Priority.High;
shippingInformation.ShippingInformationId = 1;
shippingInformation.OrderNumber = 1;
context.ShippingInformation.Add(shippingInformation);
context.SaveChanges();
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using TenantACustomisations.ExternalServices;
namespace TenantACustomisations.Database
{
public class TenantAContext : DbContext
{
public TenantAContext(DbContextOptions<TenantAContext> options)
: base(options)
{
}
public DbSet<ShippingInformation> ShippingInformation { get; set; }
}
public class TenantAContextDesignFactory : IDesignTimeDbContextFactory<TenantAContext>
{
public TenantAContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<TenantAContext>()
.UseSqlServer("Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.TenantADb;Integrated Security=true");
return new TenantAContext(optionsBuilder.Options);
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.ExternalServices
{
public interface IRFIDService
{
bool IsOrderRFIDTagged(int orderNumber);
}
}

View File

@ -0,0 +1,13 @@
using Ordering.API.Application.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.ExternalServices
{
public interface IShippingService
{
ShippingInformation CalculateShippingInformation(int orderId);
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ordering.API.Application.Models;
namespace TenantACustomisations.ExternalServices
{
public class MockedShippingService : IShippingService
{
public ShippingInformation CalculateShippingInformation(int orderId)
{
ShippingInformation shippingInformation = new ShippingInformation();
shippingInformation.ShippingTime = DateTime.Today;
shippingInformation.ArrivalTime = DateTime.Today.AddDays(2);
shippingInformation.FragilityLevel = Fragility.Medium;
shippingInformation.PriorityLevel = Priority.High;
shippingInformation.OrderNumber = orderId;
return shippingInformation;
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.ExternalServices
{
public enum Fragility
{
Low, Medium, High
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.ExternalServices
{
public enum Priority
{
Low, Medium, High
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.ExternalServices
{
public class ShippingInformation
{
public int ShippingInformationId { get; set; }
public DateTime ArrivalTime { get; set; }
public DateTime ShippingTime { get; set; }
public Priority PriorityLevel {get;set;}
public Fragility FragilityLevel { get; set; }
public String OrderNumber { get; set; }
}
}

View File

@ -1,5 +1,8 @@
using Autofac; using Autofac;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System.Reflection; using System.Reflection;
using TenantACustomisations.ExternalServices;
using TenantACustomisations.IntegrationEvents.Events;
namespace Microsoft.eShopOnContainers.Services.TenantACustomisations.Infrastructure.AutofacModules namespace Microsoft.eShopOnContainers.Services.TenantACustomisations.Infrastructure.AutofacModules
{ {
@ -18,7 +21,13 @@ namespace Microsoft.eShopOnContainers.Services.TenantACustomisations.Infrastruct
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)
{ {
//TODO builder.RegisterAssemblyTypes(typeof(UserCheckoutAcceptedIntegrationEvent).GetTypeInfo().Assembly)
.AsClosedTypesOf(typeof(IIntegrationEventHandler<>));
builder.RegisterType<MockedShippingService>()
.As<IShippingService>()
.InstancePerLifetimeScope();
} }
} }
} }

View File

@ -0,0 +1,45 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using TenantACustomisations.Database;
using TenantACustomisations.ExternalServices;
using TenantACustomisations.IntegrationEvents.Events;
namespace TenantACustomisations.IntegrationEvents.EventHandling
{
public class OrderStatusChangedToSubmittedIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToSubmittedIntegrationEvent>
{
private readonly ILogger<OrderStatusChangedToSubmittedIntegrationEventHandler> _logger;
private readonly IShippingService _shippingService;
private readonly TenantAContext _context;
public OrderStatusChangedToSubmittedIntegrationEventHandler(ILogger<OrderStatusChangedToSubmittedIntegrationEventHandler> logger, IShippingService shippingService, TenantAContext context)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_shippingService = shippingService ?? throw new ArgumentNullException(nameof(shippingService));
_context = context ?? throw new ArgumentNullException(nameof(shippingService));
}
public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event)
{
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}- TenantA"))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at TenantA - ({@IntegrationEvent})", @event.Id, @event);
_logger.LogInformation("Hello");
//TODO
Debug.WriteLine(@event);
ShippingInformation shippingInformation = _shippingService.CalculateShippingInformation(@event.OrderId);
_context.ShippingInformation.Add(shippingInformation);
_logger.LogInformation("----- Saving shipping information: {IntegrationEventId} at TenantA - ({@IntegrationEvent}) - {@ShippingInformation}", @event.Id, @event, shippingInformation);
_context.SaveChanges();
}
}
}
}

View File

@ -0,0 +1,60 @@
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions;
using Microsoft.Extensions.Logging;
using Ordering.API.Application.Behaviors;
using Serilog.Context;
using System.Threading.Tasks;
using System;
using System.Diagnostics;
using TenantACustomisations.IntegrationEvents.Events;
using TenantACustomisations.ExternalServices;
using TenantACustomisations.Database;
namespace TenantACustomisations.IntegrationEvents.EventHandling
{
public class TenantAUserCheckoutAcceptedIntegrationEventHandler :
IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly IEventBus _eventBus;
private readonly ILogger<TenantAUserCheckoutAcceptedIntegrationEventHandler> _logger;
//private readonly TenantAContext _context;
//private readonly IShippingService _shippingService;
public TenantAUserCheckoutAcceptedIntegrationEventHandler(
IMediator mediator,
ILogger<TenantAUserCheckoutAcceptedIntegrationEventHandler> logger,
IEventBus eventBus
)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
}
/// <summary>
/// Integration event handler which starts the create order process
/// </summary>
/// <param name="@event">
/// Integration event message which is sent by the
/// basket.api once it has successfully process the
/// order items.
/// </param>
/// <returns></returns>
public async Task Handle(UserCheckoutAcceptedIntegrationEvent @event)
{
using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}- TenantA"))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at TenantA- ({@IntegrationEvent})", @event.Id, @event);
_logger.LogInformation("Hello");
//TODO
Debug.WriteLine(@event);
//Save shipping info
//Hard code view comp
//Retrieve shipping info and show
}
}
}
}

View File

@ -0,0 +1,22 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TenantACustomisations.IntegrationEvents.Events
{
public class OrderStatusChangedToSubmittedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public string OrderStatus { get; }
public string BuyerName { get; }
public OrderStatusChangedToSubmittedIntegrationEvent(int orderId, string orderStatus, string buyerName)
{
OrderId = orderId;
OrderStatus = orderStatus;
BuyerName = buyerName;
}
}
}

View File

@ -0,0 +1,62 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Ordering.API.Application.Models;
using System;
namespace TenantACustomisations.IntegrationEvents.Events
{
public class UserCheckoutAcceptedIntegrationEvent : IntegrationEvent
{
public string UserId { get; }
public string UserName { get; }
public string City { get; set; }
public string Street { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string ZipCode { get; set; }
public string CardNumber { get; set; }
public string CardHolderName { get; set; }
public DateTime CardExpiration { get; set; }
public string CardSecurityNumber { get; set; }
public int CardTypeId { get; set; }
public string Buyer { get; set; }
public Guid RequestId { get; set; }
public CustomerBasket Basket { get; }
public UserCheckoutAcceptedIntegrationEvent(string userId, string userName, string city, string street,
string state, string country, string zipCode, string cardNumber, string cardHolderName,
DateTime cardExpiration, string cardSecurityNumber, int cardTypeId, string buyer, Guid requestId,
CustomerBasket basket)
{
UserId = userId;
City = city;
Street = street;
State = state;
Country = country;
ZipCode = zipCode;
CardNumber = cardNumber;
CardHolderName = cardHolderName;
CardExpiration = cardExpiration;
CardSecurityNumber = cardSecurityNumber;
CardTypeId = cardTypeId;
Buyer = buyer;
Basket = basket;
RequestId = requestId;
UserName = userName;
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration;
using Serilog; using Serilog;
using System; using System;
using System.IO; using System.IO;
using TenantACustomisations.Database;
namespace Microsoft.eShopOnContainers.Services.TenantACustomisations namespace Microsoft.eShopOnContainers.Services.TenantACustomisations
{ {

View File

@ -35,6 +35,9 @@
using global::TenantACustomisations.Infrastructure.Filters; using global::TenantACustomisations.Infrastructure.Filters;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using global::TenantACustomisations.IntegrationEvents.EventHandling; using global::TenantACustomisations.IntegrationEvents.EventHandling;
using global::TenantACustomisations.IntegrationEvents.Events;
using global::TenantACustomisations.ExternalServices;
using global::TenantACustomisations.Database;
public class Startup public class Startup
{ {
@ -107,6 +110,11 @@
}); });
ConfigureEventBus(app); ConfigureEventBus(app);
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetRequiredService<TenantAContext>();
context.Database.EnsureCreated();
}
} }
@ -114,7 +122,9 @@
{ {
var eventBus = app.ApplicationServices.GetRequiredService<BuildingBlocks.EventBus.Abstractions.IEventBus>(); var eventBus = app.ApplicationServices.GetRequiredService<BuildingBlocks.EventBus.Abstractions.IEventBus>();
eventBus.Subscribe<CustomisationEvent, CustomisationEventHandler>(); //eventBus.Subscribe<UserCheckoutAcceptedIntegrationEvent, IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>>();
eventBus.Subscribe<OrderStatusChangedToSubmittedIntegrationEvent, OrderStatusChangedToSubmittedIntegrationEventHandler>();
} }
protected virtual void ConfigureAuth(IApplicationBuilder app) protected virtual void ConfigureAuth(IApplicationBuilder app)
@ -210,18 +220,8 @@
public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
{ {
//services.AddEntityFrameworkSqlServer() services.AddDbContext<TenantAContext>(options =>
// .AddDbContext<OrderingContext>(options => options.UseSqlServer(configuration["ConnectionString"]));
// {
// options.UseSqlServer(configuration["ConnectionString"],
// sqlServerOptionsAction: sqlOptions =>
// {
// sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
// sqlOptions.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
// });
// },
// ServiceLifetime.Scoped //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request)
// );
services.AddDbContext<IntegrationEventLogContext>(options => services.AddDbContext<IntegrationEventLogContext>(options =>
{ {
@ -276,7 +276,6 @@
sp => (DbConnection c) => new IntegrationEventLogService(c)); sp => (DbConnection c) => new IntegrationEventLogService(c));
//services.AddTransient<IOrderingIntegrationEventService, OrderingIntegrationEventService>(); //services.AddTransient<IOrderingIntegrationEventService, OrderingIntegrationEventService>();
if (configuration.GetValue<bool>("AzureServiceBusEnabled")) if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
{ {
services.AddSingleton<IServiceBusPersisterConnection>(sp => services.AddSingleton<IServiceBusPersisterConnection>(sp =>
@ -387,7 +386,7 @@
} }
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
services.AddTransient<CustomisationEventHandler>(); //services.AddTransient<TenantAUserCheckoutAcceptedIntegrationEventHandler>();
return services; return services;
} }

View File

@ -42,10 +42,6 @@
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="IntegrationEvents\Events\" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" /> <ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusServiceBus\EventBusServiceBus.csproj" />

View File

@ -12,7 +12,8 @@
} }
}, },
"IdentityUrl": "http://localhost:5105", "IdentityUrl": "http://localhost:5105",
"ConnectionString": "127.0.0.1", //"ConnectionString": "127.0.0.1",
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.TenantADb;User Id=sa;Password=Pass@word;",
"AzureServiceBusEnabled": false, "AzureServiceBusEnabled": false,
"SubscriptionClientName": "TenantACustomisation", "SubscriptionClientName": "TenantACustomisation",
"ApplicationInsights": { "ApplicationInsights": {

View File

@ -2,7 +2,14 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Services;
using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation;
using Newtonsoft.Json;
using Polly.CircuitBreaker; using Polly.CircuitBreaker;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers namespace Microsoft.eShopOnContainers.WebMVC.Controllers
@ -13,6 +20,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
private IOrderingService _orderSvc; private IOrderingService _orderSvc;
private IBasketService _basketSvc; private IBasketService _basketSvc;
private readonly IIdentityParser<ApplicationUser> _appUserParser; private readonly IIdentityParser<ApplicationUser> _appUserParser;
private static String url = @"http://tenantacustomisation/";
public OrderController(IOrderingService orderSvc, IBasketService basketSvc, IIdentityParser<ApplicationUser> appUserParser) public OrderController(IOrderingService orderSvc, IBasketService basketSvc, IIdentityParser<ApplicationUser> appUserParser)
{ {
_appUserParser = appUserParser; _appUserParser = appUserParser;
@ -75,7 +84,39 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
var user = _appUserParser.Parse(HttpContext.User); var user = _appUserParser.Parse(HttpContext.User);
var vm = await _orderSvc.GetMyOrders(user); var vm = await _orderSvc.GetMyOrders(user);
List<ShippingInformation> shippingInformation = GetShippingInfo(vm);
ViewData["ShippingInfo"] = shippingInformation;
return View(vm); return View(vm);
} }
private List<ShippingInformation> GetShippingInfo(List<Order> orders)
{
List<ShippingInformation> shippingInformation = new List<ShippingInformation>();
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
{
client.BaseAddress = new Uri(url);
try
{
HttpResponseMessage response = client.GetAsync("api/shippinginformation").Result;
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
List<ShippingInformation> results = JsonConvert.DeserializeObject<List<ShippingInformation>>(result);
results.ForEach( s =>
{
if(orders.Any(item => item.OrderNumber.Equals(s.OrderNumber)))
{
shippingInformation.Add(s);
}
});
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
return shippingInformation;
}
} }
} }

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation
{
public enum Fragility
{
Low, Medium, High
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation
{
public enum Priority
{
Low, Medium, High
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation
{
public class ShippingInformation
{
public int ShippingInformationId { get; set; }
public DateTime ArrivalTime { get; set; }
public DateTime ShippingTime { get; set; }
public Priority PriorityLevel { get; set; }
public Fragility FragilityLevel { get; set; }
public String OrderNumber { get; set; }
}
}

View File

@ -1,25 +1,31 @@
@using Microsoft.eShopOnContainers.WebMVC.ViewModels @using Microsoft.eShopOnContainers.WebMVC.ViewModels
@using Microsoft.eShopOnContainers.WebMVC.ViewModels.Customisation
@model IEnumerable<Microsoft.eShopOnContainers.WebMVC.ViewModels.Order> @model IEnumerable<Microsoft.eShopOnContainers.WebMVC.ViewModels.Order>
@{ @{
ViewData["Title"] = "My Orders"; ViewData["Title"] = "My Orders";
var headerList= new List<Header>() { var headerList = new List<Header>() {
new Header() { Controller = "Catalog", Text = "Back to catalog" }, new Header() { Controller = "Catalog", Text = "Back to catalog" },
new Header() { Text = " / " }, new Header() { Text = " / " },
new Header() { Controller = "OrderManagement", Text = "Orders Management" } }; new Header() { Controller = "OrderManagement", Text = "Orders Management" } };
var shippingInfo = ViewData["ShippingInfo"] as List<ShippingInformation>;
} }
<div class="esh-orders"> <div class="esh-orders">
<partial name="_Header" model="headerList"/> <partial name="_Header" model="headerList" />
<div class="container"> <div class="container">
<article class="esh-orders-titles row"> <article class="esh-orders-titles row">
<section class="esh-orders-title col-2">Order number</section> <section class="esh-orders-title col-2">Order number</section>
<section class="esh-orders-title col-4">Date</section> <section class="esh-orders-title col-2">Date</section>
<section class="esh-orders-title col-2">Total</section> <section class="esh-orders-title col-1">Total</section>
<section class="esh-orders-title col-2">Status</section> <section class="esh-orders-title col-1">Status</section>
<section class="esh-orders-title col-2">Shipping date</section>
<section class="esh-orders-title col-2">Estimated arrival date</section>
<section class="esh-orders-title col-2"></section> <section class="esh-orders-title col-2"></section>
</article> </article>
@if (Model != null && Model.Any()) @if (Model != null && Model.Any())
{ {
@ -27,9 +33,28 @@
{ {
<article class="esh-orders-items row"> <article class="esh-orders-items row">
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section> <section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section>
<section class="esh-orders-item col-4">@Html.DisplayFor(modelItem => item.Date)</section> <section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.Date)</section>
<section class="esh-orders-item col-2">$ @Html.DisplayFor(modelItem => item.Total)</section> <section class="esh-orders-item col-1">$ @Html.DisplayFor(modelItem => item.Total)</section>
<section class="esh-orders-item col-2">@Html.DisplayFor(modelItem => item.Status)</section> <section class="esh-orders-item col-1">@Html.DisplayFor(modelItem => item.Status)</section>
<section class="esh-orders-item col-2">
@for (var i = 0; i < shippingInfo.Count(); i++)
{
var si = shippingInfo[i];
if (si.OrderNumber.Equals(item.OrderNumber)){
@si.ShippingTime
}
}
</section>
<section class="esh-orders-item col-2">
@for (var i = 0; i < shippingInfo.Count(); i++)
{
var si = shippingInfo[i];
if (si.OrderNumber.Equals(item.OrderNumber))
{
@si.ArrivalTime
}
}
</section>
<section class="esh-orders-item col-1"> <section class="esh-orders-item col-1">
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a> <a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
</section> </section>