diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs index bdaff000e..83ae8ef94 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs @@ -1,21 +1,16 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands -{ - using System; - using MediatR; - using Domain; - using System.Collections; - using System.Collections.Generic; +using System; +using MediatR; +using System.Collections.Generic; - //(CDLTLL) TO DO: This is wrong, we must NOT use a child-entity class within a Command class!! - //Need to create a different DTO class, like OrderLineDTO or similar... - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands +{ + public class CreateOrderCommand :IAsyncRequest { - //(CDLTLL) TO DO: This is wrong, we must NOT use a child-entity class (OrderItem) within a Command class!! - //Need to create a different DTO class, like OrderLineData or similar within the CreateOrderCommand class... - private readonly List _orderItems; + private readonly List _orderItems; + public string City { get; set; } public string Street { get; set; } @@ -36,18 +31,32 @@ public int CardTypeId { get; set; } - public string BuyerIdentityGuid { get; set; } + public string BuyerFullName { get; set; } - public IEnumerable OrderItems => _orderItems; + public IEnumerable Items => _orderItems; - public void AddOrderItem(OrderItem item) + public void AddOrderItem(OrderItemDTO item) { _orderItems.Add(item); } public CreateOrderCommand() { - _orderItems = new List(); + _orderItems = new List(); + } + + + public class OrderItemDTO + { + 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/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs index b584d0d01..92a5e691d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs @@ -1,12 +1,10 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands { - using Domain.AggregatesModel.OrderAggregate; using Domain.AggregatesModel.BuyerAggregate; + using Domain.AggregatesModel.OrderAggregate; using MediatR; - using System.Linq; using System; using System.Threading.Tasks; - using Domain; public class CreateOrderCommandHandler : IAsyncRequestHandler @@ -14,7 +12,7 @@ private readonly IBuyerRepository _buyerRepository; private readonly IOrderRepository _orderRepository; - public CreateOrderCommandHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository) + public CreateOrderCommandHandler(IBuyerRepository buyerRepository, IOrderRepository orderRepository) { if (buyerRepository == null) { @@ -29,36 +27,37 @@ _buyerRepository = buyerRepository; _orderRepository = orderRepository; } + public async Task Handle(CreateOrderCommand message) { //find buyer/payment or add a new one buyer/payment - var buyer = await _buyerRepository.FindAsync(message.BuyerIdentityGuid); + var buyer = await _buyerRepository.FindAsync(message.BuyerFullName); if (buyer == null) { - buyer = CreateBuyer(message); + buyer = new Buyer(message.BuyerFullName); } - var payment = GetExistingPaymentOrAddANewOne(buyer, message); + var payment = buyer.AddPayment(message.CardTypeId, + $"Payment Method on {DateTime.UtcNow}", + message.CardNumber, + message.CardSecurityNumber, + message.CardHolderName, + message.CardExpiration); + + _buyerRepository.Add(buyer); await _buyerRepository.UnitOfWork .SaveChangesAsync(); //create order for buyer and payment method - var order = CreateOrder(buyer.Id, payment.Id, 0); - order.SetAddress( new Address() - { - City = message.City, - State = message.State, - Street = message.Street, - ZipCode = message.ZipCode - }); + var order = new Order(buyer.Id, payment.Id, new Address(message.Street, message.City, message.State, message.Country, message.ZipCode)); - foreach (var item in message.OrderItems) + foreach (var item in message.Items) { - order.AddOrderItem(item); + order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.Units); } _orderRepository.Add(order); @@ -68,62 +67,5 @@ return result > 0; } - - Buyer CreateBuyer(CreateOrderCommand message) - { - return _buyerRepository.Add( - new Buyer(message.BuyerIdentityGuid)); - } - - Order CreateOrder(int buyerId, int paymentId, int addressId) - { - return new Order(buyerId, paymentId); - } - - - //TO DO: - //(CDLTLL) This is wrong. We shouldn't be able to create a PaymentMethod from a CommandHandler or anywhere in the Application Layer - //because a PaymentMethod is a child-entity, part of the Buyer Aggregate. - //So, any creation/update of a PaymentMethod should be done through its Aggregate-Root: the Buyer root entity. - //Need to move this logic to the Buyer Aggregate-Root and rename to "AddPaymentMethod()" - Payment CreatePayment(CreateOrderCommand message) - { - return new Payment("My Default Payment Method", message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration, message.CardTypeId); - } - - //TO DO: - //(CDLTLL) This is wrong. As explained, this logic should be part of the - //Buyer Aggregate Root, as a PaymentMethod is a child-entity of that Aggregate. - Payment GetExistingPaymentOrAddANewOne(Buyer buyer, CreateOrderCommand message) - { - Payment payment = PaymentAlreadyExist(buyer, message); - - if (payment == null) - { - payment = CreatePayment(message); - buyer.Payments.Add(payment); - } - - return payment; - - } - - //TO DO: - //(CDLTLL) This is wrong. As explained, this logic should be part of the - //Buyer Aggregate Root, as a PaymentMethod is a child-entity of that Aggregate. - Payment PaymentAlreadyExist(Buyer buyer, CreateOrderCommand message) - { - return buyer.Payments - .SingleOrDefault(p => - { - return p.CardHolderName == message.CardHolderName - && - p.CardNumber == message.CardNumber - && - p.Expiration == message.CardExpiration - && - p.SecurityNumber == message.CardSecurityNumber; - }); - } } } diff --git a/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs b/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs index 6830d9db0..693151be3 100644 --- a/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs +++ b/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Decorators +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators { using Extensions.Logging; using MediatR; diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs index c036e8806..f12a9e418 100644 --- a/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs +++ b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries { using System.Threading.Tasks; diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs index 899b3dccc..ed3e58c8d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs +++ b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries { using Dapper; using Microsoft.Extensions.Configuration; diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index bc50824dd..eb6df071c 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -1,16 +1,14 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers +using MediatR; +using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; +using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers { - using Api.Application.Commands; - using Api.Application.Queries; - using AspNetCore.Authorization; - using Infrastructure.Services; - using MediatR; - using Microsoft.AspNetCore.Mvc; - using Models; - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - [Route("api/v1/[controller]")] [Authorize] public class OrdersController : Controller @@ -46,9 +44,11 @@ public async Task AddOrder([FromBody]CreateOrderCommand createOrderCommand) { if (createOrderCommand.CardTypeId == 0) + { createOrderCommand.CardTypeId = 1; + } - createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity(); + createOrderCommand.BuyerFullName = _identityService.GetUserIdentity(); var added = await _mediator.SendAsync(createOrderCommand); if (added) diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs index a0ad2412f..0f56720f2 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs @@ -1,12 +1,11 @@ - +using Autofac; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories; namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules { - using Api.Application.Queries; - using Autofac; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; - using Ordering.Infrastructure.Repositories; public class ApplicationModule :Autofac.Module diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs index 0c911139e..e5754eeca 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs @@ -1,14 +1,14 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules -{ - using Api.Application.Commands; - using Api.Application.Decorators; - using Autofac; - using Autofac.Core; - using MediatR; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; +using Autofac; +using Autofac.Core; +using MediatR; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules +{ public class MediatorModule : Autofac.Module { protected override void Load(ContainerBuilder builder) diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.Designer.cs deleted file mode 100644 index f7d11fbfb..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.Designer.cs +++ /dev/null @@ -1,227 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; - -namespace Ordering.API.Infrastructure.Migrations -{ - [DbContext(typeof(OrderingContext))] - [Migration("20161124133626_InitialModel")] - partial class InitialModel - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.1") - .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("State"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("address","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq") - .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("FullName") - .IsRequired() - .HasAnnotation("MaxLength", 200); - - b.HasKey("Id"); - - b.HasIndex("FullName") - .IsUnique(); - - b.ToTable("buyers","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasDefaultValue(1); - - b.Property("Name") - .IsRequired() - .HasAnnotation("MaxLength", 200); - - b.HasKey("Id"); - - b.ToTable("cardtypes","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:HiLoSequenceName", "orderseq") - .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("BuyerId"); - - b.Property("OrderDate"); - - b.Property("PaymentId"); - - b.Property("ShippingAddressId"); - - b.Property("StatusId"); - - b.HasKey("Id"); - - b.HasIndex("BuyerId"); - - b.HasIndex("PaymentId"); - - b.HasIndex("ShippingAddressId"); - - b.HasIndex("StatusId"); - - b.ToTable("orders","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Discount"); - - b.Property("OrderId"); - - b.Property("ProductId"); - - b.Property("ProductName") - .IsRequired(); - - b.Property("UnitPrice"); - - b.Property("Units") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:DefaultValue", 1); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("orderItems","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasDefaultValue(1); - - b.Property("Name") - .IsRequired() - .HasAnnotation("MaxLength", 200); - - b.HasKey("Id"); - - b.ToTable("orderstatus","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq") - .HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("BuyerId"); - - b.Property("CardHolderName") - .IsRequired() - .HasAnnotation("MaxLength", 200); - - b.Property("CardNumber") - .IsRequired() - .HasAnnotation("MaxLength", 25); - - b.Property("CardTypeId"); - - b.Property("Expiration"); - - b.Property("SecurityNumber"); - - b.HasKey("Id"); - - b.HasIndex("BuyerId"); - - b.HasIndex("CardTypeId"); - - b.ToTable("payments","ordering"); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", "Buyer") - .WithMany() - .HasForeignKey("BuyerId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", "Payment") - .WithMany() - .HasForeignKey("PaymentId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Address", "ShippingAddress") - .WithMany() - .HasForeignKey("ShippingAddressId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderStatus", "Status") - .WithMany() - .HasForeignKey("StatusId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.OrderItem", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order") - .WithMany("OrderItems") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b => - { - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer") - .WithMany("Payments") - .HasForeignKey("BuyerId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.CardType", "CardType") - .WithMany() - .HasForeignKey("CardTypeId") - .OnDelete(DeleteBehavior.Cascade); - }); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.cs deleted file mode 100644 index a3152432b..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Ordering.API.Infrastructure.Migrations -{ - public partial class PaymentMethodWithAlias : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Alias", - schema: "ordering", - table: "payments", - maxLength: 200, - nullable: false, - defaultValue: ""); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Alias", - schema: "ordering", - table: "payments"); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.Designer.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.Designer.cs similarity index 78% rename from src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.Designer.cs rename to src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.Designer.cs index 4fe16d38a..497f5a95b 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.Designer.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.Designer.cs @@ -5,16 +5,17 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; -namespace Ordering.API.Infrastructure.Migrations +namespace Ordering.API.Migrations { [DbContext(typeof(OrderingContext))] - [Migration("20170118230807_PaymentMethodWithAlias")] - partial class PaymentMethodWithAlias + [Migration("20170125143653_Initial")] + partial class Initial { protected override void BuildTargetModel(ModelBuilder modelBuilder) { modelBuilder - .HasAnnotation("ProductVersion", "1.0.1") + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") + .HasAnnotation("SqlServer:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") @@ -30,7 +31,7 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("FullName") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -43,12 +44,11 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasDefaultValue(1); b.Property("Name") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -65,24 +65,22 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("Alias") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.Property("BuyerId"); b.Property("CardHolderName") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.Property("CardNumber") .IsRequired() - .HasAnnotation("MaxLength", 25); + .HasMaxLength(25); b.Property("CardTypeId"); b.Property("Expiration"); - b.Property("SecurityNumber"); - b.HasKey("Id"); b.HasIndex("BuyerId"); @@ -92,26 +90,6 @@ namespace Ordering.API.Infrastructure.Migrations b.ToTable("payments","ordering"); }); - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("State"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("address","ordering"); - }); - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => { b.Property("Id") @@ -122,23 +100,31 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("BuyerId"); + b.Property("City") + .IsRequired(); + b.Property("OrderDate"); + b.Property("OrderStatusId"); + b.Property("PaymentId"); - b.Property("ShippingAddressId"); + b.Property("State") + .IsRequired(); - b.Property("StatusId"); + b.Property("Street") + .IsRequired(); + + b.Property("ZipCode") + .IsRequired(); b.HasKey("Id"); b.HasIndex("BuyerId"); - b.HasIndex("PaymentId"); + b.HasIndex("OrderStatusId"); - b.HasIndex("ShippingAddressId"); - - b.HasIndex("StatusId"); + b.HasIndex("PaymentId"); b.ToTable("orders","ordering"); }); @@ -146,14 +132,14 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => { b.Property("Id") - .ValueGeneratedOnAdd(); + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); b.Property("Discount"); b.Property("OrderId"); - b.Property("PictureUrl"); - b.Property("ProductId"); b.Property("ProductName") @@ -161,9 +147,7 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("UnitPrice"); - b.Property("Units") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:DefaultValue", 1); + b.Property("Units"); b.HasKey("Id"); @@ -175,12 +159,11 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasDefaultValue(1); b.Property("Name") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -207,18 +190,14 @@ namespace Ordering.API.Infrastructure.Migrations .HasForeignKey("BuyerId") .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") - .WithMany() - .HasForeignKey("PaymentId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress") + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus") .WithMany() - .HasForeignKey("ShippingAddressId"); + .HasForeignKey("OrderStatusId") + .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "Status") + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") .WithMany() - .HasForeignKey("StatusId") - .OnDelete(DeleteBehavior.Cascade); + .HasForeignKey("PaymentId"); }); modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.cs similarity index 78% rename from src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs rename to src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.cs index e6ac74cee..2787184c7 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170125143653_Initial.cs @@ -1,17 +1,20 @@ using System; using System.Collections.Generic; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Metadata; -namespace Ordering.API.Infrastructure.Migrations +namespace Ordering.API.Migrations { - public partial class InitialModel : Migration + public partial class Initial : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.EnsureSchema( name: "ordering"); + migrationBuilder.CreateSequence( + name: "orderitemseq", + incrementBy: 10); + migrationBuilder.CreateSequence( name: "buyerseq", schema: "ordering", @@ -27,24 +30,6 @@ namespace Ordering.API.Infrastructure.Migrations schema: "ordering", incrementBy: 10); - migrationBuilder.CreateTable( - name: "address", - schema: "ordering", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), - City = table.Column(nullable: true), - Country = table.Column(nullable: true), - State = table.Column(nullable: true), - Street = table.Column(nullable: true), - ZipCode = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_address", x => x.Id); - }); - migrationBuilder.CreateTable( name: "buyers", schema: "ordering", @@ -90,12 +75,12 @@ namespace Ordering.API.Infrastructure.Migrations columns: table => new { Id = table.Column(nullable: false), + Alias = table.Column(maxLength: 200, nullable: false), BuyerId = table.Column(nullable: false), CardHolderName = table.Column(maxLength: 200, nullable: false), CardNumber = table.Column(maxLength: 25, nullable: false), CardTypeId = table.Column(nullable: false), - Expiration = table.Column(nullable: false), - SecurityNumber = table.Column(nullable: true) + Expiration = table.Column(nullable: false) }, constraints: table => { @@ -123,10 +108,13 @@ namespace Ordering.API.Infrastructure.Migrations { Id = table.Column(nullable: false), BuyerId = table.Column(nullable: false), + City = table.Column(nullable: false), OrderDate = table.Column(nullable: false), + OrderStatusId = table.Column(nullable: false), PaymentId = table.Column(nullable: false), - ShippingAddressId = table.Column(nullable: true), - StatusId = table.Column(nullable: false) + State = table.Column(nullable: false), + Street = table.Column(nullable: false), + ZipCode = table.Column(nullable: false) }, constraints: table => { @@ -139,26 +127,19 @@ namespace Ordering.API.Infrastructure.Migrations principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_orders_payments_PaymentId", - column: x => x.PaymentId, + name: "FK_orders_orderstatus_OrderStatusId", + column: x => x.OrderStatusId, principalSchema: "ordering", - principalTable: "payments", + principalTable: "orderstatus", principalColumn: "Id", - onDelete: ReferentialAction.Restrict); + onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_orders_address_ShippingAddressId", - column: x => x.ShippingAddressId, + name: "FK_orders_payments_PaymentId", + column: x => x.PaymentId, principalSchema: "ordering", - principalTable: "address", + principalTable: "payments", principalColumn: "Id", onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_orders_orderstatus_StatusId", - column: x => x.StatusId, - principalSchema: "ordering", - principalTable: "orderstatus", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( @@ -166,15 +147,13 @@ namespace Ordering.API.Infrastructure.Migrations schema: "ordering", columns: table => new { - Id = table.Column(nullable: false) - .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), + Id = table.Column(nullable: false), Discount = table.Column(nullable: false), 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) + Units = table.Column(nullable: false) }, constraints: table => { @@ -196,62 +175,44 @@ namespace Ordering.API.Infrastructure.Migrations unique: true); migrationBuilder.CreateIndex( - name: "IX_orders_BuyerId", + name: "IX_payments_BuyerId", schema: "ordering", - table: "orders", + table: "payments", column: "BuyerId"); migrationBuilder.CreateIndex( - name: "IX_orders_PaymentId", + name: "IX_payments_CardTypeId", + schema: "ordering", + table: "payments", + column: "CardTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_orders_BuyerId", schema: "ordering", table: "orders", - column: "PaymentId"); + column: "BuyerId"); migrationBuilder.CreateIndex( - name: "IX_orders_ShippingAddressId", + name: "IX_orders_OrderStatusId", schema: "ordering", table: "orders", - column: "ShippingAddressId"); + column: "OrderStatusId"); migrationBuilder.CreateIndex( - name: "IX_orders_StatusId", + name: "IX_orders_PaymentId", schema: "ordering", table: "orders", - column: "StatusId"); + column: "PaymentId"); migrationBuilder.CreateIndex( name: "IX_orderItems_OrderId", schema: "ordering", table: "orderItems", column: "OrderId"); - - migrationBuilder.CreateIndex( - name: "IX_payments_BuyerId", - schema: "ordering", - table: "payments", - column: "BuyerId"); - - migrationBuilder.CreateIndex( - name: "IX_payments_CardTypeId", - schema: "ordering", - table: "payments", - column: "CardTypeId"); } protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.DropSequence( - name: "buyerseq", - schema: "ordering"); - - migrationBuilder.DropSequence( - name: "orderseq", - schema: "ordering"); - - migrationBuilder.DropSequence( - name: "paymentseq", - schema: "ordering"); - migrationBuilder.DropTable( name: "orderItems", schema: "ordering"); @@ -261,15 +222,11 @@ namespace Ordering.API.Infrastructure.Migrations schema: "ordering"); migrationBuilder.DropTable( - name: "payments", - schema: "ordering"); - - migrationBuilder.DropTable( - name: "address", + name: "orderstatus", schema: "ordering"); migrationBuilder.DropTable( - name: "orderstatus", + name: "payments", schema: "ordering"); migrationBuilder.DropTable( @@ -279,6 +236,21 @@ namespace Ordering.API.Infrastructure.Migrations migrationBuilder.DropTable( name: "cardtypes", schema: "ordering"); + + migrationBuilder.DropSequence( + name: "orderitemseq"); + + migrationBuilder.DropSequence( + name: "buyerseq", + schema: "ordering"); + + migrationBuilder.DropSequence( + name: "orderseq", + schema: "ordering"); + + migrationBuilder.DropSequence( + name: "paymentseq", + schema: "ordering"); } } } diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs index 1f385a316..5aefd0de7 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; -namespace Ordering.API.Infrastructure.Migrations +namespace Ordering.API.Migrations { [DbContext(typeof(OrderingContext))] partial class OrderingContextModelSnapshot : ModelSnapshot @@ -13,7 +13,8 @@ namespace Ordering.API.Infrastructure.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { modelBuilder - .HasAnnotation("ProductVersion", "1.0.1") + .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") + .HasAnnotation("SqlServer:Sequence:.orderitemseq", "'orderitemseq', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'") @@ -29,7 +30,7 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("FullName") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -42,12 +43,11 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasDefaultValue(1); b.Property("Name") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -64,24 +64,22 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("Alias") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.Property("BuyerId"); b.Property("CardHolderName") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.Property("CardNumber") .IsRequired() - .HasAnnotation("MaxLength", 25); + .HasMaxLength(25); b.Property("CardTypeId"); b.Property("Expiration"); - b.Property("SecurityNumber"); - b.HasKey("Id"); b.HasIndex("BuyerId"); @@ -91,26 +89,6 @@ namespace Ordering.API.Infrastructure.Migrations b.ToTable("payments","ordering"); }); - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("City"); - - b.Property("Country"); - - b.Property("State"); - - b.Property("Street"); - - b.Property("ZipCode"); - - b.HasKey("Id"); - - b.ToTable("address","ordering"); - }); - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => { b.Property("Id") @@ -121,23 +99,31 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("BuyerId"); + b.Property("City") + .IsRequired(); + b.Property("OrderDate"); + b.Property("OrderStatusId"); + b.Property("PaymentId"); - b.Property("ShippingAddressId"); + b.Property("State") + .IsRequired(); - b.Property("StatusId"); + b.Property("Street") + .IsRequired(); + + b.Property("ZipCode") + .IsRequired(); b.HasKey("Id"); b.HasIndex("BuyerId"); - b.HasIndex("PaymentId"); + b.HasIndex("OrderStatusId"); - b.HasIndex("ShippingAddressId"); - - b.HasIndex("StatusId"); + b.HasIndex("PaymentId"); b.ToTable("orders","ordering"); }); @@ -145,14 +131,14 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => { b.Property("Id") - .ValueGeneratedOnAdd(); + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); b.Property("Discount"); b.Property("OrderId"); - b.Property("PictureUrl"); - b.Property("ProductId"); b.Property("ProductName") @@ -160,9 +146,7 @@ namespace Ordering.API.Infrastructure.Migrations b.Property("UnitPrice"); - b.Property("Units") - .ValueGeneratedOnAdd() - .HasAnnotation("SqlServer:DefaultValue", 1); + b.Property("Units"); b.HasKey("Id"); @@ -174,12 +158,11 @@ namespace Ordering.API.Infrastructure.Migrations modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasDefaultValue(1); b.Property("Name") .IsRequired() - .HasAnnotation("MaxLength", 200); + .HasMaxLength(200); b.HasKey("Id"); @@ -206,18 +189,14 @@ namespace Ordering.API.Infrastructure.Migrations .HasForeignKey("BuyerId") .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") - .WithMany() - .HasForeignKey("PaymentId"); - - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress") + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus") .WithMany() - .HasForeignKey("ShippingAddressId"); + .HasForeignKey("OrderStatusId") + .OnDelete(DeleteBehavior.Cascade); - b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "Status") + b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") .WithMany() - .HasForeignKey("StatusId") - .OnDelete(DeleteBehavior.Cascade); + .HasForeignKey("PaymentId"); }); modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => diff --git a/src/Services/Ordering/Ordering.API/Models/NewOrderViewModel.cs b/src/Services/Ordering/Ordering.API/Models/NewOrderViewModel.cs deleted file mode 100644 index e2049947c..000000000 --- a/src/Services/Ordering/Ordering.API/Models/NewOrderViewModel.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Models -{ - //TO DO: Confirm if this class is not needed, if not, remove it - //(CDLTLL) - public class NewOrderViewModel - { - public string ShippingCity { get; set; } - - public string ShippingStreet { get; set; } - - public string ShippingState { get; set; } - - public string ShippingCountry { get; set; } - - public string CardType { get; set; } - - public string CardNumber { get; set; } - - public string CardHolderName { get; set; } - - public DateTime CardExpiration { get; set; } - - public string CardSecurityNumber { get; set; } - - public List Items { get; set; } - - public NewOrderViewModel() - { - Items = new List(); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs b/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs deleted file mode 100644 index 1f088f648..000000000 --- a/src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Models -{ - //TO DO: Confirm if this class is not needed, if not, remove it - //(CDLTLL) - public class OrderItemViewModel - { - 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; } - - public string PictureUrl { get; set; } - } -} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Models/_REFACTORING TO DO - Remove ViewModel classes.txt b/src/Services/Ordering/Ordering.API/Models/_REFACTORING TO DO - Remove ViewModel classes.txt deleted file mode 100644 index a7ac46963..000000000 --- a/src/Services/Ordering/Ordering.API/Models/_REFACTORING TO DO - Remove ViewModel classes.txt +++ /dev/null @@ -1,5 +0,0 @@ - -REFACTORING TO DO: - //TO DO: Confirm if these ViewModel classes are still needed, if not, remove it - //and remove the related Unit Tests - //(CDLTLL) diff --git a/src/Services/Ordering/Ordering.API/project.json b/src/Services/Ordering/Ordering.API/project.json index 0c4d597ea..291892b40 100644 --- a/src/Services/Ordering/Ordering.API/project.json +++ b/src/Services/Ordering/Ordering.API/project.json @@ -1,44 +1,45 @@ { "dependencies": { "Microsoft.NETCore.App": { - "version": "1.0.1", + "version": "1.1.0", "type": "platform" }, - "MediatR.Extensions.Microsoft.DependencyInjection": "1.0.1", + "MediatR.Extensions.Microsoft.DependencyInjection": "1.1.0", "Autofac.Extensions.DependencyInjection": "4.0.0", - "Microsoft.AspNetCore.Mvc": "1.0.0", - "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", - "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", - "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", - "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0", - "Microsoft.Extensions.Configuration.Json": "1.0.0", - "Microsoft.Extensions.Logging.Abstractions": "1.0.0", - "Microsoft.Extensions.Logging.Console": "1.0.0", - "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", - "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", - "Microsoft.EntityFrameworkCore": "1.0.1", - "Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final", - "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", - "Microsoft.AspNetCore.Diagnostics": "1.0.0", + "Microsoft.AspNetCore.Mvc": "1.1.0", + "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0", + "Microsoft.AspNetCore.Server.Kestrel":"1.0.1", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", + "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", + "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0", + "Microsoft.Extensions.Configuration.Json": "1.1.0", + "Microsoft.Extensions.Logging.Abstractions": "1.1.0", + "Microsoft.Extensions.Logging.Console": "1.1.0", + "Microsoft.Extensions.Logging.Debug": "1.1.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0", + "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0", + "Microsoft.EntityFrameworkCore": "1.1.0", + "Microsoft.EntityFrameworkCore.Design":"1.1.0", + "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.1.0", + "Microsoft.AspNetCore.Diagnostics": "1.1.0", "Swashbuckle": "6.0.0-beta902", "MediatR": "2.1.0", - "Ordering.Domain": "1.0.0-*", - "Ordering.Infrastructure": "1.0.0-*", "System.Reflection": "4.3.0", "IdentityServer4.AccessTokenValidation": "1.0.1-rc3", - "Dapper": "1.50.2" + "Dapper": "1.50.2", + "Ordering.Domain": "1.0.0-*", + "Ordering.Infrastructure": "1.0.0-*" }, "tools": { - "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", + "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.1.0-preview4-final", "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" }, "frameworks": { - "netcoreapp1.0": { + "netcoreapp1.1": { "imports": [ - "dotnet5.6", - "portable-net45+win8" + "netstandard1.6.1", + "dnxcore50", + "portable-net451+win8" ] } }, diff --git a/src/Services/Ordering/Ordering.API/settings.json b/src/Services/Ordering/Ordering.API/settings.json index a6c3d9cac..09552377a 100644 --- a/src/Services/Ordering/Ordering.API/settings.json +++ b/src/Services/Ordering/Ordering.API/settings.json @@ -1,6 +1,6 @@ { "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "IdentityUrl": "http://localhost:5105", + "IdentityUrl": "http://localhost:5105", "Logging": { "IncludeScopes": false, "LogLevel": { diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs index c10f38ff3..0203b72e3 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs @@ -1,27 +1,50 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate -{ - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using System; - using System.Collections.Generic; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +using System.Collections.Generic; +using System.Linq; +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate +{ public class Buyer - :Entity,IAggregateRoot + : Entity, IAggregateRoot { public string FullName { get; private set; } - public HashSet Payments { get; private set; } + private HashSet _payments; + + public IEnumerable Payments => _payments?.ToList().AsEnumerable(); protected Buyer() { } - public Buyer(string IdentityGuid) + public Buyer(string identity) + { + if (String.IsNullOrWhiteSpace(identity)) + { + throw new ArgumentNullException(nameof(identity)); + } + + FullName = identity; + + _payments = new HashSet(); + } + + public Payment AddPayment(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration) { - if (String.IsNullOrWhiteSpace(IdentityGuid)) + var existingPayment = Payments.Where(p => p.IsEqualTo(cardTypeId, cardNumber, expiration)) + .SingleOrDefault(); + + if (existingPayment != null) { - throw new ArgumentNullException(nameof(IdentityGuid)); + return existingPayment; } + else + { + var payment = new Payment(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration); + + _payments.Add(payment); - this.FullName = IdentityGuid; - this.Payments = new HashSet(); + return payment; + } } } } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs index dc5cfe6f6..217ef6095 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs @@ -1,12 +1,11 @@ - +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +using System.Collections.Generic; +using System.Linq; namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate { - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using System; - using System.Collections.Generic; - using System.Linq; - + public class CardType : Entity { diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs index 3644bba35..5cf02e8b5 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs @@ -1,30 +1,25 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate -{ - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using System; - +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate +{ public class Payment : Entity { - public string Alias { get; private set; } - public int BuyerId { get; private set; } - - public string CardNumber { get; private set; } - - public string SecurityNumber { get; private set; } - - public string CardHolderName { get; private set; } - - public int CardTypeId { get; private set; } - + private int _buyerId; + private string _alias; + private string _cardNumber; + private string _securityNumber; + private string _cardHolderName; + private DateTime _expiration; + + private int _cardTypeId; public CardType CardType { get; private set; } - public DateTime Expiration { get; private set; } protected Payment() { } - public Payment(string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration, int cardTypeId) + public Payment(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration) { if (String.IsNullOrWhiteSpace(cardNumber)) { @@ -35,7 +30,7 @@ { throw new ArgumentException(nameof(securityNumber)); } - + if (String.IsNullOrWhiteSpace(cardHolderName)) { throw new ArgumentException(nameof(cardHolderName)); @@ -46,12 +41,19 @@ throw new ArgumentException(nameof(expiration)); } - this.Alias = alias; - this.CardNumber = cardNumber; - this.SecurityNumber = securityNumber; - this.CardHolderName = cardHolderName; - this.Expiration = expiration; - this.CardTypeId = cardTypeId; + _alias = alias; + _cardNumber = cardNumber; + _securityNumber = securityNumber; + _cardHolderName = cardHolderName; + _expiration = expiration; + _cardTypeId = cardTypeId; + } + + public bool IsEqualTo(int cardTypeId, string cardNumber,DateTime expiration) + { + return _cardTypeId == cardTypeId + && _cardNumber == cardNumber + && _expiration == expiration; } } } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs index 9d36bcc17..b3760480c 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs @@ -1,22 +1,26 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate -{ - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using System; +using System; - //(CDLTLL) - //TO DO: Need to convert this entity to a Value-Object (Address VO) +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate +{ public class Address - : Entity { - public String Street { get; set; } + public String Street { get; } - public String City { get; set; } + public String City { get; } - public String State { get; set; } + public String State { get; } - public String Country { get; set; } + public String Country { get; } - public String ZipCode { get; set; } + public String ZipCode { get; } + public Address(string street, string city, string state, string country, string zipcode) + { + Street = street; + City = city; + State = state; + Country = country; + ZipCode = zipcode; + } } } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs index 85dfe4eb1..c7af790eb 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs @@ -1,7 +1,7 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; + +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate { - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; //This is just the RepositoryContracts or Interface defined at the Domain Layer //as requisite for the Order Aggregate diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs index db86e5ba2..e1e44fcf0 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -1,79 +1,76 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate { - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; - using System; - using System.Collections.Generic; - - //(CDLTLL) - //TO DO: Need to add additional Domain Logic to this Aggregate-Root for - //scenarios related to Order state changes, stock availability validation, etc. public class Order - : Entity, IAggregateRoot + : Entity { - public int BuyerId { get; private set; } - - public Buyer Buyer { get; private set; } - - public DateTime OrderDate { get; private set; } - public int StatusId { get; private set; } + private string _street; + private string _city; + private string _state; + private string _country; + private string _zipCode; + private DateTime _orderDate; - public OrderStatus Status { get; private set; } - - public ICollection OrderItems { get; private set; } - - public int? ShippingAddressId { get; private set; } + public Buyer Buyer { get; private set; } + int _buyerId; - public Address ShippingAddress { get; private set; } + public OrderStatus OrderStatus { get; private set; } + int _orderStatusId; - public int PaymentId { get; private set; } + HashSet _orderItems; + public IEnumerable OrderItems => _orderItems.ToList().AsEnumerable(); public Payment Payment { get; private set; } + int _paymentId; protected Order() { } - public Order(int buyerId, int paymentId) + public Order(int buyerId, int paymentId, Address address) { - BuyerId = buyerId; - PaymentId = paymentId; - StatusId = OrderStatus.InProcess.Id; - OrderDate = DateTime.UtcNow; - OrderItems = new List(); + + _buyerId = buyerId; + _paymentId = paymentId; + _orderStatusId = OrderStatus.InProcess.Id; + _orderDate = DateTime.UtcNow; + _street = address.Street; + _city = address.City; + _state = address.State; + _country = address.Country; + _zipCode = address.ZipCode; + + _orderItems = new HashSet(); } - public void SetAddress(Address address) + + public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, int units = 1) { - if (address == null) + var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId) + .SingleOrDefault(); + + if (existingOrderForProduct != null) { - throw new ArgumentNullException(nameof(address)); + //if previous line exist modify it with higher discount and units.. + + if (discount > existingOrderForProduct.GetCurrentDiscount()) + { + existingOrderForProduct.SetNewDiscount(discount); + existingOrderForProduct.AddUnits(units); + } } + else + { + //add validated new order item - ShippingAddress = address; - } + var orderItem = new OrderItem(productId, productName, unitPrice, discount, units); - //TO DO: - // (CDLTLL) Bad implementation, needs to be changed. - // The AddOrderItem should have the needed data params - // instead of an already created OrderItem object. - // The Aggregate-Root is responsible for any Update/Creation of its child entities - // If we are providing an already created OrderItem, that was created from the outside - // and the AggregateRoot cannot control/validate any rule/invariants/consistency. - public void AddOrderItem(OrderItem item) - { - //TO DO: Bad implementation, need to change. - // The code "new OrderItem(params);" should be done here - // Plus any validation/rule related - OrderItems.Add(item); - - //(CDLTLL) - // TO DO: Some more logic needs to be added here, - // Like consolidating items that are the same product in one single OrderItem with several units - // Also validation logic could be added here (like ensuring it is adding at least one item unit) - - //Or, If there are different amounts of discounts per added OrderItem - //but the product Id is the same to existing Order Items, you should - //apply the higher discount, or any other domain logic that makes sense. + _orderItems.Add(orderItem); + } } } } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs index 0e57ea701..9a62ef1a3 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs @@ -1,28 +1,74 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate -{ - using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; - //TO DO: - //(CDLTLL) Wrong implementation. Need to put Setters as private - // and only be able to update the OrderItem through specific methods, if needed, so we can - // have validations/control/logic in those "update or set methods". - //We also need to have a constructor with the needed params, we must not use the "setters".. +namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate +{ public class OrderItem - :Entity + : Entity { - public int ProductId { get; set; } + private string _productName; + private string _pictureUrl; + private int _orderId; + private decimal _unitPrice; + private decimal _discount; + private int _units; + + public int ProductId { get; private set; } + + + protected OrderItem() { } + + public OrderItem(int productId, string productName, decimal unitPrice, decimal discount, int units = 1) + { + if (units <= 0) + { + throw new ArgumentNullException("Invalid number of units"); + } + + if ((unitPrice * units) < discount) + { + throw new ArgumentException("The total of order item is lower than applied discount"); + } + + ProductId = productId; - public string ProductName { get; set; } + _productName = productName; + _unitPrice = unitPrice; + _discount = discount; + _units = units; + } - public string PictureUrl { get; set; } + public void SetPictureUri(string pictureUri) + { + if (!String.IsNullOrWhiteSpace(pictureUri)) + { + _pictureUrl = pictureUri; + } + } - public int OrderId { get; set; } + public decimal GetCurrentDiscount() + { + return _discount; + } - public decimal UnitPrice { get; set; } + public void SetNewDiscount(decimal discount) + { + if (discount < 0) + { + throw new ArgumentException("Discount is not valid"); + } - public decimal Discount { get; set; } + _discount = discount; + } - public int Units { get; set; } + public void AddUnits(int units) + { + if (units < 0) + { + throw new ArgumentException("Invalid units"); + } + _units += units; + } } } diff --git a/src/Services/Ordering/Ordering.Domain/project.json b/src/Services/Ordering/Ordering.Domain/project.json index db56591f2..2feeaa08d 100644 --- a/src/Services/Ordering/Ordering.Domain/project.json +++ b/src/Services/Ordering/Ordering.Domain/project.json @@ -2,11 +2,11 @@ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6" + "NETStandard.Library": "1.6.1" }, "frameworks": { - "netstandard1.6": { + "netstandard1.6.1": { "imports": "dnxcore50" } } diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index b34a6ee05..ac21ae53e 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -1,17 +1,15 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; + +namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure { - using System; - using System.Threading.Tasks; - using Domain.SeedWork; - using EntityFrameworkCore.Metadata; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - using Microsoft.eShopOnContainers.Services.Ordering.Domain; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; - public class OrderingContext - : DbContext,IUnitOfWork + : DbContext,IUnitOfWork { const string DEFAULT_SCHEMA = "ordering"; @@ -28,8 +26,6 @@ public DbSet OrderStatus { get; set; } - public DbSet
Addresses { get; set; } - public OrderingContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -40,29 +36,31 @@ modelBuilder.Entity(ConfigureOrderItems); modelBuilder.Entity(ConfigureCardTypes); modelBuilder.Entity(ConfigureOrderStatus); - modelBuilder.Entity
(ConfigureAddress); } void ConfigureBuyer(EntityTypeBuilder buyerConfiguration) { buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA); - buyerConfiguration.HasIndex(b => b.FullName) - .IsUnique(true); - buyerConfiguration.HasKey(b => b.Id); buyerConfiguration.Property(b => b.Id) .ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); - buyerConfiguration.Property(b => b.FullName) + buyerConfiguration.Property(b=>b.FullName) .HasMaxLength(200) .IsRequired(); + buyerConfiguration.HasIndex("FullName") + .IsUnique(true); + buyerConfiguration.HasMany(b => b.Payments) - .WithOne() - .HasForeignKey(p => p.BuyerId) - .OnDelete(DeleteBehavior.Cascade); + .WithOne() + .HasForeignKey("BuyerId") + .OnDelete(DeleteBehavior.Cascade); + + var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.Payments)); + navigation.SetPropertyAccessMode(PropertyAccessMode.Field); } void ConfigurePayment(EntityTypeBuilder paymentConfiguration) @@ -74,24 +72,30 @@ paymentConfiguration.Property(b => b.Id) .ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); - paymentConfiguration.Property(p => p.CardHolderName) + paymentConfiguration.Property("BuyerId") + .IsRequired(); + + paymentConfiguration.Property("CardHolderName") .HasMaxLength(200) .IsRequired(); - paymentConfiguration.Property(p => p.Alias) + paymentConfiguration.Property("Alias") .HasMaxLength(200) .IsRequired(); - paymentConfiguration.Property(p => p.CardNumber) + paymentConfiguration.Property("CardNumber") .HasMaxLength(25) .IsRequired(); - paymentConfiguration.Property(p => p.Expiration) + paymentConfiguration.Property("Expiration") + .IsRequired(); + + paymentConfiguration.Property("CardTypeId") .IsRequired(); paymentConfiguration.HasOne(p => p.CardType) .WithMany() - .HasForeignKey(p => p.CardTypeId); + .HasForeignKey("CardTypeId"); } void ConfigureOrder(EntityTypeBuilder orderConfiguration) @@ -103,21 +107,31 @@ orderConfiguration.Property(o => o.Id) .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); - orderConfiguration.Property(o => o.OrderDate) - .IsRequired(); + orderConfiguration.Property("OrderDate").IsRequired(); + orderConfiguration.Property("Street").IsRequired(); + orderConfiguration.Property("State").IsRequired(); + orderConfiguration.Property("City").IsRequired(); + orderConfiguration.Property("ZipCode").IsRequired(); + orderConfiguration.Property("BuyerId").IsRequired(); + orderConfiguration.Property("OrderStatusId").IsRequired(); + orderConfiguration.Property("PaymentId").IsRequired(); + + var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems)); + + navigation.SetPropertyAccessMode(PropertyAccessMode.Field); orderConfiguration.HasOne(o => o.Payment) .WithMany() - .HasForeignKey(o => o.PaymentId) + .HasForeignKey("PaymentId") .OnDelete(DeleteBehavior.Restrict); orderConfiguration.HasOne(o => o.Buyer) .WithMany() - .HasForeignKey(o => o.BuyerId); + .HasForeignKey("BuyerId"); - orderConfiguration.HasOne(o => o.Status) + orderConfiguration.HasOne(o => o.OrderStatus) .WithMany() - .HasForeignKey(o => o.StatusId); + .HasForeignKey("OrderStatusId"); } void ConfigureOrderItems(EntityTypeBuilder orderItemConfiguration) @@ -126,20 +140,25 @@ orderItemConfiguration.HasKey(o => o.Id); - orderItemConfiguration.Property(o => o.Discount) + orderItemConfiguration.Property(o => o.Id) + .ForSqlServerUseSequenceHiLo("orderitemseq"); + + orderItemConfiguration.Property("OrderId") .IsRequired(); - orderItemConfiguration.Property(o => o.ProductId) + orderItemConfiguration.Property("Discount") .IsRequired(); - orderItemConfiguration.Property(o => o.ProductName) + orderItemConfiguration.Property("ProductId") .IsRequired(); - orderItemConfiguration.Property(o => o.UnitPrice) + orderItemConfiguration.Property("ProductName") .IsRequired(); - orderItemConfiguration.Property(o => o.Units) - .ForSqlServerHasDefaultValue(1) + orderItemConfiguration.Property("UnitPrice") + .IsRequired(); + + orderItemConfiguration.Property("Units") .IsRequired(); } @@ -151,6 +170,7 @@ orderStatusConfiguration.Property(o => o.Id) .HasDefaultValue(1) + .ValueGeneratedNever() .IsRequired(); orderStatusConfiguration.Property(o => o.Name) @@ -166,16 +186,12 @@ cardTypesConfiguration.Property(ct => ct.Id) .HasDefaultValue(1) + .ValueGeneratedNever() .IsRequired(); cardTypesConfiguration.Property(ct => ct.Name) .HasMaxLength(200) .IsRequired(); } - - void ConfigureAddress(EntityTypeBuilder
addressConfiguration) - { - addressConfiguration.ToTable("address", DEFAULT_SCHEMA); - } } } diff --git a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs index cb1fe4049..2854e42e1 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs @@ -1,13 +1,12 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories -{ - using Domain.SeedWork; - using Microsoft.EntityFrameworkCore; - using Microsoft.eShopOnContainers.Services.Ordering.Domain; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; - using System; - using System.Linq; - using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +using System.Linq; +using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories +{ public class BuyerRepository : IBuyerRepository { @@ -33,16 +32,24 @@ public Buyer Add(Buyer buyer) { - return _context.Buyers - .Add(buyer) - .Entity; + if (buyer.IsTransient()) + { + return _context.Buyers + .Add(buyer) + .Entity; + } + else + { + return buyer; + } + } - public async Task FindAsync(string BuyerIdentityGuid) + public async Task FindAsync(string identity) { var buyer = await _context.Buyers .Include(b => b.Payments) - .Where(b => b.FullName == BuyerIdentityGuid) + .Where(b => b.FullName == identity) .SingleOrDefaultAsync(); return buyer; diff --git a/src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs b/src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs index b7995f039..62066dd91 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs @@ -1,14 +1,14 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories -{ - using Domain; - using Domain.SeedWork; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; - using System; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +using System; +namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories +{ public class OrderRepository : IOrderRepository { private readonly OrderingContext _context; + public IUnitOfWork UnitOfWork { get diff --git a/src/Services/Ordering/Ordering.Infrastructure/project.json b/src/Services/Ordering/Ordering.Infrastructure/project.json index 03c2eeef4..5d5355dfc 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/project.json +++ b/src/Services/Ordering/Ordering.Infrastructure/project.json @@ -2,14 +2,14 @@ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0", - "Microsoft.EntityFrameworkCore": "1.0.1", - "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", + "NETStandard.Library": "1.6.1", + "Microsoft.EntityFrameworkCore": "1.1.0", + "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0", "Ordering.Domain": "1.0.0-*" }, "frameworks": { - "netstandard1.6": { + "netstandard1.6.1": { "imports": "dnxcore50" } } diff --git a/test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs b/test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs index 3230b1924..1320d47e3 100644 --- a/test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs +++ b/test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs @@ -1,12 +1,13 @@ namespace FunctionalTests.Services.Ordering { - using Microsoft.eShopOnContainers.Services.Ordering.API.Models; + using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; using Newtonsoft.Json; using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Xunit; + using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; public class OrderingScenarios : OrderingScenarioBase @@ -64,34 +65,45 @@ string BuildOrder() { - var order = new NewOrderViewModel() + var order = new CreateOrderCommand() { CardExpiration = DateTime.UtcNow.AddYears(1), CardNumber = "5145-555-5555", CardHolderName = "Jhon Senna", CardSecurityNumber = "232", - CardType = "Amex", - ShippingCity = "Redmon", - ShippingCountry = "USA", - ShippingState = "WA", - ShippingStreet = "One way" + CardTypeId = 1, + City = "Redmon", + Country = "USA", + State = "WA", + Street = "One way", + ZipCode = "zipcode", }; + order.AddOrderItem(new OrderItemDTO() + { + ProductId = 1, + Discount = 10M, + UnitPrice = 10, + Units = 1, + ProductName = "Some name" + }); + return JsonConvert.SerializeObject(order); } string BuildOrderWithInvalidExperationTime() { - var order = new NewOrderViewModel() + var order = new CreateOrderCommand() { CardExpiration = DateTime.UtcNow.AddYears(-1), CardNumber = "5145-555-5555", CardHolderName = "Jhon Senna", CardSecurityNumber = "232", - CardType = "Amex", - ShippingCity = "Redmon", - ShippingCountry = "USA", - ShippingState = "WA", - ShippingStreet = "One way" + CardTypeId = 1, + City = "Redmon", + Country = "USA", + State = "WA", + Street = "One way", + ZipCode = "zipcode" }; return JsonConvert.SerializeObject(order); diff --git a/test/Services/FunctionalTests/project.json b/test/Services/FunctionalTests/project.json index 56d0182a2..9db48cfb1 100644 --- a/test/Services/FunctionalTests/project.json +++ b/test/Services/FunctionalTests/project.json @@ -2,21 +2,28 @@ "version": "1.0.0-*", "dependencies": { - "Microsoft.NETCore.App": "1.1.0", + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.1.0" + }, "Microsoft.AspNetCore.TestHost": "1.1.0", "dotnet-test-xunit": "2.2.0-preview2-build1029", + "Microsoft.DotNet.InternalAbstractions": "1.0.0", "xunit": "2.2.0-beta4-build3444", "Catalog.API": "1.0.0-*", "Ordering.API": "1.0.0-*" }, "testRunner": "xunit", - "runtimes": { - "win10-x64": {} - }, + //"runtimes": { + // "win10-x64": {} + //}, "frameworks": { - "netcoreapp1.0": { - "dependencies": { - } + "netcoreapp1.1": { + "imports": [ + "netstandard1.6.1", + "dnxcore50", + "portable-net451+win8" + ] } }, "publishOptions": { diff --git a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs index 47a57d578..af26cbe49 100644 --- a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs +++ b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs @@ -1,15 +1,14 @@ -namespace UnitTest.Ordering.Application +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Moq; +using System; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace UnitTest.Ordering.Application { - using Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands; - using Microsoft.eShopOnContainers.Services.Ordering.Domain; - using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories; - using Moq; - using System; - using System.Threading; - using System.Threading.Tasks; - using Xunit; - - public class NewOrderRequestHandlerTest { private readonly Mock _buyerRepositoryMock; @@ -26,7 +25,7 @@ public async Task Handle_returns_true_when_order_is_persisted_succesfully() { // Arrange - _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid)) + _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName)) .Returns(Task.FromResult(FakeBuyer())); _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) @@ -49,7 +48,7 @@ [Fact] public async Task Handle_return_false_if_order_is_not_persisted() { - _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid)) + _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName)) .Returns(Task.FromResult(FakeBuyer())); _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) @@ -74,17 +73,14 @@ private Order FakeOrder() { - return new Order(1, 1) - { - - }; + return new Order(1, 1, new Address("street", "city", "state", "country", "zipcode")); } private CreateOrderCommand FakeOrderRequestWithBuyer() { return new CreateOrderCommand { - BuyerIdentityGuid = "1234", + BuyerFullName = "1234", CardNumber = "1234", CardExpiration = DateTime.Now.AddYears(1), CardSecurityNumber = "123", diff --git a/test/Services/UnitTest/project.json b/test/Services/UnitTest/project.json index 0e54e4c4f..e44322750 100644 --- a/test/Services/UnitTest/project.json +++ b/test/Services/UnitTest/project.json @@ -2,23 +2,27 @@ "version": "1.0.0-*", "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.1.0" + }, "MediatR": "2.1.0", "Moq": "4.6.38-alpha", - "Microsoft.NETCore.App": "1.1.0", "xunit": "2.2.0-beta4-build3444", - "Ordering.API": "1.0.0-*", - "Catalog.API": "1.0.0-*", "Microsoft.AspNetCore.TestHost": "1.1.0", - "dotnet-test-xunit": "2.2.0-preview2-build1029" + "dotnet-test-xunit": "2.2.0-preview2-build1029", + "Ordering.API": "1.0.0-*", + "Ordering.Infrastructure": "1.0.0-*", + "Ordering.Domain": "1.0.0-*" }, "testRunner": "xunit", - "runtimes": { - "win10-x64": {} - }, "frameworks": { - "netcoreapp1.0": { - "dependencies": { - } + "netcoreapp1.1": { + "imports": [ + "netstandard1.6.1", + "dnxcore50", + "portable-net451+win8" + ] } } }