Improve ordering int order to solve feedback

This commit is contained in:
Unai Zorrilla Castro 2017-01-25 17:10:08 +01:00
parent 92cd474d34
commit 9d2d152c2d
34 changed files with 600 additions and 920 deletions

View File

@ -1,21 +1,16 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands using System;
{
using System;
using MediatR; using MediatR;
using Domain;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
//(CDLTLL) TO DO: This is wrong, we must NOT use a child-entity class within a Command class!! namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
//Need to create a different DTO class, like OrderLineDTO or similar... {
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
public class CreateOrderCommand public class CreateOrderCommand
:IAsyncRequest<bool> :IAsyncRequest<bool>
{ {
//(CDLTLL) TO DO: This is wrong, we must NOT use a child-entity class (OrderItem) within a Command class!! private readonly List<OrderItemDTO> _orderItems;
//Need to create a different DTO class, like OrderLineData or similar within the CreateOrderCommand class...
private readonly List<OrderItem> _orderItems;
public string City { get; set; } public string City { get; set; }
public string Street { get; set; } public string Street { get; set; }
@ -36,18 +31,32 @@
public int CardTypeId { get; set; } public int CardTypeId { get; set; }
public string BuyerIdentityGuid { get; set; } public string BuyerFullName { get; set; }
public IEnumerable<OrderItem> OrderItems => _orderItems; public IEnumerable<OrderItemDTO> Items => _orderItems;
public void AddOrderItem(OrderItem item) public void AddOrderItem(OrderItemDTO item)
{ {
_orderItems.Add(item); _orderItems.Add(item);
} }
public CreateOrderCommand() public CreateOrderCommand()
{ {
_orderItems = new List<OrderItem>(); _orderItems = new List<OrderItemDTO>();
}
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; }
} }
} }
} }

View File

@ -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.BuyerAggregate;
using Domain.AggregatesModel.OrderAggregate;
using MediatR; using MediatR;
using System.Linq;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Domain;
public class CreateOrderCommandHandler public class CreateOrderCommandHandler
: IAsyncRequestHandler<CreateOrderCommand, bool> : IAsyncRequestHandler<CreateOrderCommand, bool>
@ -29,36 +27,37 @@
_buyerRepository = buyerRepository; _buyerRepository = buyerRepository;
_orderRepository = orderRepository; _orderRepository = orderRepository;
} }
public async Task<bool> Handle(CreateOrderCommand message) public async Task<bool> Handle(CreateOrderCommand message)
{ {
//find buyer/payment or add a new one buyer/payment //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) 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 await _buyerRepository.UnitOfWork
.SaveChangesAsync(); .SaveChangesAsync();
//create order for buyer and payment method //create order for buyer and payment method
var order = CreateOrder(buyer.Id, payment.Id, 0); var order = new Order(buyer.Id, payment.Id, new Address(message.Street, message.City, message.State, message.Country, message.ZipCode));
order.SetAddress( new Address()
{
City = message.City,
State = message.State,
Street = message.Street,
ZipCode = 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); _orderRepository.Add(order);
@ -68,62 +67,5 @@
return result > 0; 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;
});
}
} }
} }

