diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 5a35f5e8b..4dfa4dc63 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,15 +9,15 @@ version: '2' services: - webmvc: - environment: - - CatalogUrl=http://catalog.api - - OrderingUrl=http://ordering.api:5102 +# webmvc: +# environment: +# - CatalogUrl=http://catalog.api +# - OrderingUrl=http://ordering.api:5102 #- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105. - - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. - - BasketUrl=http://basket.api:5103 - ports: - - "5100:5100" +# - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. +# - BasketUrl=http://basket.api:5103 +# ports: +# - "5100:5100" webspa: environment: @@ -39,38 +39,31 @@ services: catalog.api: environment: - - ConnectionString=Server=business.data;Database=CatalogDB;User Id=sa;Password=Pass@word + - ConnectionString=Server=sql.data;Database=CatalogDB;User Id=sa;Password=Pass@word ports: - "5101:80" - ordering.api: - environment: - - ConnectionString=Server=business.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word - - identityUrl=http://identity.service:5105 #local +# ordering.api: +# environment: +# - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word +# - identityUrl=http://identity.service:5105 #local #- identityUrl=http://104.40.62.65:5105 #remote - ports: - - "5102:5102" +# ports: +# - "5102:5102" identity.service: environment: - SpaClient=http://localhost:5104 - - ConnectionStrings__DefaultConnection=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word + - ConnectionStrings__DefaultConnection=Server=sql.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word #- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105. - MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker. #10.0.75.1:5105 CCE/TODO: try to avoid host entry. ports: - "5105:5105" - identity.data: + sql.data: environment: - SA_PASSWORD=Pass@word - ACCEPT_EULA=Y ports: - "5433:1433" - - business.data: - environment: - - SA_PASSWORD=Pass@word - - ACCEPT_EULA=Y - ports: - - "5434:1433" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index f103237cf..c8dc1797f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,11 +7,11 @@ version: '2' services: - webmvc: - image: eshop/web - depends_on: - - identity.service - - basket.api +# webmvc: +# image: eshop/web +# depends_on: +# - identity.service +# - basket.api webspa: image: eshop/webspa @@ -28,22 +28,19 @@ services: catalog.api: image: eshop/catalog.api depends_on: - - business.data + - sql.data - ordering.api: - image: eshop/ordering.api - depends_on: - - business.data +# ordering.api: +# image: eshop/ordering.api +# depends_on: +# - sql.data identity.service: image: eshop/identity depends_on: - - identity.data - - identity.data: - image: microsoft/mssql-server-linux + - sql.data - business.data: + sql.data: image: microsoft/mssql-server-linux basket.data: diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index c666066e4..7ef0fc8df 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -1,4 +1,4 @@ -{ +{ "Logging": { "IncludeScopes": false, "LogLevel": { @@ -7,6 +7,6 @@ "Microsoft": "Information" } }, - "IdentityUrl": "http://localhost:5000", + "IdentityUrl": "http://identity.service:5105", "ConnectionString": "127.0.0.1" } diff --git a/src/Services/Catalog/Catalog.API/settings.json b/src/Services/Catalog/Catalog.API/settings.json index d3a58585d..bac26f3b5 100644 --- a/src/Services/Catalog/Catalog.API/settings.json +++ b/src/Services/Catalog/Catalog.API/settings.json @@ -1,5 +1,5 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5434;Initial Catalog=CatalogDB;User Id=sa;Password=Pass@word", + "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=CatalogDB;User Id=sa;Password=Pass@word", "Logging": { "IncludeScopes": false, "LogLevel": { diff --git a/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs b/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs index f66ad52a0..3223feefd 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs @@ -99,7 +99,7 @@ namespace IdentityServer4.Quickstart.UI.Controllers props = new AuthenticationProperties { IsPersistent = true, - ExpiresUtc = DateTimeOffset.UtcNow.AddMonths(1) + ExpiresUtc = DateTimeOffset.UtcNow.AddYears(10) }; }; diff --git a/src/Services/Identity/eShopOnContainers.Identity/Data/ApplicationContextSeed.cs b/src/Services/Identity/eShopOnContainers.Identity/Data/ApplicationContextSeed.cs index 0d0fb85f0..8a413c139 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Data/ApplicationContextSeed.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Data/ApplicationContextSeed.cs @@ -61,7 +61,6 @@ CardType = 1, City = "Redmond", Country = "U.S.", - CountryCode = "91", Email = "demouser@microsoft.com", Expiration = "12/20", Id = Guid.NewGuid().ToString(), diff --git a/src/Services/Identity/eShopOnContainers.Identity/Data/Migrations/20161019122215_Init_Scheme.cs b/src/Services/Identity/eShopOnContainers.Identity/Data/Migrations/20161019122215_Init_Scheme.cs index 8e9d6f205..278c3f422 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Data/Migrations/20161019122215_Init_Scheme.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Data/Migrations/20161019122215_Init_Scheme.cs @@ -49,14 +49,11 @@ namespace WebMVC.Migrations City = table.Column(nullable: true), ConcurrencyStamp = table.Column(nullable: true), Country = table.Column(nullable: true), - CountryCode = table.Column(nullable: true), Email = table.Column(maxLength: 256, nullable: true), EmailConfirmed = table.Column(nullable: false), Expiration = table.Column(nullable: true), - Latitude = table.Column(nullable: false), LockoutEnabled = table.Column(nullable: false), LockoutEnd = table.Column(nullable: true), - Longitude = table.Column(nullable: false), NormalizedEmail = table.Column(maxLength: 256, nullable: true), NormalizedUserName = table.Column(maxLength: 256, nullable: true), PasswordHash = table.Column(nullable: true), @@ -65,7 +62,6 @@ namespace WebMVC.Migrations SecurityNumber = table.Column(nullable: true), SecurityStamp = table.Column(nullable: true), State = table.Column(nullable: true), - StateCode = table.Column(nullable: true), Street = table.Column(nullable: true), TwoFactorEnabled = table.Column(nullable: false), UserName = table.Column(maxLength: 256, nullable: true), diff --git a/src/Services/Identity/eShopOnContainers.Identity/Extensions/PrincipalExtensions.cs b/src/Services/Identity/eShopOnContainers.Identity/Extensions/PrincipalExtensions.cs deleted file mode 100644 index a1247cb92..000000000 --- a/src/Services/Identity/eShopOnContainers.Identity/Extensions/PrincipalExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Principal; -using System.Threading.Tasks; - -namespace eShopOnContainers.Identity.Extensions -{ - //public static class PrincipalExtensions - //{ - // public static string GetSubjectId(this IPrincipal principal) - // { - // return principal.Identity.GetSubjectId(); - // } - //} -} diff --git a/src/Services/Identity/eShopOnContainers.Identity/Models/ApplicationUser.cs b/src/Services/Identity/eShopOnContainers.Identity/Models/ApplicationUser.cs index 72e6b97ea..5d009b718 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Models/ApplicationUser.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Models/ApplicationUser.cs @@ -10,21 +10,29 @@ namespace eShopOnContainers.Identity.Models // Add profile data for application users by adding properties to the ApplicationUser class public class ApplicationUser : IdentityUser { + [Required] public string CardNumber { get; set; } + [Required] public string SecurityNumber { get; set; } + [Required] + [RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "Expiration should match a valid MM/YY value")] public string Expiration { get; set; } + [Required] public string CardHolderName { get; set; } public int CardType { get; set; } + [Required] public string Street { get; set; } + [Required] public string City { get; set; } + [Required] public string State { get; set; } - public string StateCode { get; set; } + [Required] public string Country { get; set; } - public string CountryCode { get; set; } + [Required] public string ZipCode { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } + [Required] public string Name { get; set; } + [Required] public string LastName { get; set; } } } diff --git a/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json b/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json index 725e1c299..622822efc 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json +++ b/src/Services/Identity/eShopOnContainers.Identity/Properties/launchSettings.json @@ -11,7 +11,7 @@ "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, - "launchUrl": "http://localhost:5000", + "launchUrl": "http://localhost:5105", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Identity/eShopOnContainers.Identity/Services/ProfileService.cs b/src/Services/Identity/eShopOnContainers.Identity/Services/ProfileService.cs index e30a6ca7e..79a419382 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Services/ProfileService.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Services/ProfileService.cs @@ -88,6 +88,9 @@ namespace eShopOnContainers.Identity.Services if (!string.IsNullOrWhiteSpace(user.SecurityNumber)) claims.Add(new Claim("card_security_number", user.SecurityNumber)); + if (!string.IsNullOrWhiteSpace(user.Expiration)) + claims.Add(new Claim("card_expiration", user.Expiration)); + if (!string.IsNullOrWhiteSpace(user.City)) claims.Add(new Claim("address_city", user.City)); diff --git a/src/Services/Identity/eShopOnContainers.Identity/appsettings.json b/src/Services/Identity/eShopOnContainers.Identity/appsettings.json index 8fbc03c5a..0048c419f 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/appsettings.json +++ b/src/Services/Identity/eShopOnContainers.Identity/appsettings.json @@ -1,8 +1,8 @@ -{ +{ "ConnectionStrings": { "DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word" }, - "MvcClient": "http://localhost:5001", + "MvcClient": "http://localhost:5100", "SpaClient": "http://localhost:5104", "Logging": { "IncludeScopes": false, diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index 0dd1b269a..b3a4a477b 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Models; using System; + using System.Collections.Generic; using System.Threading.Tasks; [Route("api/v1/[controller]")] @@ -34,38 +35,14 @@ [Route("new")] [HttpPost] - public async Task AddOrder([FromBody]NewOrderViewModel order) + public async Task AddOrder([FromBody]NewOrderRequest order) { if (order.CardExpiration == DateTime.MinValue) order.CardExpiration = DateTime.Now; - var newOrderRequest = new NewOrderRequest() - { - Buyer = GetUserName(), - CardTypeId = 1, //TODO - CardHolderName = order.CardHolderName, - CardNumber = order.CardNumber, - CardExpiration = order.CardExpiration, - CardSecurityNumber = order.CardSecurityNumber, - State = order.ShippingState, - City = order.ShippingCity, - Country = order.ShippingCountry, - Street = order.ShippingStreet - }; - - foreach (var orderItem in order.Items) - { - newOrderRequest.AddOrderItem(new Domain.OrderItem() { - Discount = orderItem.Discount, - ProductId = orderItem.ProductId, - UnitPrice = orderItem.UnitPrice, - ProductName = orderItem.ProductName, - Units = orderItem.Units - }); - } - - var added = await _mediator.SendAsync(newOrderRequest); + order.Buyer = GetUserName(); + var added = await _mediator.SendAsync(order); if (added) { return Ok(); @@ -78,9 +55,15 @@ [HttpGet] public async Task GetOrder(int orderId) { - var order = await _orderQueries.GetOrder(orderId); - - return Ok(order); + try + { + var order = await _orderQueries.GetOrder(orderId); + return Ok(order); + } + catch (KeyNotFoundException) + { + return NotFound(); + } } [Route("")] diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs index e60cf281f..e6ac74cee 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs @@ -172,6 +172,7 @@ namespace Ordering.API.Infrastructure.Migrations OrderId = table.Column(nullable: false), ProductId = table.Column(nullable: false), ProductName = table.Column(nullable: false), + PictureUrl = table.Column(nullable: false), UnitPrice = table.Column(nullable: false), Units = table.Column(nullable: false, defaultValue: 1) }, diff --git a/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs b/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs index 989993fc2..8a2f42d52 100644 --- a/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs +++ b/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs @@ -11,5 +11,7 @@ public decimal Discount { get; set; } public int Units { get; set; } + + public string PictureUrl { get; set; } } } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 7aa3c94a4..d5daf106e 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -15,9 +15,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) - //.UseIISIntegration() - .UseStartup() .UseUrls("http://0.0.0.0:5102") + .UseIISIntegration() + .UseStartup() .Build(); host.Run(); diff --git a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json index c2ecdd3e6..2e24c9099 100644 --- a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:5002/", + "applicationUrl": "http://localhost:5102/", "sslPort": 0 } }, diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json deleted file mode 100644 index fa8ce71a9..000000000 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/src/Services/Ordering/Ordering.API/settings.json b/src/Services/Ordering/Ordering.API/settings.json index eb9bb0cc6..ea67d33a8 100644 --- a/src/Services/Ordering/Ordering.API/settings.json +++ b/src/Services/Ordering/Ordering.API/settings.json @@ -1,4 +1,12 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5434;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "IdentityUrl": "http://localhost:5105" + "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", + "IdentityUrl": "http://identity.service:5105", + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } } diff --git a/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs index 7697f7262..db877cf31 100644 --- a/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs +++ b/src/Services/Ordering/Ordering.Application/Queries/OrderQueries.cs @@ -5,6 +5,8 @@ using System.Data.SqlClient; using System.Threading.Tasks; using System; + using System.Dynamic; + using System.Collections.Generic; public class OrderQueries :IOrderQueries @@ -16,14 +18,29 @@ _connectionString = configuration["ConnectionString"]; } - + public async Task GetOrder(int id) { using (var connection = new SqlConnection(_connectionString)) { connection.Open(); - return await connection.QueryAsync("SELECT * FROM ordering.Orders where Id=@id",new { id }); + var result = await connection.QueryAsync( + @"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status, + oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl, + oa.Street as street, oa.City as city, oa.Country as country, oa.State as state, oa.ZipCode as zipcode + FROM ordering.Orders o + LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid + LEFT JOIN ordering.orderstatus os on o.StatusId = os.Id + LEFT JOIN ordering.address oa on o.ShippingAddressId = oa.Id + WHERE o.Id=@id" + , new { id } + ); + + if (result.AsList().Count == 0) + throw new KeyNotFoundException(); + + return MapOrderItems(result); } } @@ -50,5 +67,35 @@ return await connection.QueryAsync("SELECT * FROM ordering.cardtypes"); } } + + private dynamic MapOrderItems(dynamic result) + { + dynamic order = new ExpandoObject(); + + order.ordernumber = result[0].ordernumber; + order.date = result[0].date; + order.status = result[0].status; + order.street = result[0].street; + order.city = result[0].city; + order.zipcode = result[0].zipcode; + order.country = result[0].country; + + order.orderitems = new List(); + order.total = 0; + + foreach (dynamic item in result) + { + dynamic orderitem = new ExpandoObject(); + orderitem.productname = item.productname; + orderitem.units = item.units; + orderitem.unitprice = item.unitprice; + orderitem.pictureurl = item.pictureurl; + + order.total += item.units * item.unitprice; + order.orderitems.Add(orderitem); + } + + return order; + } } } diff --git a/src/Services/Ordering/Ordering.Domain/OrderItem.cs b/src/Services/Ordering/Ordering.Domain/OrderItem.cs index 625e56da0..c305f0e03 100644 --- a/src/Services/Ordering/Ordering.Domain/OrderItem.cs +++ b/src/Services/Ordering/Ordering.Domain/OrderItem.cs @@ -10,6 +10,8 @@ public string ProductName { get; set; } + public string PictureUrl { get; set; } + public int OrderId { get; set; } public decimal UnitPrice { get; set; } diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index 0bb499341..646349de9 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.Models; using Microsoft.AspNetCore.Authorization; -using Microsoft.eShopOnContainers.WebMVC.Models.OrderViewModels; +using System.Net.Http; namespace Microsoft.eShopOnContainers.WebMVC.Controllers { @@ -25,31 +25,22 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers public async Task Create() { - var vm = new CreateOrderViewModel(); var user = _appUserParser.Parse(HttpContext.User); var basket = await _basketSvc.GetBasket(user); var order = _basketSvc.MapBasketToOrder(basket); - vm.Order = _orderSvc.MapUserInfoIntoOrder(user, order); + var vm = _orderSvc.MapUserInfoIntoOrder(user, order); + vm.CardExpirationShortFormat(); return View(vm); } [HttpPost] - public async Task Create(CreateOrderViewModel model, Dictionary quantities, string action) + public async Task Create(Order model, string action) { var user = _appUserParser.Parse(HttpContext.User); - var basket = await _basketSvc.SetQuantities(user, quantities); - basket = await _basketSvc.UpdateBasket(basket); - var order = _basketSvc.MapBasketToOrder(basket); - - - // override if user has changed some shipping address or payment info data. - _orderSvc.OverrideUserInfoIntoOrder(model.Order, order); - if (action == "[ Place Order ]") { - - await _orderSvc.CreateOrder(user, order); + await _orderSvc.CreateOrder(model); //Empty basket for current user. await _basketSvc.CleanBasket(user); @@ -61,11 +52,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers return View(model); } - public IActionResult Detail(string orderId) + public async Task Detail(string orderId) { var user = _appUserParser.Parse(HttpContext.User); - var order = _orderSvc.GetOrder(user, orderId); + var order = await _orderSvc.GetOrder(user, orderId); return View(order); } diff --git a/src/Web/WebMVC/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs deleted file mode 100644 index c256b098c..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/ExternalLoginConfirmationViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class ExternalLoginConfirmationViewModel - { - [Required] - [EmailAddress] - public string Email { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/ForgotPasswordViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/ForgotPasswordViewModel.cs deleted file mode 100644 index 74bbada93..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/ForgotPasswordViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class ForgotPasswordViewModel - { - [Required] - [EmailAddress] - public string Email { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/LoginViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/LoginViewModel.cs deleted file mode 100644 index cc5245149..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/LoginViewModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class LoginViewModel - { - [Required] - [EmailAddress] - public string Email { get; set; } - - [Required] - [DataType(DataType.Password)] - public string Password { get; set; } - - [Display(Name = "Remember me?")] - public bool RememberMe { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/RegisterViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/RegisterViewModel.cs deleted file mode 100644 index 4c863b652..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/RegisterViewModel.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class RegisterViewModel - { - [Required] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - - public ApplicationUser User { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/ResetPasswordViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/ResetPasswordViewModel.cs deleted file mode 100644 index 0ae402f4c..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/ResetPasswordViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class ResetPasswordViewModel - { - [Required] - [EmailAddress] - public string Email { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - public string Password { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - - public string Code { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/SendCodeViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/SendCodeViewModel.cs deleted file mode 100644 index 8fc47bdb1..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/SendCodeViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Rendering; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class SendCodeViewModel - { - public string SelectedProvider { get; set; } - - public ICollection Providers { get; set; } - - public string ReturnUrl { get; set; } - - public bool RememberMe { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/AccountViewModels/VerifyCodeViewModel.cs b/src/Web/WebMVC/Models/AccountViewModels/VerifyCodeViewModel.cs deleted file mode 100644 index bdc893691..000000000 --- a/src/Web/WebMVC/Models/AccountViewModels/VerifyCodeViewModel.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -{ - public class VerifyCodeViewModel - { - [Required] - public string Provider { get; set; } - - [Required] - public string Code { get; set; } - - public string ReturnUrl { get; set; } - - [Display(Name = "Remember this browser?")] - public bool RememberBrowser { get; set; } - - [Display(Name = "Remember me?")] - public bool RememberMe { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/Address.cs b/src/Web/WebMVC/Models/Address.cs deleted file mode 100644 index 28bc90e2c..000000000 --- a/src/Web/WebMVC/Models/Address.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models -{ - public class Address - { - public Guid Id { get; set; } - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - public string StateCode { get; set; } - public string Country { get; set; } - public string CountryCode { get; set; } - public string ZipCode { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/Annotations/CardExpiration.cs b/src/Web/WebMVC/Models/Annotations/CardExpiration.cs new file mode 100644 index 000000000..96644d790 --- /dev/null +++ b/src/Web/WebMVC/Models/Annotations/CardExpiration.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.WebMVC.Models.Annotations +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] + public class CardExpirationAttribute : ValidationAttribute + { + public override bool IsValid(object value) + { + if (value == null) + return false; + + var month = value.ToString().Split('/')[0]; + var year = $"20{value.ToString().Split('/')[1]}"; + DateTime d = new DateTime(int.Parse(year), int.Parse(month), 1); + + return d > DateTime.UtcNow; + } + } +} diff --git a/src/Web/WebMVC/Models/ManageViewModels/AddPhoneNumberViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/AddPhoneNumberViewModel.cs deleted file mode 100644 index fa89f1088..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/AddPhoneNumberViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class AddPhoneNumberViewModel - { - [Required] - [Phone] - [Display(Name = "Phone number")] - public string PhoneNumber { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/ChangePasswordViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/ChangePasswordViewModel.cs deleted file mode 100644 index 34d7cd732..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/ChangePasswordViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class ChangePasswordViewModel - { - [Required] - [DataType(DataType.Password)] - [Display(Name = "Current password")] - public string OldPassword { get; set; } - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs deleted file mode 100644 index 9ed3b9b1d..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/ConfigureTwoFactorViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.Rendering; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class ConfigureTwoFactorViewModel - { - public string SelectedProvider { get; set; } - - public ICollection Providers { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/FactorViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/FactorViewModel.cs deleted file mode 100644 index f1191cd1a..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/FactorViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class FactorViewModel - { - public string Purpose { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/IndexViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/IndexViewModel.cs deleted file mode 100644 index 87091c61c..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/IndexViewModel.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class IndexViewModel - { - public bool HasPassword { get; set; } - - public IList Logins { get; set; } - - public string PhoneNumber { get; set; } - - public bool TwoFactor { get; set; } - - public bool BrowserRemembered { get; set; } - - public ApplicationUser User { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/ManageLoginsViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/ManageLoginsViewModel.cs deleted file mode 100644 index 1944dd9ff..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/ManageLoginsViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http.Authentication; -using Microsoft.AspNetCore.Identity; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class ManageLoginsViewModel - { - public IList CurrentLogins { get; set; } - - public IList OtherLogins { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/RemoveLoginViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/RemoveLoginViewModel.cs deleted file mode 100644 index 1178c3ccb..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/RemoveLoginViewModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class RemoveLoginViewModel - { - public string LoginProvider { get; set; } - public string ProviderKey { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/SetPasswordViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/SetPasswordViewModel.cs deleted file mode 100644 index 11cfdade5..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/SetPasswordViewModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class SetPasswordViewModel - { - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs b/src/Web/WebMVC/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs deleted file mode 100644 index ce606825f..000000000 --- a/src/Web/WebMVC/Models/ManageViewModels/VerifyPhoneNumberViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels -{ - public class VerifyPhoneNumberViewModel - { - [Required] - public string Code { get; set; } - - [Required] - [Phone] - [Display(Name = "Phone number")] - public string PhoneNumber { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/Order.cs b/src/Web/WebMVC/Models/Order.cs index 455875cd4..368526141 100644 --- a/src/Web/WebMVC/Models/Order.cs +++ b/src/Web/WebMVC/Models/Order.cs @@ -1,6 +1,7 @@ -using System; +using Microsoft.eShopOnContainers.WebMVC.Models.Annotations; +using System; using System.Collections.Generic; -using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; @@ -8,40 +9,61 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models { public class Order { - public Order() - { + public Order() { OrderItems = new List(); - ShippingAddress = new Address(); - PaymentInfo = new PaymentInfo(); } - public string Id; - public List OrderItems { get; set; } - public string OrderNumber + public string OrderNumber {get;set;} + + public DateTime Date {get;set;} + + public string Status { get; set; } + + public decimal Total {get;set;} + [Required] + public string City { get; set; } + [Required] + public string Street { get; set; } + [Required] + public string State { get; set; } + [Required] + public string Country { get; set; } + + public string ZipCode { get; set; } + [Required] + public string CardNumber { get; set; } + [Required] + public string CardHolderName { get; set; } + + public DateTime CardExpiration { get; set; } + [RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "Expiration should match a valid MM/YY value")] + [CardExpiration(ErrorMessage = "Should't be expired"), Required] + public string CardExpirationShort { get; set; } + [Required] + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public List OrderItems { get; } + + public void CardExpirationShortFormat() { - get - { - return string.Format("{0}/{1}-{2}", OrderDate.Year, OrderDate.Month, SequenceNumber); - } + CardExpirationShort = CardExpiration.ToString("MM/yy"); + } + + public void CardExpirationApiFormat() + { + var month = CardExpirationShort.Split('/')[0]; + var year = $"20{CardExpirationShort.Split('/')[1]}"; + + CardExpiration = new DateTime(int.Parse(year), int.Parse(month), 1); } - public int SequenceNumber { get; set; } - public virtual string BuyerId { get; set; } - public virtual Address ShippingAddress { get; set; } - public virtual PaymentInfo PaymentInfo { get; set; } - public virtual DateTime OrderDate { get; set; } - public OrderState State { get; set; } - - public decimal Total() { - return OrderItems.Sum(x => x.Quantity * x.UnitPrice); - } - - //(CCE) public virtual Address BillingAddress { get; set; } - //(CDLTLL) public virtual OrderStatus Status { get; set; } } - - public enum OrderState:int + + public enum CardType { - InProcess = 0, - Delivered = 1 + AMEX = 1 } } diff --git a/src/Web/WebMVC/Models/OrderItem.cs b/src/Web/WebMVC/Models/OrderItem.cs index ece2ef207..5fc6273ae 100644 --- a/src/Web/WebMVC/Models/OrderItem.cs +++ b/src/Web/WebMVC/Models/OrderItem.cs @@ -7,18 +7,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models { public class OrderItem { - public string Id; - public string ProductId { get; set; } - public string OrderId { get; set; } + public int ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } - public int Quantity { get; set; } + public decimal Discount { get; set; } + + public int Units { get; set; } + public string PictureUrl { get; set; } - public override string ToString() - { - return String.Format("Product Id: {0}, Quantity: {1}", this.Id, this.Quantity); - } } - } diff --git a/src/Web/WebMVC/Models/OrderRequest.cs b/src/Web/WebMVC/Models/OrderRequest.cs deleted file mode 100644 index f45da66dd..000000000 --- a/src/Web/WebMVC/Models/OrderRequest.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models -{ - public class OrderRequest - { - public OrderRequest() { - Items = new List(); - } - - 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 List Items { get; } - - - } -} diff --git a/src/Web/WebMVC/Models/OrderRequestItem.cs b/src/Web/WebMVC/Models/OrderRequestItem.cs deleted file mode 100644 index e80f77b83..000000000 --- a/src/Web/WebMVC/Models/OrderRequestItem.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models -{ - public class OrderRequestItem - { - public int ProductId { get; set; } - - public string ProductName { get; set; } - - public decimal UnitPrice { get; set; } - - public decimal Discount { get; set; } - - public int Units { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/OrderViewModels/CreateOrderViewModel.cs b/src/Web/WebMVC/Models/OrderViewModels/CreateOrderViewModel.cs deleted file mode 100644 index 078686df4..000000000 --- a/src/Web/WebMVC/Models/OrderViewModels/CreateOrderViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models.OrderViewModels -{ - public class CreateOrderViewModel - { - public Order Order { get; set; } - } -} diff --git a/src/Web/WebMVC/Models/PaymentInfo.cs b/src/Web/WebMVC/Models/PaymentInfo.cs deleted file mode 100644 index 9be93ebfd..000000000 --- a/src/Web/WebMVC/Models/PaymentInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Models -{ - public class PaymentInfo - { - public Guid Id { get; set; } - public string CardNumber {get;set;} - public string SecurityNumber { get; set; } - public int ExpirationMonth { get; set; } //CCE: I would simplify with a string Expiration field so I guess we are not going to validate with real data. It's a demo.. - public int ExpirationYear { get; set; } //CCE: Idem. - public string CardHolderName { get; set; } - public CardType CardType { get; set; } //CCE: Discuss with team if this is needed for a demo. - public string Expiration { get; set; } //CCE: Added to simplify.. - } - - public enum CardType:int - { - AMEX, - VISA - } -} diff --git a/src/Web/WebMVC/Properties/launchSettings.json b/src/Web/WebMVC/Properties/launchSettings.json index 6a6a133af..cc4099fcb 100644 --- a/src/Web/WebMVC/Properties/launchSettings.json +++ b/src/Web/WebMVC/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:5001", + "applicationUrl": "http://localhost:5100", "sslPort": 0 } }, diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 29d8bfa50..1d5678ffe 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -79,23 +79,21 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public Order MapBasketToOrder(Basket basket) { - var order = new Order() - { - Id = Guid.NewGuid().ToString(), - BuyerId = basket.BuyerId - }; + var order = new Order(); + order.Total = 0; basket.Items.ForEach(x => { order.OrderItems.Add(new OrderItem() { - ProductId = x.ProductId, - OrderId = order.Id, + ProductId = int.Parse(x.ProductId), + PictureUrl = x.PictureUrl, ProductName = x.ProductName, - Quantity = x.Quantity, + Units = x.Quantity, UnitPrice = x.UnitPrice }); + order.Total += (x.Quantity * x.UnitPrice); }); return order; @@ -109,8 +107,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services basket = new Basket() { BuyerId = user.Id, - //Id = Guid.NewGuid().ToString(), - Items = new List() + Items = new List() }; } diff --git a/src/Web/WebMVC/Services/IOrderingService.cs b/src/Web/WebMVC/Services/IOrderingService.cs index 3cf52808b..527be4fe3 100644 --- a/src/Web/WebMVC/Services/IOrderingService.cs +++ b/src/Web/WebMVC/Services/IOrderingService.cs @@ -10,7 +10,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { Task> GetMyOrders(ApplicationUser user); Task GetOrder(ApplicationUser user, string orderId); - Task CreateOrder(ApplicationUser user, Order order); + Task CreateOrder(Order order); Order MapUserInfoIntoOrder(ApplicationUser user, Order order); void OverrideUserInfoIntoOrder(Order original, Order destination); } diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index 8324329ab..7deaf8620 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -23,45 +23,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services _remoteServiceBaseUrl = $"{settings.Value.OrderingUrl}/api/v1/orders"; _settings = settings; _httpContextAccesor = httpContextAccesor; - - #region fake items - //_orders = new List() - //{ - // new Order() - // { - // Id = Guid.NewGuid().ToString(), - // BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), - // OrderDate = DateTime.Now, - // State = OrderState.InProcess, - // OrderItems = new List() - // { - // new OrderItem() { UnitPrice = 12.40m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } - // } - // }, - // new Order() - // { - // Id = Guid.NewGuid().ToString(), - // BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), - // OrderDate = DateTime.Now, - // State = OrderState.InProcess, - // OrderItems = new List() - // { - // new OrderItem() { UnitPrice = 12.00m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } - // } - // }, - // new Order() - // { - // Id = Guid.NewGuid().ToString(), - // BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), - // OrderDate = DateTime.Now, - // State = OrderState.Delivered, - // OrderItems = new List() - // { - // new OrderItem() { UnitPrice = 12.05m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } - // } - // } - //}; - #endregion } async public Task GetOrder(ApplicationUser user, string Id) @@ -74,6 +35,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services var ordersUrl = $"{_remoteServiceBaseUrl}/{Id}"; var dataString = await _apiClient.GetStringAsync(ordersUrl); + var response = JsonConvert.DeserializeObject(dataString); return response; @@ -96,50 +58,20 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public Order MapUserInfoIntoOrder(ApplicationUser user, Order order) { - order.ShippingAddress.City = user.City; - order.ShippingAddress.Street = user.Street; - order.ShippingAddress.State = user.State; - order.ShippingAddress.Country = user.Country; + order.City = user.City; + order.Street = user.Street; + order.State = user.State; + order.Country = user.Country; - order.PaymentInfo.CardNumber = user.CardNumber; - order.PaymentInfo.CardHolderName = user.CardHolderName; - order.PaymentInfo.Expiration = user.Expiration; - order.PaymentInfo.SecurityNumber = user.SecurityNumber; + order.CardNumber = user.CardNumber; + order.CardHolderName = user.CardHolderName; + //order.CardExpiration = user.Expiration; + order.CardSecurityNumber = user.SecurityNumber; return order; } - public OrderRequest MapOrderIntoOrderRequest(Order order) - { - var od = new OrderRequest() - { - CardHolderName = order.PaymentInfo.CardHolderName, - CardNumber = order.PaymentInfo.CardNumber, - CardSecurityNumber = order.PaymentInfo.SecurityNumber, - CardTypeId = (int)order.PaymentInfo.CardType, - City = order.ShippingAddress.City, - Country = order.ShippingAddress.Country, - State = order.ShippingAddress.State, - Street = order.ShippingAddress.Street, - ZipCode = order.ShippingAddress.ZipCode, - }; - - foreach (var item in order.OrderItems) - { - od.Items.Add(new OrderRequestItem() - { - Discount = item.Discount, - ProductId = int.Parse(item.ProductId), - ProductName = item.ProductName, - UnitPrice = item.UnitPrice, - Units = item.Quantity - }); - } - - return od; - } - - async public Task CreateOrder(ApplicationUser user, Order order) + async public Task CreateOrder(Order order) { var context = _httpContextAccesor.HttpContext; var token = await context.Authentication.GetTokenAsync("access_token"); @@ -148,9 +80,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services _apiClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); var ordersUrl = $"{_remoteServiceBaseUrl}/new"; - order.PaymentInfo.CardType = CardType.AMEX; - OrderRequest request = MapOrderIntoOrderRequest(order); - StringContent content = new StringContent(JsonConvert.SerializeObject(request), System.Text.Encoding.UTF8, "application/json"); + order.CardTypeId = 1; + order.CardExpirationApiFormat(); + StringContent content = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json"); var response = await _apiClient.PostAsync(ordersUrl, content); @@ -160,15 +92,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public void OverrideUserInfoIntoOrder(Order original, Order destination) { - destination.ShippingAddress.City = original.ShippingAddress.City; - destination.ShippingAddress.Street = original.ShippingAddress.Street; - destination.ShippingAddress.State = original.ShippingAddress.State; - destination.ShippingAddress.Country = original.ShippingAddress.Country; - - destination.PaymentInfo.CardNumber = original.PaymentInfo.CardNumber; - destination.PaymentInfo.CardHolderName = original.PaymentInfo.CardHolderName; - destination.PaymentInfo.Expiration = original.PaymentInfo.Expiration; - destination.PaymentInfo.SecurityNumber = original.PaymentInfo.SecurityNumber; + destination.City = original.City; + destination.Street = original.Street; + destination.State = original.State; + destination.Country = original.Country; + + destination.CardNumber = original.CardNumber; + destination.CardHolderName = original.CardHolderName; + destination.CardExpiration = original.CardExpiration; + destination.CardSecurityNumber = original.CardSecurityNumber; } } } diff --git a/src/Web/WebMVC/Views/Order/Create.cshtml b/src/Web/WebMVC/Views/Order/Create.cshtml index 8588c2b4d..359e69196 100644 --- a/src/Web/WebMVC/Views/Order/Create.cshtml +++ b/src/Web/WebMVC/Views/Order/Create.cshtml @@ -1,5 +1,5 @@ @using Microsoft.eShopOnContainers.WebMVC.Services -@model Microsoft.eShopOnContainers.WebMVC.Models.OrderViewModels.CreateOrderViewModel +@model Microsoft.eShopOnContainers.WebMVC.Models.Order @inject IIdentityParser UserManager @{ @@ -15,24 +15,24 @@

