Browse Source

Merge branch 'master' of https://github.com/dotnet/eShopOnContainers

pull/49/merge
PLAINCONCEPTS\ccanizares 8 years ago
parent
commit
f1fc4c0552
47 changed files with 675 additions and 968 deletions
  1. +28
    -17
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
  2. +16
    -74
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
  3. +1
    -1
      src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs
  4. +1
    -1
      src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs
  5. +4
    -5
      src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
  6. +14
    -13
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  7. +1
    -1
      src/Services/Ordering/Ordering.API/Dockerfile
  8. +0
    -2
      src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs
  9. +5
    -6
      src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs
  10. +10
    -10
      src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs
  11. +0
    -227
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.Designer.cs
  12. +0
    -28
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.cs
  13. +42
    -58
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.Designer.cs
  14. +60
    -86
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.cs
  15. +40
    -56
      src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs
  16. +0
    -35
      src/Services/Ordering/Ordering.API/Models/NewOrderViewModel.cs
  17. +0
    -19
      src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs
  18. +0
    -5
      src/Services/Ordering/Ordering.API/Models/_REFACTORING TO DO - Remove ViewModel classes.txt
  19. +26
    -25
      src/Services/Ordering/Ordering.API/project.json
  20. +1
    -1
      src/Services/Ordering/Ordering.API/settings.json
  21. +35
    -12
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs
  22. +5
    -6
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs
  23. +1
    -1
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs
  24. +0
    -57
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs
  25. +59
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs
  26. +16
    -12
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs
  27. +3
    -4
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs
  28. +53
    -57
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  29. +63
    -16
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs
  30. +1
    -1
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs
  31. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs
  32. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/IAggregateRoot.cs
  33. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/IRepository.cs
  34. +1
    -1
      src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs
  35. +2
    -2
      src/Services/Ordering/Ordering.Domain/project.json
  36. +71
    -50
      src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs
  37. +22
    -15
      src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs
  38. +6
    -6
      src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs
  39. +4
    -4
      src/Services/Ordering/Ordering.Infrastructure/project.json
  40. +1
    -0
      src/Web/WebMVC/Models/Order.cs
  41. +11
    -1
      src/Web/WebMVC/Services/OrderingService.cs
  42. +1
    -0
      src/Web/WebMVC/Views/Order/Create.cshtml
  43. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts
  44. +25
    -13
      test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs
  45. +14
    -7
      test/Services/FunctionalTests/project.json
  46. +14
    -19
      test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs
  47. +14
    -10
      test/Services/UnitTest/project.json

+ 28
- 17
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs View File

@ -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 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!!
//Need to create a different DTO class, like OrderLineData or similar within the CreateOrderCommand class...
private readonly List<OrderItem> _orderItems;
private readonly List<OrderItemDTO> _orderItems;
public string City { get; set; } public string City { get; set; }
public string Street { get; set; } public string Street { get; set; }
@ -36,18 +31,34 @@
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> OrderItems => _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; }
public string PictureUrl { get; set; }
} }
} }
} }

+ 16
- 74
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs 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>
@ -14,7 +12,7 @@
private readonly IBuyerRepository _buyerRepository; private readonly IBuyerRepository _buyerRepository;
private readonly IOrderRepository _orderRepository; private readonly IOrderRepository _orderRepository;
public CreateOrderCommandHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository)
public CreateOrderCommandHandler(IBuyerRepository buyerRepository, IOrderRepository orderRepository)
{ {
if (buyerRepository == null) if (buyerRepository == null)
{ {
@ -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.AddPaymentMethod(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);
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.OrderItems)
{ {
order.AddOrderItem(item);
order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, 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;
});
}
} }
} }

+ 1
- 1
src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs 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;


+ 1
- 1
src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs 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;