View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Decorators namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators
{ {
using Extensions.Logging; using Extensions.Logging;
using MediatR; using MediatR;

View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
{ {
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries
{ {
using Dapper; using Dapper;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;

View File

@ -1,16 +1,14 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers using MediatR;
{
using Api.Application.Commands;
using Api.Application.Queries;
using AspNetCore.Authorization;
using Infrastructure.Services;
using MediatR;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Models; 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{
[Route("api/v1/[controller]")] [Route("api/v1/[controller]")]
[Authorize] [Authorize]
public class OrdersController : Controller public class OrdersController : Controller
@ -46,9 +44,11 @@
public async Task<IActionResult> AddOrder([FromBody]CreateOrderCommand createOrderCommand) public async Task<IActionResult> AddOrder([FromBody]CreateOrderCommand createOrderCommand)
{ {
if (createOrderCommand.CardTypeId == 0) if (createOrderCommand.CardTypeId == 0)
{
createOrderCommand.CardTypeId = 1; createOrderCommand.CardTypeId = 1;
}
createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity(); createOrderCommand.BuyerFullName = _identityService.GetUserIdentity();
var added = await _mediator.SendAsync(createOrderCommand); var added = await _mediator.SendAsync(createOrderCommand);
if (added) if (added)

View File

@ -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 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 public class ApplicationModule
:Autofac.Module :Autofac.Module

View File

@ -1,14 +1,14 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules using Autofac;
{
using Api.Application.Commands;
using Api.Application.Decorators;
using Autofac;
using Autofac.Core; using Autofac.Core;
using MediatR; using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules
{
public class MediatorModule : Autofac.Module public class MediatorModule : Autofac.Module
{ {
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)

View File

@ -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<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("State");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("address","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Buyer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:HiLoSequenceName", "buyerseq")
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<string>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1);
b.Property<string>("Name")
.IsRequired()
.HasAnnotation("MaxLength", 200);
b.HasKey("Id");
b.ToTable("cardtypes","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:HiLoSequenceName", "orderseq")
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<int>("BuyerId");
b.Property<DateTime>("OrderDate");
b.Property<int>("PaymentId");
b.Property<int?>("ShippingAddressId");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd();
b.Property<decimal>("Discount");
b.Property<int>("OrderId");
b.Property<int>("ProductId");
b.Property<string>("ProductName")
.IsRequired();
b.Property<decimal>("UnitPrice");
b.Property<int>("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<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1);
b.Property<string>("Name")
.IsRequired()
.HasAnnotation("MaxLength", 200);
b.HasKey("Id");
b.ToTable("orderstatus","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.Payment", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:HiLoSequenceName", "paymentseq")
.HasAnnotation("SqlServer:HiLoSequenceSchema", "ordering")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<int>("BuyerId");
b.Property<string>("CardHolderName")
.IsRequired()
.HasAnnotation("MaxLength", 200);
b.Property<string>("CardNumber")
.IsRequired()
.HasAnnotation("MaxLength", 25);
b.Property<int>("CardTypeId");
b.Property<DateTime>("Expiration");
b.Property<string>("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);
});
}
}
}

View File

@ -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<string>(
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");
}
}
}

View File

@ -5,16 +5,17 @@ using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Ordering.API.Infrastructure.Migrations namespace Ordering.API.Migrations
{ {
[DbContext(typeof(OrderingContext))] [DbContext(typeof(OrderingContext))]
[Migration("20170118230807_PaymentMethodWithAlias")] [Migration("20170125143653_Initial")]
partial class PaymentMethodWithAlias partial class Initial
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder 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.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', '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:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
@ -30,7 +31,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<string>("FullName") b.Property<string>("FullName")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -43,12 +44,11 @@ namespace Ordering.API.Infrastructure.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1); .HasDefaultValue(1);
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -65,24 +65,22 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<string>("Alias") b.Property<string>("Alias")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("CardHolderName") b.Property<string>("CardHolderName")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.Property<string>("CardNumber") b.Property<string>("CardNumber")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 25); .HasMaxLength(25);
b.Property<int>("CardTypeId"); b.Property<int>("CardTypeId");
b.Property<DateTime>("Expiration"); b.Property<DateTime>("Expiration");
b.Property<string>("SecurityNumber");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
@ -92,26 +90,6 @@ namespace Ordering.API.Infrastructure.Migrations
b.ToTable("payments","ordering"); b.ToTable("payments","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("State");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("address","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -122,38 +100,46 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<DateTime>("OrderDate"); b.Property<DateTime>("OrderDate");
b.Property<int>("OrderStatusId");
b.Property<int>("PaymentId"); b.Property<int>("PaymentId");
b.Property<int?>("ShippingAddressId"); b.Property<string>("State")
.IsRequired();
b.Property<int>("StatusId"); b.Property<string>("Street")
.IsRequired();
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
b.HasIndex("OrderStatusId");
b.HasIndex("PaymentId"); b.HasIndex("PaymentId");
b.HasIndex("ShippingAddressId");
b.HasIndex("StatusId");
b.ToTable("orders","ordering"); b.ToTable("orders","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<decimal>("Discount"); b.Property<decimal>("Discount");
b.Property<int>("OrderId"); b.Property<int>("OrderId");
b.Property<string>("PictureUrl");
b.Property<int>("ProductId"); b.Property<int>("ProductId");
b.Property<string>("ProductName") b.Property<string>("ProductName")
@ -161,9 +147,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<decimal>("UnitPrice"); b.Property<decimal>("UnitPrice");
b.Property<int>("Units") b.Property<int>("Units");
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:DefaultValue", 1);
b.HasKey("Id"); b.HasKey("Id");
@ -175,12 +159,11 @@ namespace Ordering.API.Infrastructure.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1); .HasDefaultValue(1);
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -207,18 +190,14 @@ namespace Ordering.API.Infrastructure.Migrations
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
.WithMany()
.HasForeignKey("OrderStatusId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment")
.WithMany() .WithMany()
.HasForeignKey("PaymentId"); .HasForeignKey("PaymentId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "Status")
.WithMany()
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>

View File

@ -1,17 +1,20 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations; 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) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.EnsureSchema( migrationBuilder.EnsureSchema(
name: "ordering"); name: "ordering");
migrationBuilder.CreateSequence(
name: "orderitemseq",
incrementBy: 10);
migrationBuilder.CreateSequence( migrationBuilder.CreateSequence(
name: "buyerseq", name: "buyerseq",
schema: "ordering", schema: "ordering",
@ -27,24 +30,6 @@ namespace Ordering.API.Infrastructure.Migrations
schema: "ordering", schema: "ordering",
incrementBy: 10); incrementBy: 10);
migrationBuilder.CreateTable(
name: "address",
schema: "ordering",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
City = table.Column<string>(nullable: true),
Country = table.Column<string>(nullable: true),
State = table.Column<string>(nullable: true),
Street = table.Column<string>(nullable: true),
ZipCode = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_address", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "buyers", name: "buyers",
schema: "ordering", schema: "ordering",
@ -90,12 +75,12 @@ namespace Ordering.API.Infrastructure.Migrations
columns: table => new columns: table => new
{ {
Id = table.Column<int>(nullable: false), Id = table.Column<int>(nullable: false),
Alias = table.Column<string>(maxLength: 200, nullable: false),
BuyerId = table.Column<int>(nullable: false), BuyerId = table.Column<int>(nullable: false),
CardHolderName = table.Column<string>(maxLength: 200, nullable: false), CardHolderName = table.Column<string>(maxLength: 200, nullable: false),
CardNumber = table.Column<string>(maxLength: 25, nullable: false), CardNumber = table.Column<string>(maxLength: 25, nullable: false),
CardTypeId = table.Column<int>(nullable: false), CardTypeId = table.Column<int>(nullable: false),
Expiration = table.Column<DateTime>(nullable: false), Expiration = table.Column<DateTime>(nullable: false)
SecurityNumber = table.Column<string>(nullable: true)
}, },
constraints: table => constraints: table =>
{ {
@ -123,10 +108,13 @@ namespace Ordering.API.Infrastructure.Migrations
{ {
Id = table.Column<int>(nullable: false), Id = table.Column<int>(nullable: false),
BuyerId = table.Column<int>(nullable: false), BuyerId = table.Column<int>(nullable: false),
City = table.Column<string>(nullable: false),
OrderDate = table.Column<DateTime>(nullable: false), OrderDate = table.Column<DateTime>(nullable: false),
OrderStatusId = table.Column<int>(nullable: false),
PaymentId = table.Column<int>(nullable: false), PaymentId = table.Column<int>(nullable: false),
ShippingAddressId = table.Column<int>(nullable: true), State = table.Column<string>(nullable: false),
StatusId = table.Column<int>(nullable: false) Street = table.Column<string>(nullable: false),
ZipCode = table.Column<string>(nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -138,6 +126,13 @@ namespace Ordering.API.Infrastructure.Migrations
principalTable: "buyers", principalTable: "buyers",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_orders_orderstatus_OrderStatusId",
column: x => x.OrderStatusId,
principalSchema: "ordering",
principalTable: "orderstatus",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_orders_payments_PaymentId", name: "FK_orders_payments_PaymentId",
column: x => x.PaymentId, column: x => x.PaymentId,
@ -145,20 +140,6 @@ namespace Ordering.API.Infrastructure.Migrations
principalTable: "payments", principalTable: "payments",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Restrict); onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_orders_address_ShippingAddressId",
column: x => x.ShippingAddressId,
principalSchema: "ordering",
principalTable: "address",
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( migrationBuilder.CreateTable(
@ -166,15 +147,13 @@ namespace Ordering.API.Infrastructure.Migrations
schema: "ordering", schema: "ordering",
columns: table => new columns: table => new
{ {
Id = table.Column<int>(nullable: false) Id = table.Column<int>(nullable: false),
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Discount = table.Column<decimal>(nullable: false), Discount = table.Column<decimal>(nullable: false),
OrderId = table.Column<int>(nullable: false), OrderId = table.Column<int>(nullable: false),
ProductId = table.Column<int>(nullable: false), ProductId = table.Column<int>(nullable: false),
ProductName = table.Column<string>(nullable: false), ProductName = table.Column<string>(nullable: false),
PictureUrl = table.Column<string>(nullable: false),
UnitPrice = table.Column<decimal>(nullable: false), UnitPrice = table.Column<decimal>(nullable: false),
Units = table.Column<int>(nullable: false, defaultValue: 1) Units = table.Column<int>(nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -195,36 +174,6 @@ namespace Ordering.API.Infrastructure.Migrations
column: "FullName", column: "FullName",
unique: true); unique: true);
migrationBuilder.CreateIndex(
name: "IX_orders_BuyerId",
schema: "ordering",
table: "orders",
column: "BuyerId");
migrationBuilder.CreateIndex(
name: "IX_orders_PaymentId",
schema: "ordering",
table: "orders",
column: "PaymentId");
migrationBuilder.CreateIndex(
name: "IX_orders_ShippingAddressId",
schema: "ordering",
table: "orders",
column: "ShippingAddressId");
migrationBuilder.CreateIndex(
name: "IX_orders_StatusId",
schema: "ordering",
table: "orders",
column: "StatusId");
migrationBuilder.CreateIndex(
name: "IX_orderItems_OrderId",
schema: "ordering",
table: "orderItems",
column: "OrderId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_payments_BuyerId", name: "IX_payments_BuyerId",
schema: "ordering", schema: "ordering",
@ -236,10 +185,61 @@ namespace Ordering.API.Infrastructure.Migrations
schema: "ordering", schema: "ordering",
table: "payments", table: "payments",
column: "CardTypeId"); column: "CardTypeId");
migrationBuilder.CreateIndex(
name: "IX_orders_BuyerId",
schema: "ordering",
table: "orders",
column: "BuyerId");
migrationBuilder.CreateIndex(
name: "IX_orders_OrderStatusId",
schema: "ordering",
table: "orders",
column: "OrderStatusId");
migrationBuilder.CreateIndex(
name: "IX_orders_PaymentId",
schema: "ordering",
table: "orders",
column: "PaymentId");
migrationBuilder.CreateIndex(
name: "IX_orderItems_OrderId",
schema: "ordering",
table: "orderItems",
column: "OrderId");
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.DropTable(
name: "orderItems",
schema: "ordering");
migrationBuilder.DropTable(
name: "orders",
schema: "ordering");
migrationBuilder.DropTable(
name: "orderstatus",
schema: "ordering");
migrationBuilder.DropTable(
name: "payments",
schema: "ordering");
migrationBuilder.DropTable(
name: "buyers",
schema: "ordering");
migrationBuilder.DropTable(
name: "cardtypes",
schema: "ordering");
migrationBuilder.DropSequence(
name: "orderitemseq");
migrationBuilder.DropSequence( migrationBuilder.DropSequence(
name: "buyerseq", name: "buyerseq",
schema: "ordering"); schema: "ordering");
@ -251,34 +251,6 @@ namespace Ordering.API.Infrastructure.Migrations
migrationBuilder.DropSequence( migrationBuilder.DropSequence(
name: "paymentseq", name: "paymentseq",
schema: "ordering"); schema: "ordering");
migrationBuilder.DropTable(
name: "orderItems",
schema: "ordering");
migrationBuilder.DropTable(
name: "orders",
schema: "ordering");
migrationBuilder.DropTable(
name: "payments",
schema: "ordering");
migrationBuilder.DropTable(
name: "address",
schema: "ordering");
migrationBuilder.DropTable(
name: "orderstatus",
schema: "ordering");
migrationBuilder.DropTable(
name: "buyers",
schema: "ordering");
migrationBuilder.DropTable(
name: "cardtypes",
schema: "ordering");
} }
} }
} }

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
namespace Ordering.API.Infrastructure.Migrations namespace Ordering.API.Migrations
{ {
[DbContext(typeof(OrderingContext))] [DbContext(typeof(OrderingContext))]
partial class OrderingContextModelSnapshot : ModelSnapshot partial class OrderingContextModelSnapshot : ModelSnapshot
@ -13,7 +13,8 @@ namespace Ordering.API.Infrastructure.Migrations
protected override void BuildModel(ModelBuilder modelBuilder) protected override void BuildModel(ModelBuilder 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.buyerseq", "'buyerseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
.HasAnnotation("SqlServer:Sequence:ordering.orderseq", "'orderseq', '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:Sequence:ordering.paymentseq", "'paymentseq', 'ordering', '1', '10', '', '', 'Int64', 'False'")
@ -29,7 +30,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<string>("FullName") b.Property<string>("FullName")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -42,12 +43,11 @@ namespace Ordering.API.Infrastructure.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.CardType", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1); .HasDefaultValue(1);
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -64,24 +64,22 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<string>("Alias") b.Property<string>("Alias")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("CardHolderName") b.Property<string>("CardHolderName")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.Property<string>("CardNumber") b.Property<string>("CardNumber")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 25); .HasMaxLength(25);
b.Property<int>("CardTypeId"); b.Property<int>("CardTypeId");
b.Property<DateTime>("Expiration"); b.Property<DateTime>("Expiration");
b.Property<string>("SecurityNumber");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
@ -91,26 +89,6 @@ namespace Ordering.API.Infrastructure.Migrations
b.ToTable("payments","ordering"); b.ToTable("payments","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("State");
b.Property<string>("Street");
b.Property<string>("ZipCode");
b.HasKey("Id");
b.ToTable("address","ordering");
});
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -121,38 +99,46 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<DateTime>("OrderDate"); b.Property<DateTime>("OrderDate");
b.Property<int>("OrderStatusId");
b.Property<int>("PaymentId"); b.Property<int>("PaymentId");
b.Property<int?>("ShippingAddressId"); b.Property<string>("State")
.IsRequired();
b.Property<int>("StatusId"); b.Property<string>("Street")
.IsRequired();
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
b.HasIndex("OrderStatusId");
b.HasIndex("PaymentId"); b.HasIndex("PaymentId");
b.HasIndex("ShippingAddressId");
b.HasIndex("StatusId");
b.ToTable("orders","ordering"); b.ToTable("orders","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:HiLoSequenceName", "orderitemseq")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo);
b.Property<decimal>("Discount"); b.Property<decimal>("Discount");
b.Property<int>("OrderId"); b.Property<int>("OrderId");
b.Property<string>("PictureUrl");
b.Property<int>("ProductId"); b.Property<int>("ProductId");
b.Property<string>("ProductName") b.Property<string>("ProductName")
@ -160,9 +146,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<decimal>("UnitPrice"); b.Property<decimal>("UnitPrice");
b.Property<int>("Units") b.Property<int>("Units");
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:DefaultValue", 1);
b.HasKey("Id"); b.HasKey("Id");
@ -174,12 +158,11 @@ namespace Ordering.API.Infrastructure.Migrations
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasDefaultValue(1); .HasDefaultValue(1);
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasAnnotation("MaxLength", 200); .HasMaxLength(200);
b.HasKey("Id"); b.HasKey("Id");
@ -206,18 +189,14 @@ namespace Ordering.API.Infrastructure.Migrations
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
.WithMany()
.HasForeignKey("OrderStatusId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment") b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment")
.WithMany() .WithMany()
.HasForeignKey("PaymentId"); .HasForeignKey("PaymentId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress")
.WithMany()
.HasForeignKey("ShippingAddressId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "Status")
.WithMany()
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>

View File

@ -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<OrderItemViewModel> Items { get; set; }
public NewOrderViewModel()
{
Items = new List<OrderItemViewModel>();
}
}
}

View File

@ -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; }
}
}

View File

@ -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)

View File

@ -1,44 +1,45 @@
{ {
"dependencies": { "dependencies": {
"Microsoft.NETCore.App": { "Microsoft.NETCore.App": {
"version": "1.0.1", "version": "1.1.0",
"type": "platform" "type": "platform"
}, },
"MediatR.Extensions.Microsoft.DependencyInjection": "1.0.1", "MediatR.Extensions.Microsoft.DependencyInjection": "1.1.0",
"Autofac.Extensions.DependencyInjection": "4.0.0", "Autofac.Extensions.DependencyInjection": "4.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.1.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel":"1.0.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0", "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.1.0",
"Microsoft.Extensions.Logging.Abstractions": "1.0.0", "Microsoft.Extensions.Logging.Abstractions": "1.1.0",
"Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.1.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.1.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
"Microsoft.EntityFrameworkCore": "1.0.1", "Microsoft.EntityFrameworkCore": "1.1.0",
"Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.Design":"1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.1.0",
"Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Diagnostics": "1.1.0",
"Swashbuckle": "6.0.0-beta902", "Swashbuckle": "6.0.0-beta902",
"MediatR": "2.1.0", "MediatR": "2.1.0",
"Ordering.Domain": "1.0.0-*",
"Ordering.Infrastructure": "1.0.0-*",
"System.Reflection": "4.3.0", "System.Reflection": "4.3.0",
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3", "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": { "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" "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
}, },
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.1": {
"imports": [ "imports": [
"dotnet5.6", "netstandard1.6.1",
"portable-net45+win8" "dnxcore50",
"portable-net451+win8"
] ]
} }
}, },

View File

@ -1,27 +1,50 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
public class Buyer public class Buyer
: Entity, IAggregateRoot : Entity, IAggregateRoot
{ {
public string FullName { get; private set; } public string FullName { get; private set; }
public HashSet<Payment> Payments { get; private set; } private HashSet<Payment> _payments;
public IEnumerable<Payment> Payments => _payments?.ToList().AsEnumerable();
protected Buyer() { } protected Buyer() { }
public Buyer(string IdentityGuid) public Buyer(string identity)
{ {
if (String.IsNullOrWhiteSpace(IdentityGuid)) if (String.IsNullOrWhiteSpace(identity))
{ {
throw new ArgumentNullException(nameof(IdentityGuid)); throw new ArgumentNullException(nameof(identity));
} }
this.FullName = IdentityGuid; FullName = identity;
this.Payments = new HashSet<Payment>();
_payments = new HashSet<Payment>();
}
public Payment AddPayment(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)
{
var existingPayment = Payments.Where(p => p.IsEqualTo(cardTypeId, cardNumber, expiration))
.SingleOrDefault();
if (existingPayment != null)
{
return existingPayment;
}
else
{
var payment = new Payment(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration);
_payments.Add(payment);
return payment;
}
} }
} }
} }

View File

@ -1,12 +1,11 @@
 using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
public class CardType public class CardType
: Entity : Entity
{ {

View File

@ -1,30 +1,25 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System; using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
public class Payment public class Payment
: Entity : Entity
{ {
public string Alias { get; private set; } private int _buyerId;
public int BuyerId { get; private set; } private string _alias;
private string _cardNumber;
public string CardNumber { get; private set; } private string _securityNumber;
private string _cardHolderName;
public string SecurityNumber { get; private set; } private DateTime _expiration;
public string CardHolderName { get; private set; }
public int CardTypeId { get; private set; }
private int _cardTypeId;
public CardType CardType { get; private set; } public CardType CardType { get; private set; }
public DateTime Expiration { get; private set; }
protected Payment() { } 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)) if (String.IsNullOrWhiteSpace(cardNumber))
{ {
@ -46,12 +41,19 @@
throw new ArgumentException(nameof(expiration)); throw new ArgumentException(nameof(expiration));
} }
this.Alias = alias; _alias = alias;
this.CardNumber = cardNumber; _cardNumber = cardNumber;
this.SecurityNumber = securityNumber; _securityNumber = securityNumber;
this.CardHolderName = cardHolderName; _cardHolderName = cardHolderName;
this.Expiration = expiration; _expiration = expiration;
this.CardTypeId = cardTypeId; _cardTypeId = cardTypeId;
}
public bool IsEqualTo(int cardTypeId, string cardNumber,DateTime expiration)
{
return _cardTypeId == cardTypeId
&& _cardNumber == cardNumber
&& _expiration == expiration;
} }
} }
} }