SHIPPING ADDRESS

- - - + + +
- - - + + +
- - - + + +
- - - + + +


@@ -40,33 +40,34 @@

PAYMENT METHOD

- - - + + +
- - - + + +
- - - + + +
- - - + + +


- @await Component.InvokeAsync("CartList", new { user = UserManager.Parse(User) }) + @*@await Component.InvokeAsync("CartList", new { user = UserManager.Parse(User) })*@ + @await Html.PartialAsync("_OrderItems")
diff --git a/src/Web/WebMVC/Views/Order/Detail.cshtml b/src/Web/WebMVC/Views/Order/Detail.cshtml index 49f0f060b..483d3e628 100644 --- a/src/Web/WebMVC/Views/Order/Detail.cshtml +++ b/src/Web/WebMVC/Views/Order/Detail.cshtml @@ -1,5 +1,4 @@ @model Microsoft.eShopOnContainers.WebMVC.Models.Order -@inject UserManager UserManager @{ ViewData["Title"] = "Order Detail"; @@ -7,7 +6,7 @@ @@ -20,24 +19,24 @@
DATE
- @Model.OrderDate + @Model.Date
TOTAL
- $ @Model.Total() + $ @Model.Total
STATUS
- @Model.State + @Model.Status
SHIPING ADDRESS
- @Model.ShippingAddress.Street
- @Model.ShippingAddress.City
+ @Model.Street
+ @Model.City
@*@Model.ShippingAddress.ZipCode
*@ - @Model.ShippingAddress.Country
+ @Model.Country
@@ -54,8 +53,8 @@ @item.ProductName ROSLYN $ @Math.Round(item.UnitPrice, 2) - @item.Quantity - $ @Math.Round(item.Quantity * item.UnitPrice,2) + @item.Units + $ @Math.Round(item.Units * item.UnitPrice,2) } @@ -68,17 +67,9 @@
- @**@
- @*
SUBTOTAL
-
$ @Model.Total()
-
TAX
-
$ 4.20
*@
TOTAL
-
$ @Model.Total()
+
$ @Model.Total
diff --git a/src/Web/WebMVC/Views/Order/Index.cshtml b/src/Web/WebMVC/Views/Order/Index.cshtml index c73afa71b..c1546c90c 100644 --- a/src/Web/WebMVC/Views/Order/Index.cshtml +++ b/src/Web/WebMVC/Views/Order/Index.cshtml @@ -34,16 +34,16 @@ @Html.DisplayFor(modelItem => item.OrderNumber) - @Html.DisplayFor(modelItem => item.OrderDate) + @Html.DisplayFor(modelItem => item.Date) - $ @item.Total() + $ @Html.DisplayFor(modelItem => item.Total) - @Html.DisplayFor(modelItem => item.State) + @Html.DisplayFor(modelItem => item.Status) - Detail + Detail } diff --git a/src/Web/WebMVC/Views/Order/_OrderItems.cshtml b/src/Web/WebMVC/Views/Order/_OrderItems.cshtml new file mode 100644 index 000000000..ec76df224 --- /dev/null +++ b/src/Web/WebMVC/Views/Order/_OrderItems.cshtml @@ -0,0 +1,73 @@ +@model Microsoft.eShopOnContainers.WebMVC.Models.Order + +
+
+ + + + + + + + + + + + + @for (int i = 0; i < Model.OrderItems.Count; i++) + { + var item = Model.OrderItems[i]; + + + + + + + + + + } + + + + + + + + + +
+ PRODUCT + + + + BRAND + + PRICE + + QUANTITY + + COST +
+ + + + @item.ProductName + + ROSLYN$ @item.UnitPrice + + @item.Units + + $ @Math.Round(item.Units * item.UnitPrice, 2)
+ + +
+
TOTAL
+ $ @Model.Total +
+
+
+
diff --git a/src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml b/src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml index 17ef71004..7da0105df 100644 --- a/src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml +++ b/src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml @@ -68,15 +68,5 @@ -@*
-
-
SUBTOTAL
-
$ @Model.Total()
-
TAX
-
$ 4.20
-
TOTAL
-
$ @Model.Total()
-
-
*@ diff --git a/src/Web/WebMVC/Views/Shared/Error.cshtml b/src/Web/WebMVC/Views/Shared/Error.cshtml index e514139c4..32162fc67 100644 --- a/src/Web/WebMVC/Views/Shared/Error.cshtml +++ b/src/Web/WebMVC/Views/Shared/Error.cshtml @@ -2,13 +2,15 @@ ViewData["Title"] = "Error"; } -