+ 4
- 5
src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs 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;
@ -28,11 +28,10 @@
var result = await connection.QueryAsync<dynamic>( var result = await connection.QueryAsync<dynamic>(
@"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status, @"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status,
oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl, oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl,
oa.Street as street, oa.City as city, oa.Country as country, oa.State as state, oa.ZipCode as zipcode
o.Street as street, o.City as city, o.Country as country, o.State as state, o.ZipCode as zipcode
FROM ordering.Orders o FROM ordering.Orders o
LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid
LEFT JOIN ordering.orderstatus os on o.StatusId = os.Id
LEFT JOIN ordering.address oa on o.ShippingAddressId = oa.Id
LEFT JOIN ordering.orderstatus os on o.OrderStatusId = os.Id
WHERE o.Id=@id" WHERE o.Id=@id"
, new { id } , new { id }
); );
@ -53,7 +52,7 @@
return await connection.QueryAsync<dynamic>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total return await connection.QueryAsync<dynamic>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total
FROM [ordering].[Orders] o FROM [ordering].[Orders] o
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid
LEFT JOIN[ordering].[orderstatus] os on o.StatusId = os.Id
LEFT JOIN[ordering].[orderstatus] os on o.OrderStatusId = os.Id
GROUP BY o.[Id], o.[OrderDate], os.[Name]"); GROUP BY o.[Id], o.[OrderDate], os.[Name]");
} }
} }


+ 14
- 13
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -1,16 +1,15 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
using MediatR;
using Microsoft.AspNetCore.Authorization;
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]")] [Route("api/v1/[controller]")]
[Authorize] [Authorize]
public class OrdersController : Controller public class OrdersController : Controller
@ -46,9 +45,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)


+ 1
- 1
src/Services/Ordering/Ordering.API/Dockerfile View File

@ -1,4 +1,4 @@
FROM microsoft/aspnetcore:1.0.1
FROM microsoft/aspnetcore:1.1
# Entry point through the copied assembly # Entry point through the copied assembly
ENTRYPOINT ["dotnet", "Ordering.API.dll"] ENTRYPOINT ["dotnet", "Ordering.API.dll"]


+ 0
- 2
src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs View File

@ -1,10 +1,8 @@
using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Authorization;
using Swashbuckle.Swagger.Model; using Swashbuckle.Swagger.Model;
using Swashbuckle.SwaggerGen.Generator; using Swashbuckle.SwaggerGen.Generator;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Auth namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Auth
{ {


+ 5
- 6
src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs 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


+ 10
- 10
src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs View File

@ -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 public class MediatorModule : Autofac.Module
{ {
protected override void Load(ContainerBuilder builder) protected override void Load(ContainerBuilder builder)


+ 0
- 227
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.Designer.cs 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);
});
}
}
}

+ 0
- 28
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.cs 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");
}
}
}