View File

@ -1,22 +1,26 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate using System;
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
//(CDLTLL) namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
//TO DO: Need to convert this entity to a Value-Object (Address VO) {
public class Address 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;
}
} }
} }

View File

@ -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 //This is just the RepositoryContracts or Interface defined at the Domain Layer
//as requisite for the Order Aggregate //as requisite for the Order Aggregate

View File

@ -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 Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
//(CDLTLL) namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
//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
{ {
public int BuyerId { get; private set; } public class Order
: Entity
{
private string _street;
private string _city;
private string _state;
private string _country;
private string _zipCode;
private DateTime _orderDate;
public Buyer Buyer { get; private set; } public Buyer Buyer { get; private set; }
int _buyerId;
public DateTime OrderDate { get; private set; } public OrderStatus OrderStatus { get; private set; }
int _orderStatusId;
public int StatusId { get; private set; } HashSet<OrderItem> _orderItems;
public IEnumerable<OrderItem> OrderItems => _orderItems.ToList().AsEnumerable();
public OrderStatus Status { get; private set; }
public ICollection<OrderItem> OrderItems { get; private set; }
public int? ShippingAddressId { get; private set; }
public Address ShippingAddress { get; private set; }
public int PaymentId { get; private set; }
public Payment Payment { get; private set; } public Payment Payment { get; private set; }
int _paymentId;
protected Order() { } protected Order() { }
public Order(int buyerId, int paymentId) public Order(int buyerId, int paymentId, Address address)
{ {
BuyerId = buyerId;
PaymentId = paymentId; _buyerId = buyerId;
StatusId = OrderStatus.InProcess.Id; _paymentId = paymentId;
OrderDate = DateTime.UtcNow; _orderStatusId = OrderStatus.InProcess.Id;
OrderItems = new List<OrderItem>(); _orderDate = DateTime.UtcNow;
_street = address.Street;
_city = address.City;
_state = address.State;
_country = address.Country;
_zipCode = address.ZipCode;
_orderItems = new HashSet<OrderItem>();
} }
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..
}
ShippingAddress = address; if (discount > existingOrderForProduct.GetCurrentDiscount())
}
//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. existingOrderForProduct.SetNewDiscount(discount);
// The code "new OrderItem(params);" should be done here existingOrderForProduct.AddUnits(units);
// Plus any validation/rule related }
OrderItems.Add(item); }
else
{
//add validated new order item
//(CDLTLL) var orderItem = new OrderItem(productId, productName, unitPrice, discount, units);
// 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 _orderItems.Add(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.
} }
} }
} }