Error.

-

An error occurred while processing your request.

+
+

Error.

+

An error occurred while processing your request.

-

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. -

+

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. +

+
diff --git a/src/Web/WebMVC/Views/_ViewImports.cshtml b/src/Web/WebMVC/Views/_ViewImports.cshtml index 40d832cf4..032411f99 100644 --- a/src/Web/WebMVC/Views/_ViewImports.cshtml +++ b/src/Web/WebMVC/Views/_ViewImports.cshtml @@ -1,7 +1,5 @@ @using Microsoft.eShopOnContainers.WebMVC @using Microsoft.eShopOnContainers.WebMVC.Models -@using Microsoft.eShopOnContainers.WebMVC.Models.AccountViewModels -@using Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels @using Microsoft.AspNetCore.Identity @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 9fe15aa25..90021dfe4 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -2,7 +2,7 @@ "CatalogUrl": "http://localhost:5101", "OrderingUrl": "http://localhost:5102", "BasketUrl": "http://localhost:5103", - "IdentityUrl": "http://localhost:5105", + "IdentityUrl": "http://identity.service:5105", "CallBackUrl": "http://localhost:5100/", "Logging": { "IncludeScopes": false, diff --git a/src/Web/WebMVC/wwwroot/css/site.css b/src/Web/WebMVC/wwwroot/css/site.css index efda10e62..85cdd1670 100644 --- a/src/Web/WebMVC/wwwroot/css/site.css +++ b/src/Web/WebMVC/wwwroot/css/site.css @@ -699,7 +699,7 @@ form .col-md-4 { .order-section-total { margin-bottom: 5px; - margin-left: 40px; + margin-left: 20px; text-align: left; }