src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170118230807_PaymentMethodWithAlias.Designer.cs → src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.Designer.cs 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")]
partial class PaymentMethodWithAlias
[Migration("20170127103457_Initial")]
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,19 +44,18 @@ 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");
b.ToTable("cardtypes","ordering"); b.ToTable("cardtypes","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", b =>
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@ -65,51 +65,29 @@ 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");
b.HasIndex("CardTypeId"); b.HasIndex("CardTypeId");
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");
b.ToTable("paymentmethods","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
@ -122,23 +100,34 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<string>("Country")
.IsRequired();
b.Property<DateTime>("OrderDate"); b.Property<DateTime>("OrderDate");
b.Property<int>("PaymentId");
b.Property<int>("OrderStatusId");
b.Property<int>("PaymentMethodId");
b.Property<string>("State")
.IsRequired();
b.Property<int?>("ShippingAddressId");
b.Property<string>("Street")
.IsRequired();
b.Property<int>("StatusId");
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
b.HasIndex("PaymentId");
b.HasIndex("ShippingAddressId");
b.HasIndex("OrderStatusId");
b.HasIndex("StatusId");
b.HasIndex("PaymentMethodId");
b.ToTable("orders","ordering"); b.ToTable("orders","ordering");
}); });
@ -146,7 +135,9 @@ namespace Ordering.API.Infrastructure.Migrations
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");
@ -161,9 +152,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<decimal>("UnitPrice"); b.Property<decimal>("UnitPrice");
b.Property<int>("Units")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:DefaultValue", 1);
b.Property<int>("Units");
b.HasKey("Id"); b.HasKey("Id");
@ -175,22 +164,21 @@ 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");
b.ToTable("orderstatus","ordering"); b.ToTable("orderstatus","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", b =>
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
{ {
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer") b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
.WithMany("Payments")
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
@ -207,18 +195,14 @@ namespace Ordering.API.Infrastructure.Migrations
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment")
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
.WithMany() .WithMany()
.HasForeignKey("PaymentId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress")
.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.PaymentMethod", "PaymentMethod")
.WithMany() .WithMany()
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade);
.HasForeignKey("PaymentMethodId");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>

src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20161124133626_InitialModel.cs → src/Services/Ordering/Ordering.API/Infrastructure/Migrations/20170127103457_Initial.cs 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",
@ -85,30 +70,30 @@ namespace Ordering.API.Infrastructure.Migrations
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "payments",
name: "paymentmethods",
schema: "ordering", schema: "ordering",
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),
SecurityNumber = table.Column<string>(nullable: true)
Expiration = table.Column<DateTime>(nullable: false)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_payments", x => x.Id);
table.PrimaryKey("PK_paymentmethods", x => x.Id);
table.ForeignKey( table.ForeignKey(
name: "FK_payments_buyers_BuyerId",
name: "FK_paymentmethods_buyers_BuyerId",
column: x => x.BuyerId, column: x => x.BuyerId,
principalSchema: "ordering", principalSchema: "ordering",
principalTable: "buyers", principalTable: "buyers",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_payments_cardtypes_CardTypeId",
name: "FK_paymentmethods_cardtypes_CardTypeId",
column: x => x.CardTypeId, column: x => x.CardTypeId,
principalSchema: "ordering", principalSchema: "ordering",
principalTable: "cardtypes", principalTable: "cardtypes",
@ -123,10 +108,14 @@ 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),
Country = table.Column<string>(nullable: false),
OrderDate = table.Column<DateTime>(nullable: false), OrderDate = table.Column<DateTime>(nullable: false),
PaymentId = table.Column<int>(nullable: false),
ShippingAddressId = table.Column<int>(nullable: true),
StatusId = table.Column<int>(nullable: false)
OrderStatusId = table.Column<int>(nullable: false),
PaymentMethodId = table.Column<int>(nullable: false),
State = table.Column<string>(nullable: false),
Street = table.Column<string>(nullable: false),
ZipCode = table.Column<string>(nullable: false)
}, },
constraints: table => constraints: table =>
{ {
@ -139,26 +128,19 @@ namespace Ordering.API.Infrastructure.Migrations
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_orders_payments_PaymentId",
column: x => x.PaymentId,
name: "FK_orders_orderstatus_OrderStatusId",
column: x => x.OrderStatusId,
principalSchema: "ordering", principalSchema: "ordering",
principalTable: "payments",
principalTable: "orderstatus",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_orders_address_ShippingAddressId",
column: x => x.ShippingAddressId,
name: "FK_orders_paymentmethods_PaymentMethodId",
column: x => x.PaymentMethodId,
principalSchema: "ordering", principalSchema: "ordering",
principalTable: "address",
principalTable: "paymentmethods",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Restrict); 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 +148,14 @@ namespace Ordering.API.Infrastructure.Migrations
schema: "ordering", schema: "ordering",
columns: table => new columns: table => new
{ {
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Id = table.Column<int>(nullable: false),
Discount = table.Column<decimal>(nullable: false), Discount = table.Column<decimal>(nullable: false),
OrderId = table.Column<int>(nullable: false), OrderId = table.Column<int>(nullable: false),
PictureUrl = table.Column<string>(nullable: true),
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 =>
{ {
@ -196,62 +177,44 @@ namespace Ordering.API.Infrastructure.Migrations
unique: true); unique: true);
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_orders_BuyerId",
name: "IX_paymentmethods_BuyerId",
schema: "ordering", schema: "ordering",
table: "orders",
table: "paymentmethods",
column: "BuyerId"); column: "BuyerId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_orders_PaymentId",
name: "IX_paymentmethods_CardTypeId",
schema: "ordering",
table: "paymentmethods",
column: "CardTypeId");
migrationBuilder.CreateIndex(
name: "IX_orders_BuyerId",
schema: "ordering", schema: "ordering",
table: "orders", table: "orders",
column: "PaymentId");
column: "BuyerId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_orders_ShippingAddressId",
name: "IX_orders_OrderStatusId",
schema: "ordering", schema: "ordering",
table: "orders", table: "orders",
column: "ShippingAddressId");
column: "OrderStatusId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_orders_StatusId",
name: "IX_orders_PaymentMethodId",
schema: "ordering", schema: "ordering",
table: "orders", table: "orders",
column: "StatusId");
column: "PaymentMethodId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_orderItems_OrderId", name: "IX_orderItems_OrderId",
schema: "ordering", schema: "ordering",
table: "orderItems", table: "orderItems",
column: "OrderId"); 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) 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( migrationBuilder.DropTable(
name: "orderItems", name: "orderItems",
schema: "ordering"); schema: "ordering");
@ -261,15 +224,11 @@ namespace Ordering.API.Infrastructure.Migrations
schema: "ordering"); schema: "ordering");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "payments",
schema: "ordering");
migrationBuilder.DropTable(
name: "address",
name: "orderstatus",
schema: "ordering"); schema: "ordering");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "orderstatus",
name: "paymentmethods",
schema: "ordering"); schema: "ordering");
migrationBuilder.DropTable( migrationBuilder.DropTable(
@ -279,6 +238,21 @@ namespace Ordering.API.Infrastructure.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "cardtypes", name: "cardtypes",
schema: "ordering"); schema: "ordering");
migrationBuilder.DropSequence(
name: "orderitemseq");
migrationBuilder.DropSequence(
name: "buyerseq",
schema: "ordering");
migrationBuilder.DropSequence(
name: "orderseq",
schema: "ordering");
migrationBuilder.DropSequence(
name: "paymentseq",
schema: "ordering");
} }
} }
} }