View File

@ -1,28 +1,74 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
{ using System;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
//TO DO: namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
//(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"..
public class OrderItem 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 string ProductName { get; set; } public int ProductId { get; private set; }
public string PictureUrl { get; set; }
public int OrderId { get; set; } protected OrderItem() { }
public decimal UnitPrice { get; set; } public OrderItem(int productId, string productName, decimal unitPrice, decimal discount, int units = 1)
{
if (units <= 0)
{
throw new ArgumentNullException("Invalid number of units");
}
public decimal Discount { get; set; } if ((unitPrice * units) < discount)
{
throw new ArgumentException("The total of order item is lower than applied discount");
}
public int Units { get; set; } ProductId = productId;
_productName = productName;
_unitPrice = unitPrice;
_discount = discount;
_units = units;
}
public void SetPictureUri(string pictureUri)
{
if (!String.IsNullOrWhiteSpace(pictureUri))
{
_pictureUrl = pictureUri;
}
}
public decimal GetCurrentDiscount()
{
return _discount;
}
public void SetNewDiscount(decimal discount)
{
if (discount < 0)
{
throw new ArgumentException("Discount is not valid");
}
_discount = discount;
}
public void AddUnits(int units)
{
if (units < 0)
{
throw new ArgumentException("Invalid units");
}
_units += units;
}
} }
} }