+ 40
- 56
src/Services/Ordering/Ordering.API/Infrastructure/Migrations/OrderingContextModelSnapshot.cs 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,19 +43,18 @@ 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");
b.ToTable("cardtypes","ordering"); b.ToTable("cardtypes","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", b =>
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@ -64,51 +64,29 @@ 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");
b.HasIndex("CardTypeId"); b.HasIndex("CardTypeId");
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");
b.ToTable("paymentmethods","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Order", b =>
@ -121,23 +99,34 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<int>("BuyerId"); b.Property<int>("BuyerId");
b.Property<string>("City")
.IsRequired();
b.Property<string>("Country")
.IsRequired();
b.Property<DateTime>("OrderDate"); b.Property<DateTime>("OrderDate");
b.Property<int>("PaymentId");
b.Property<int>("OrderStatusId");
b.Property<int>("PaymentMethodId");
b.Property<string>("State")
.IsRequired();
b.Property<int?>("ShippingAddressId");
b.Property<string>("Street")
.IsRequired();
b.Property<int>("StatusId");
b.Property<string>("ZipCode")
.IsRequired();
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("BuyerId"); b.HasIndex("BuyerId");
b.HasIndex("PaymentId");
b.HasIndex("ShippingAddressId");
b.HasIndex("OrderStatusId");
b.HasIndex("StatusId");
b.HasIndex("PaymentMethodId");
b.ToTable("orders","ordering"); b.ToTable("orders","ordering");
}); });
@ -145,7 +134,9 @@ namespace Ordering.API.Infrastructure.Migrations
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");
@ -160,9 +151,7 @@ namespace Ordering.API.Infrastructure.Migrations
b.Property<decimal>("UnitPrice"); b.Property<decimal>("UnitPrice");
b.Property<int>("Units")
.ValueGeneratedOnAdd()
.HasAnnotation("SqlServer:DefaultValue", 1);
b.Property<int>("Units");
b.HasKey("Id"); b.HasKey("Id");
@ -174,22 +163,21 @@ 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");
b.ToTable("orderstatus","ordering"); b.ToTable("orderstatus","ordering");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", b =>
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.PaymentMethod", b =>
{ {
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer") b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Buyer")
.WithMany("Payments")
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
@ -206,18 +194,14 @@ namespace Ordering.API.Infrastructure.Migrations
.HasForeignKey("BuyerId") .HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate.Payment", "Payment")
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderStatus", "OrderStatus")
.WithMany() .WithMany()
.HasForeignKey("PaymentId");
b.HasOne("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.Address", "ShippingAddress")
.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.PaymentMethod", "PaymentMethod")
.WithMany() .WithMany()
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.Cascade);
.HasForeignKey("PaymentMethodId");
}); });
modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b => modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate.OrderItem", b =>


+ 0
- 35
src/Services/Ordering/Ordering.API/Models/NewOrderViewModel.cs 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>();
}
}
}

+ 0
- 19
src/Services/Ordering/Ordering.API/Models/OrderItemViewModel.cs 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; }
}
}

+ 0
- 5
src/Services/Ordering/Ordering.API/Models/_REFACTORING TO DO - Remove ViewModel classes.txt 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)

+ 26
- 25
src/Services/Ordering/Ordering.API/project.json 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.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", "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",
"portable-net45+win8"
"netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
] ]
} }
}, },


+ 1
- 1
src/Services/Ordering/Ordering.API/settings.json View File

@ -1,6 +1,6 @@
{ {
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", "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": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {


+ 35
- 12
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs View File

@ -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 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<PaymentMethod> _paymentMethods;
public IEnumerable<PaymentMethod> PaymentMethods => _paymentMethods?.ToList().AsEnumerable();
protected Buyer() { } protected Buyer() { }
public Buyer(string IdentityGuid)
public Buyer(string identity)
{
if (String.IsNullOrWhiteSpace(identity))
{
throw new ArgumentNullException(nameof(identity));
}
FullName = identity;
_paymentMethods = new HashSet<PaymentMethod>();
}
public PaymentMethod AddPaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)
{ {
if (String.IsNullOrWhiteSpace(IdentityGuid))
var existingPayment = _paymentMethods.Where(p => p.IsEqualTo(cardTypeId, cardNumber, expiration))
.SingleOrDefault();
if (existingPayment != null)
{ {
throw new ArgumentNullException(nameof(IdentityGuid));
return existingPayment;
} }
else
{
var payment = new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration);
_paymentMethods.Add(payment);
this.FullName = IdentityGuid;
this.Payments = new HashSet<Payment>();
return payment;
}
} }
} }
} }

+ 5
- 6
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.cs View File

@ -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 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 public class CardType
: Entity : Entity
{ {


+ 1
- 1
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/IBuyerRepository.cs View File

@ -1,4 +1,4 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using System.Threading.Tasks; using System.Threading.Tasks;


+ 0
- 57
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Payment.cs View File

@ -1,57 +0,0 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using System;
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; }
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)
{
if (String.IsNullOrWhiteSpace(cardNumber))
{
throw new ArgumentException(nameof(cardNumber));
}
if (String.IsNullOrWhiteSpace(securityNumber))
{
throw new ArgumentException(nameof(securityNumber));
}
if (String.IsNullOrWhiteSpace(cardHolderName))
{
throw new ArgumentException(nameof(cardHolderName));
}
if (expiration < DateTime.UtcNow)
{
throw new ArgumentException(nameof(expiration));
}
this.Alias = alias;
this.CardNumber = cardNumber;
this.SecurityNumber = securityNumber;
this.CardHolderName = cardHolderName;
this.Expiration = expiration;
this.CardTypeId = cardTypeId;
}
}
}

+ 59
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs View File

@ -0,0 +1,59 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using System;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate
{
public class PaymentMethod
: Entity
{
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; }
protected PaymentMethod() { }
public PaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration)
{
if (String.IsNullOrWhiteSpace(cardNumber))
{
throw new ArgumentException(nameof(cardNumber));
}
if (String.IsNullOrWhiteSpace(securityNumber))
{
throw new ArgumentException(nameof(securityNumber));
}
if (String.IsNullOrWhiteSpace(cardHolderName))
{
throw new ArgumentException(nameof(cardHolderName));
}
if (expiration < DateTime.UtcNow)
{
throw new ArgumentException(nameof(expiration));
}
_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;
}
}
}

+ 16
- 12
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs View File

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

+ 3
- 4
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs View File