View File

@ -2,11 +2,11 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.6" "NETStandard.Library": "1.6.1"
}, },
"frameworks": { "frameworks": {
"netstandard1.6": { "netstandard1.6.1": {
"imports": "dnxcore50" "imports": "dnxcore50"
} }
} }

View File

@ -1,15 +1,13 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure using Microsoft.EntityFrameworkCore;
{ using Microsoft.EntityFrameworkCore.Metadata;
using System;
using System.Threading.Tasks;
using Domain.SeedWork;
using EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; 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.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure
{
public class OrderingContext public class OrderingContext
: DbContext,IUnitOfWork : DbContext,IUnitOfWork
@ -28,8 +26,6 @@
public DbSet<OrderStatus> OrderStatus { get; set; } public DbSet<OrderStatus> OrderStatus { get; set; }
public DbSet<Address> Addresses { get; set; }
public OrderingContext(DbContextOptions options) : base(options) { } public OrderingContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -40,16 +36,12 @@
modelBuilder.Entity<OrderItem>(ConfigureOrderItems); modelBuilder.Entity<OrderItem>(ConfigureOrderItems);
modelBuilder.Entity<CardType>(ConfigureCardTypes); modelBuilder.Entity<CardType>(ConfigureCardTypes);
modelBuilder.Entity<OrderStatus>(ConfigureOrderStatus); modelBuilder.Entity<OrderStatus>(ConfigureOrderStatus);
modelBuilder.Entity<Address>(ConfigureAddress);
} }
void ConfigureBuyer(EntityTypeBuilder<Buyer> buyerConfiguration) void ConfigureBuyer(EntityTypeBuilder<Buyer> buyerConfiguration)
{ {
buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA); buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA);
buyerConfiguration.HasIndex(b => b.FullName)
.IsUnique(true);
buyerConfiguration.HasKey(b => b.Id); buyerConfiguration.HasKey(b => b.Id);
buyerConfiguration.Property(b => b.Id) buyerConfiguration.Property(b => b.Id)
@ -59,10 +51,16 @@
.HasMaxLength(200) .HasMaxLength(200)
.IsRequired(); .IsRequired();
buyerConfiguration.HasIndex("FullName")
.IsUnique(true);
buyerConfiguration.HasMany(b => b.Payments) buyerConfiguration.HasMany(b => b.Payments)
.WithOne() .WithOne()
.HasForeignKey(p => p.BuyerId) .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.Payments));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
} }
void ConfigurePayment(EntityTypeBuilder<Payment> paymentConfiguration) void ConfigurePayment(EntityTypeBuilder<Payment> paymentConfiguration)
@ -74,24 +72,30 @@
paymentConfiguration.Property(b => b.Id) paymentConfiguration.Property(b => b.Id)
.ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); .ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA);
paymentConfiguration.Property(p => p.CardHolderName) paymentConfiguration.Property<int>("BuyerId")
.IsRequired();
paymentConfiguration.Property<string>("CardHolderName")
.HasMaxLength(200) .HasMaxLength(200)
.IsRequired(); .IsRequired();
paymentConfiguration.Property(p => p.Alias) paymentConfiguration.Property<string>("Alias")
.HasMaxLength(200) .HasMaxLength(200)
.IsRequired(); .IsRequired();
paymentConfiguration.Property(p => p.CardNumber) paymentConfiguration.Property<string>("CardNumber")
.HasMaxLength(25) .HasMaxLength(25)
.IsRequired(); .IsRequired();
paymentConfiguration.Property(p => p.Expiration) paymentConfiguration.Property<DateTime>("Expiration")
.IsRequired();
paymentConfiguration.Property<int>("CardTypeId")
.IsRequired(); .IsRequired();
paymentConfiguration.HasOne(p => p.CardType) paymentConfiguration.HasOne(p => p.CardType)
.WithMany() .WithMany()
.HasForeignKey(p => p.CardTypeId); .HasForeignKey("CardTypeId");
} }
void ConfigureOrder(EntityTypeBuilder<Order> orderConfiguration) void ConfigureOrder(EntityTypeBuilder<Order> orderConfiguration)
@ -103,21 +107,31 @@
orderConfiguration.Property(o => o.Id) orderConfiguration.Property(o => o.Id)
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA);
orderConfiguration.Property(o => o.OrderDate) orderConfiguration.Property<DateTime>("OrderDate").IsRequired();
.IsRequired(); orderConfiguration.Property<string>("Street").IsRequired();
orderConfiguration.Property<string>("State").IsRequired();
orderConfiguration.Property<string>("City").IsRequired();
orderConfiguration.Property<string>("ZipCode").IsRequired();
orderConfiguration.Property<int>("BuyerId").IsRequired();
orderConfiguration.Property<int>("OrderStatusId").IsRequired();
orderConfiguration.Property<int>("PaymentId").IsRequired();
var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
orderConfiguration.HasOne(o => o.Payment) orderConfiguration.HasOne(o => o.Payment)
.WithMany() .WithMany()
.HasForeignKey(o => o.PaymentId) .HasForeignKey("PaymentId")
.OnDelete(DeleteBehavior.Restrict); .OnDelete(DeleteBehavior.Restrict);
orderConfiguration.HasOne(o => o.Buyer) orderConfiguration.HasOne(o => o.Buyer)
.WithMany() .WithMany()
.HasForeignKey(o => o.BuyerId); .HasForeignKey("BuyerId");
orderConfiguration.HasOne(o => o.Status) orderConfiguration.HasOne(o => o.OrderStatus)
.WithMany() .WithMany()
.HasForeignKey(o => o.StatusId); .HasForeignKey("OrderStatusId");
} }
void ConfigureOrderItems(EntityTypeBuilder<OrderItem> orderItemConfiguration) void ConfigureOrderItems(EntityTypeBuilder<OrderItem> orderItemConfiguration)
@ -126,20 +140,25 @@
orderItemConfiguration.HasKey(o => o.Id); orderItemConfiguration.HasKey(o => o.Id);
orderItemConfiguration.Property(o => o.Discount) orderItemConfiguration.Property(o => o.Id)
.ForSqlServerUseSequenceHiLo("orderitemseq");
orderItemConfiguration.Property<int>("OrderId")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.ProductId) orderItemConfiguration.Property<decimal>("Discount")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.ProductName) orderItemConfiguration.Property<int>("ProductId")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.UnitPrice) orderItemConfiguration.Property<string>("ProductName")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.Units) orderItemConfiguration.Property<decimal>("UnitPrice")
.ForSqlServerHasDefaultValue(1) .IsRequired();
orderItemConfiguration.Property<int>("Units")
.IsRequired(); .IsRequired();
} }
@ -151,6 +170,7 @@
orderStatusConfiguration.Property(o => o.Id) orderStatusConfiguration.Property(o => o.Id)
.HasDefaultValue(1) .HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired(); .IsRequired();
orderStatusConfiguration.Property(o => o.Name) orderStatusConfiguration.Property(o => o.Name)
@ -166,16 +186,12 @@
cardTypesConfiguration.Property(ct => ct.Id) cardTypesConfiguration.Property(ct => ct.Id)
.HasDefaultValue(1) .HasDefaultValue(1)
.ValueGeneratedNever()
.IsRequired(); .IsRequired();
cardTypesConfiguration.Property(ct => ct.Name) cardTypesConfiguration.Property(ct => ct.Name)
.HasMaxLength(200) .HasMaxLength(200)
.IsRequired(); .IsRequired();
} }
void ConfigureAddress(EntityTypeBuilder<Address> addressConfiguration)
{
addressConfiguration.ToTable("address", DEFAULT_SCHEMA);
}
} }
} }