@ -1,8 +1,7 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
{
using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
namespace 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
public interface IOrderRepository public interface IOrderRepository


+ 53
- 57
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -1,79 +1,75 @@
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;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
using System;
using System.Collections.Generic;
using System.Linq;
//(CDLTLL)
//TO DO: Need to add additional Domain Logic to this Aggregate-Root for
//scenarios related to Order state changes, stock availability validation, etc.
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
{
public class Order public class Order
: Entity, IAggregateRoot
: Entity
{ {
public int BuyerId { get; private set; }
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 int StatusId { get; private set; }
public OrderStatus Status { get; private set; }
public ICollection<OrderItem> OrderItems { get; private set; }
public OrderStatus OrderStatus { get; private set; }
int _orderStatusId;
public int? ShippingAddressId { get; private set; }
HashSet<OrderItem> _orderItems;
public IEnumerable<OrderItem> OrderItems => _orderItems.ToList().AsEnumerable();
public Address ShippingAddress { get; private set; }
public int PaymentId { get; private set; }
public Payment Payment { get; private set; }
public PaymentMethod PaymentMethod { get; private set; }
int _paymentMethodId;
protected Order() { } protected Order() { }
public Order(int buyerId, int paymentId)
public Order(int buyerId, int paymentMethodId, Address address)
{ {
BuyerId = buyerId;
PaymentId = paymentId;
StatusId = OrderStatus.InProcess.Id;
OrderDate = DateTime.UtcNow;
OrderItems = new List<OrderItem>();
_buyerId = buyerId;
_paymentMethodId = paymentMethodId;
_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<OrderItem>();
} }
public void SetAddress(Address address)
public void AddOrderItem(int productId, string productName, decimal unitPrice, decimal discount, string pictureUrl, int units = 1)
{ {
if (address == null)
{
throw new ArgumentNullException(nameof(address));
}
var existingOrderForProduct = _orderItems.Where(o => o.ProductId == productId)
.SingleOrDefault();
ShippingAddress = address;
}
if (existingOrderForProduct != null)
{
//if previous line exist modify it with higher discount and 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);
if (discount > existingOrderForProduct.GetCurrentDiscount())
{
existingOrderForProduct.SetNewDiscount(discount);
existingOrderForProduct.AddUnits(units);
}
}
else
{
//add validated new order 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)
var orderItem = new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units);
//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);
}
} }
} }
} }

+ 63
- 16
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderItem.cs View File

@ -1,28 +1,75 @@
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 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, string PictureUrl, 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;
_pictureUrl = PictureUrl;
}
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;
}
} }
} }

+ 1
- 1
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs View File

@ -1,6 +1,6 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate
{ {
using SeedWork;
using Seedwork;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;


+ 1
- 1
src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
{ {
using System; using System;


+ 1
- 1
src/Services/Ordering/Ordering.Domain/SeedWork/IAggregateRoot.cs View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
{ {
public interface IAggregateRoot { } public interface IAggregateRoot { }


+ 1
- 1
src/Services/Ordering/Ordering.Domain/SeedWork/IRepository.cs View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
{ {
public interface IRepository public interface IRepository
{ {


+ 1
- 1
src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs View File

@ -2,7 +2,7 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork
{ {
public interface IUnitOfWork : IDisposable public interface IUnitOfWork : IDisposable
{ {


+ 2
- 2
src/Services/Ordering/Ordering.Domain/project.json 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"
} }
} }


+ 71
- 50
src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs View File

@ -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 public class OrderingContext
: DbContext,IUnitOfWork
: DbContext,IUnitOfWork
{ {
const string DEFAULT_SCHEMA = "ordering"; const string DEFAULT_SCHEMA = "ordering";
@ -20,7 +18,7 @@
public DbSet<OrderItem> OrderItems { get; set; } public DbSet<OrderItem> OrderItems { get; set; }
public DbSet<Payment> Payments { get; set; }
public DbSet<PaymentMethod> Payments { get; set; }
public DbSet<Buyer> Buyers { get; set; } public DbSet<Buyer> Buyers { get; set; }
@ -28,70 +26,77 @@
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)
{ {
modelBuilder.Entity<Buyer>(ConfigureBuyer); modelBuilder.Entity<Buyer>(ConfigureBuyer);
modelBuilder.Entity<Payment>(ConfigurePayment);
modelBuilder.Entity<PaymentMethod>(ConfigurePayment);
modelBuilder.Entity<Order>(ConfigureOrder); modelBuilder.Entity<Order>(ConfigureOrder);
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)
.ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); .ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA);
buyerConfiguration.Property(b => b.FullName)
buyerConfiguration.Property(b=>b.FullName)
.HasMaxLength(200) .HasMaxLength(200)
.IsRequired(); .IsRequired();
buyerConfiguration.HasMany(b => b.Payments)
.WithOne()
.HasForeignKey(p => p.BuyerId)
.OnDelete(DeleteBehavior.Cascade);
buyerConfiguration.HasIndex("FullName")
.IsUnique(true);
buyerConfiguration.HasMany(b => b.PaymentMethods)
.WithOne()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade);
var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.PaymentMethods));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
} }
void ConfigurePayment(EntityTypeBuilder<Payment> paymentConfiguration)
void ConfigurePayment(EntityTypeBuilder<PaymentMethod> paymentConfiguration)
{ {
paymentConfiguration.ToTable("payments", DEFAULT_SCHEMA);
paymentConfiguration.ToTable("paymentmethods", DEFAULT_SCHEMA);
paymentConfiguration.HasKey(b => b.Id); paymentConfiguration.HasKey(b => b.Id);
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 +108,32 @@
orderConfiguration.Property(o => o.Id) orderConfiguration.Property(o => o.Id)
.ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA);
orderConfiguration.Property(o => o.OrderDate)
.IsRequired();
orderConfiguration.Property<DateTime>("OrderDate").IsRequired();
orderConfiguration.Property<string>("Street").IsRequired();
orderConfiguration.Property<string>("State").IsRequired();
orderConfiguration.Property<string>("City").IsRequired();
orderConfiguration.Property<string>("ZipCode").IsRequired();
orderConfiguration.Property<string>("Country").IsRequired();
orderConfiguration.Property<int>("BuyerId").IsRequired();
orderConfiguration.Property<int>("OrderStatusId").IsRequired();
orderConfiguration.Property<int>("PaymentMethodId").IsRequired();
var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems));
navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
orderConfiguration.HasOne(o => o.Payment)
orderConfiguration.HasOne(o => o.PaymentMethod)
.WithMany() .WithMany()
.HasForeignKey(o => o.PaymentId)
.HasForeignKey("PaymentMethodId")
.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,21 +142,29 @@
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();
orderItemConfiguration.Property<decimal>("Discount")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.ProductId)
orderItemConfiguration.Property<int>("ProductId")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.ProductName)
orderItemConfiguration.Property<string>("ProductName")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.UnitPrice)
orderItemConfiguration.Property<decimal>("UnitPrice")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property(o => o.Units)
.ForSqlServerHasDefaultValue(1)
orderItemConfiguration.Property<int>("Units")
.IsRequired(); .IsRequired();
orderItemConfiguration.Property<string>("PictureUrl")
.IsRequired(false);
} }
void ConfigureOrderStatus(EntityTypeBuilder<OrderStatus> orderStatusConfiguration) void ConfigureOrderStatus(EntityTypeBuilder<OrderStatus> orderStatusConfiguration)
@ -151,6 +175,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 +191,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);
}
} }
} }

+ 22
- 15
src/Services/Ordering/Ordering.Infrastructure/Repositories/BuyerRepository.cs View File