View File

@ -1,13 +1,12 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories using Microsoft.EntityFrameworkCore;
{
using Domain.SeedWork;
using Microsoft.EntityFrameworkCore;
using Microsoft.eShopOnContainers.Services.Ordering.Domain;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
{
public class BuyerRepository public class BuyerRepository
: IBuyerRepository : IBuyerRepository
{ {
@ -32,17 +31,25 @@
} }
public Buyer Add(Buyer buyer) public Buyer Add(Buyer buyer)
{
if (buyer.IsTransient())
{ {
return _context.Buyers return _context.Buyers
.Add(buyer) .Add(buyer)
.Entity; .Entity;
} }
else
{
return buyer;
}
public async Task<Buyer> FindAsync(string BuyerIdentityGuid) }
public async Task<Buyer> FindAsync(string identity)
{ {
var buyer = await _context.Buyers var buyer = await _context.Buyers
.Include(b => b.Payments) .Include(b => b.Payments)
.Where(b => b.FullName == BuyerIdentityGuid) .Where(b => b.FullName == identity)
.SingleOrDefaultAsync(); .SingleOrDefaultAsync();
return buyer; return buyer;

View File

@ -1,14 +1,14 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
{ using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Domain;
using Domain.SeedWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using System; using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories
{
public class OrderRepository public class OrderRepository
: IOrderRepository : IOrderRepository
{ {
private readonly OrderingContext _context; private readonly OrderingContext _context;
public IUnitOfWork UnitOfWork public IUnitOfWork UnitOfWork
{ {
get get

View File

@ -2,14 +2,14 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.6.0", "NETStandard.Library": "1.6.1",
"Microsoft.EntityFrameworkCore": "1.0.1", "Microsoft.EntityFrameworkCore": "1.1.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
"Ordering.Domain": "1.0.0-*" "Ordering.Domain": "1.0.0-*"
}, },
"frameworks": { "frameworks": {
"netstandard1.6": { "netstandard1.6.1": {
"imports": "dnxcore50" "imports": "dnxcore50"
} }
} }

View File

@ -1,12 +1,13 @@
namespace FunctionalTests.Services.Ordering namespace FunctionalTests.Services.Ordering
{ {
using Microsoft.eShopOnContainers.Services.Ordering.API.Models; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
public class OrderingScenarios public class OrderingScenarios
: OrderingScenarioBase : OrderingScenarioBase
@ -64,34 +65,45 @@
string BuildOrder() string BuildOrder()
{ {
var order = new NewOrderViewModel() var order = new CreateOrderCommand()
{ {
CardExpiration = DateTime.UtcNow.AddYears(1), CardExpiration = DateTime.UtcNow.AddYears(1),
CardNumber = "5145-555-5555", CardNumber = "5145-555-5555",
CardHolderName = "Jhon Senna", CardHolderName = "Jhon Senna",
CardSecurityNumber = "232", CardSecurityNumber = "232",
CardType = "Amex", CardTypeId = 1,
ShippingCity = "Redmon", City = "Redmon",
ShippingCountry = "USA", Country = "USA",
ShippingState = "WA", State = "WA",
ShippingStreet = "One way" Street = "One way",
ZipCode = "zipcode",
}; };
order.AddOrderItem(new OrderItemDTO()
{
ProductId = 1,
Discount = 10M,
UnitPrice = 10,
Units = 1,
ProductName = "Some name"
});
return JsonConvert.SerializeObject(order); return JsonConvert.SerializeObject(order);
} }
string BuildOrderWithInvalidExperationTime() string BuildOrderWithInvalidExperationTime()
{ {
var order = new NewOrderViewModel() var order = new CreateOrderCommand()
{ {
CardExpiration = DateTime.UtcNow.AddYears(-1), CardExpiration = DateTime.UtcNow.AddYears(-1),
CardNumber = "5145-555-5555", CardNumber = "5145-555-5555",
CardHolderName = "Jhon Senna", CardHolderName = "Jhon Senna",
CardSecurityNumber = "232", CardSecurityNumber = "232",
CardType = "Amex", CardTypeId = 1,
ShippingCity = "Redmon", City = "Redmon",
ShippingCountry = "USA", Country = "USA",
ShippingState = "WA", State = "WA",
ShippingStreet = "One way" Street = "One way",
ZipCode = "zipcode"
}; };
return JsonConvert.SerializeObject(order); return JsonConvert.SerializeObject(order);

View File

@ -2,21 +2,28 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"Microsoft.NETCore.App": "1.1.0", "Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
},
"Microsoft.AspNetCore.TestHost": "1.1.0", "Microsoft.AspNetCore.TestHost": "1.1.0",
"dotnet-test-xunit": "2.2.0-preview2-build1029", "dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.DotNet.InternalAbstractions": "1.0.0",
"xunit": "2.2.0-beta4-build3444", "xunit": "2.2.0-beta4-build3444",
"Catalog.API": "1.0.0-*", "Catalog.API": "1.0.0-*",
"Ordering.API": "1.0.0-*" "Ordering.API": "1.0.0-*"
}, },
"testRunner": "xunit", "testRunner": "xunit",
"runtimes": { //"runtimes": {
"win10-x64": {} // "win10-x64": {}
}, //},
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.1": {
"dependencies": { "imports": [
} "netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
]
} }
}, },
"publishOptions": { "publishOptions": {

View File

@ -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.Api.Application.Commands; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Repositories;
using Moq; using Moq;
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
namespace UnitTest.Ordering.Application
{
public class NewOrderRequestHandlerTest public class NewOrderRequestHandlerTest
{ {
private readonly Mock<IBuyerRepository> _buyerRepositoryMock; private readonly Mock<IBuyerRepository> _buyerRepositoryMock;
@ -26,7 +25,7 @@
public async Task Handle_returns_true_when_order_is_persisted_succesfully() public async Task Handle_returns_true_when_order_is_persisted_succesfully()
{ {
// Arrange // Arrange
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid)) _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerFullName))
.Returns(Task.FromResult<Buyer>(FakeBuyer())); .Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -49,7 +48,7 @@
[Fact] [Fact]
public async Task Handle_return_false_if_order_is_not_persisted() 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<Buyer>(FakeBuyer())); .Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) _buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -74,17 +73,14 @@
private Order FakeOrder() private Order FakeOrder()
{ {
return new Order(1, 1) return new Order(1, 1, new Address("street", "city", "state", "country", "zipcode"));
{
};
} }
private CreateOrderCommand FakeOrderRequestWithBuyer() private CreateOrderCommand FakeOrderRequestWithBuyer()
{ {
return new CreateOrderCommand return new CreateOrderCommand
{ {
BuyerIdentityGuid = "1234", BuyerFullName = "1234",
CardNumber = "1234", CardNumber = "1234",
CardExpiration = DateTime.Now.AddYears(1), CardExpiration = DateTime.Now.AddYears(1),
CardSecurityNumber = "123", CardSecurityNumber = "123",

View File

@ -2,23 +2,27 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.1.0"
},
"MediatR": "2.1.0", "MediatR": "2.1.0",
"Moq": "4.6.38-alpha", "Moq": "4.6.38-alpha",
"Microsoft.NETCore.App": "1.1.0",
"xunit": "2.2.0-beta4-build3444", "xunit": "2.2.0-beta4-build3444",
"Ordering.API": "1.0.0-*",
"Catalog.API": "1.0.0-*",
"Microsoft.AspNetCore.TestHost": "1.1.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", "testRunner": "xunit",
"runtimes": {
"win10-x64": {}
},
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.1": {
"dependencies": { "imports": [
} "netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
]
} }
} }
} }