@ -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 public class BuyerRepository
: IBuyerRepository : IBuyerRepository
{ {
@ -33,16 +32,24 @@
public Buyer Add(Buyer buyer) 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<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)
.Where(b => b.FullName == BuyerIdentityGuid)
.Include(b => b.PaymentMethods)
.Where(b => b.FullName == identity)
.SingleOrDefaultAsync(); .SingleOrDefaultAsync();
return buyer; return buyer;


+ 6
- 6
src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs View File

@ -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 public class OrderRepository
: IOrderRepository : IOrderRepository
{ {
private readonly OrderingContext _context; private readonly OrderingContext _context;
public IUnitOfWork UnitOfWork public IUnitOfWork UnitOfWork
{ {
get get


+ 4
- 4
src/Services/Ordering/Ordering.Infrastructure/project.json View File

@ -2,14 +2,14 @@
"version": "1.0.0-*", "version": "1.0.0-*",
"dependencies": { "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-*" "Ordering.Domain": "1.0.0-*"
}, },
"frameworks": { "frameworks": {
"netstandard1.6": {
"netstandard1.6.1": {
"imports": "dnxcore50" "imports": "dnxcore50"
} }
} }


+ 1
- 0
src/Web/WebMVC/Models/Order.cs View File

@ -1,4 +1,5 @@
using Microsoft.eShopOnContainers.WebMVC.Models.Annotations; using Microsoft.eShopOnContainers.WebMVC.Models.Annotations;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;


+ 11
- 1
src/Web/WebMVC/Services/OrderingService.cs View File

@ -62,7 +62,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
order.Street = user.Street; order.Street = user.Street;
order.State = user.State; order.State = user.State;
order.Country = user.Country; order.Country = user.Country;
order.ZipCode = user.ZipCode;
order.CardNumber = user.CardNumber; order.CardNumber = user.CardNumber;
order.CardHolderName = user.CardHolderName; order.CardHolderName = user.CardHolderName;
order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]),int.Parse(user.Expiration.Split('/')[0]), 1); order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]),int.Parse(user.Expiration.Split('/')[0]), 1);
@ -82,6 +83,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var ordersUrl = $"{_remoteServiceBaseUrl}/new"; var ordersUrl = $"{_remoteServiceBaseUrl}/new";
order.CardTypeId = 1; order.CardTypeId = 1;
order.CardExpirationApiFormat(); order.CardExpirationApiFormat();
SetFakeIdToProducts(order);
StringContent content = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json"); StringContent content = new StringContent(JsonConvert.SerializeObject(order), System.Text.Encoding.UTF8, "application/json");
var response = await _apiClient.PostAsync(ordersUrl, content); var response = await _apiClient.PostAsync(ordersUrl, content);
@ -96,11 +99,18 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
destination.Street = original.Street; destination.Street = original.Street;
destination.State = original.State; destination.State = original.State;
destination.Country = original.Country; destination.Country = original.Country;
destination.ZipCode = original.ZipCode;
destination.CardNumber = original.CardNumber; destination.CardNumber = original.CardNumber;
destination.CardHolderName = original.CardHolderName; destination.CardHolderName = original.CardHolderName;
destination.CardExpiration = original.CardExpiration; destination.CardExpiration = original.CardExpiration;
destination.CardSecurityNumber = original.CardSecurityNumber; destination.CardSecurityNumber = original.CardSecurityNumber;
} }
private void SetFakeIdToProducts(Order order)
{
var id = 1;
order.OrderItems.ForEach(x => { x.ProductId = id; id++; });
}
} }
} }

+ 1
- 0
src/Web/WebMVC/Views/Order/Create.cshtml View File

@ -88,6 +88,7 @@
</div> </div>
</div> </div>
</section> </section>
<input asp-for="ZipCode" type="hidden" />
</form> </form>
</div> </div>


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts View File

@ -62,7 +62,7 @@ export class OrdersService {
order.city = identityInfo.address_city; order.city = identityInfo.address_city;
order.country = identityInfo.address_country; order.country = identityInfo.address_country;
order.state = identityInfo.address_state; order.state = identityInfo.address_state;
order.zipcode = identityInfo.addrees_zipcode;
order.zipcode = identityInfo.address_zip_code;
order.cardexpiration = identityInfo.card_expiration; order.cardexpiration = identityInfo.card_expiration;
order.cardnumber = identityInfo.card_number; order.cardnumber = identityInfo.card_number;
order.cardsecuritynumber = identityInfo.card_security_number; order.cardsecuritynumber = identityInfo.card_security_number;


+ 25
- 13
test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs 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",
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); 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",
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); return JsonConvert.SerializeObject(order);


+ 14
- 7
test/Services/FunctionalTests/project.json 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": {
"win10-x64": {}
},
//"runtimes": {
// "win10-x64": {}
//},
"frameworks": { "frameworks": {
"netcoreapp1.0": {
"dependencies": {
}
"netcoreapp1.1": {
"imports": [
"netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
]
} }
}, },
"publishOptions": { "publishOptions": {


+ 14
- 19
test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs View File

@ -1,16 +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.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Moq;
using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
public class NewOrderRequestHandlerTest public class NewOrderRequestHandlerTest
{ {
private readonly Mock<IBuyerRepository> _buyerRepositoryMock; private readonly Mock<IBuyerRepository> _buyerRepositoryMock;
@ -27,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)))
@ -50,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)))
@ -75,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",


+ 14
- 10
test/Services/UnitTest/project.json 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": {
"dependencies": {
}
"netcoreapp1.1": {
"imports": [
"netstandard1.6.1",
"dnxcore50",
"portable-net451+win8"
]
} }
} }
} }

Loading…
Cancel
Save