diff --git a/.gitignore b/.gitignore
index 7d3f5e8..0206901 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,3 +47,4 @@ build/
*.pidb
*.log
*.scc
+*.vs
diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config
deleted file mode 100644
index 2cb5d16..0000000
--- a/.vs/config/applicationhost.config
+++ /dev/null
@@ -1,1038 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/eCommerce.Tests/DomainModelLayer/CartTest.cs b/eCommerce.Tests/DomainModelLayer/CartTest.cs
index fd6abdc..326ea12 100644
--- a/eCommerce.Tests/DomainModelLayer/CartTest.cs
+++ b/eCommerce.Tests/DomainModelLayer/CartTest.cs
@@ -1,10 +1,16 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using FluentAssertions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
using eCommerce.DomainModelLayer.Carts;
+using eCommerce.DomainModelLayer.Countries;
+using eCommerce.DomainModelLayer.Customers;
using eCommerce.DomainModelLayer.Products;
+using eCommerce.DomainModelLayer.Services;
+using eCommerce.Helpers.Domain;
namespace eCommerce.Tests.DomainModelLayer
{
@@ -12,77 +18,212 @@ namespace eCommerce.Tests.DomainModelLayer
public class CartTest
{
[TestMethod, TestCategory("Unit")]
- public void TotalCost_TwoProductsOneQuantitySummedUp_ReturnsCorrectSum()
+ public void SharedCart_SharingACart_ReturnsCorrectCustomerId()
{
- decimal expected = 100;
+ var cart = CreateCart();
+ var recipient = CreateCustomer("receiver");
- Mock cartProduct = new Mock();
- cartProduct.CallBase = true;
- cartProduct.SetupGet(x => x.Quantity).Returns(1);
- cartProduct.SetupGet(x => x.Cost).Returns(50);
+ var sharedCart = cart.Share(recipient);
- Mock cart = new Mock();
- cart.CallBase = true;
- cart.SetupGet(x => x.Products)
- .Returns(new ReadOnlyCollection(new List()
- {
- cartProduct.Object,
- cartProduct.Object
- }));
+ recipient.Id.Should().Equals(sharedCart.CustomerId);
+ }
- decimal actual = cart.Object.TotalCost;
+ [TestMethod, TestCategory("Unit")]
+ public void TotalCost_TwoProductsOneQuantitySummedUp_ReturnsCorrectSum()
+ {
+ var cart = CreateCart();
+ var expected = 200;
+ var actual = cart.TotalCost;
actual.ShouldBeEquivalentTo(expected);
}
[TestMethod, TestCategory("Unit")]
public void TotalCost_TwoProductsTwoQuantitiesSummedUp_ReturnsCorrectTotalCostSum()
{
- decimal expected = 200;
+ var cart = CreateCart();
- Mock cartProduct = new Mock();
- cartProduct.CallBase = true;
- cartProduct.SetupGet(x => x.Quantity).Returns(2);
- cartProduct.SetupGet(x => x.Cost).Returns(50);
+ var expected = 200;
+ var actual = cart.TotalCost;
+ actual.ShouldBeEquivalentTo(expected);
+ }
- Mock cart = new Mock();
- cart.CallBase = true;
- cart.SetupGet(x => x.Products)
- .Returns(new ReadOnlyCollection(new List()
- {
- cartProduct.Object,
- cartProduct.Object
- }));
+ [TestMethod, TestCategory("Unit")]
+ public void TotalCost_TwoSingleProductsTaxSummedUp_ReturnsCorrectTotalTaxSum()
+ {
+ var cart = CreateCart();
+
+ var expected = 20;
+ var actual = cart.TotalTax;
+ actual.ShouldBeEquivalentTo(expected);
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ public void SharedCart_SharingACart_ReturnsCorrectProducts()
+ {
+ var cart = CreateCart();
+ var recipient = CreateCustomer("receiver");
- decimal actual = cart.Object.TotalCost;
+ var sharedCart = cart.Share(recipient);
+ var subjectProductIds = cart.Products.Select(x => x.ProductId).ToList();
+ var sharedCartIds = sharedCart.Products.Select(x => x.ProductId).ToList();
+ subjectProductIds.ForEach(id => Assert.IsTrue(sharedCartIds.Contains(id)));
+ }
+
+
+ [TestMethod, TestCategory("Unit")]
+ public void SharedCart_SharingACart_ReturnsCorrectTotalTax()
+ {
+ var cart = CreateCart();
+ var recipient = Customer.Create("receiver", "v", "c@c.com", new Mock().Object);
+
+ var sharedCart = cart.Share(recipient);
+
+ var expected = 20;
+ var actual = sharedCart.TotalTax;
actual.ShouldBeEquivalentTo(expected);
}
[TestMethod, TestCategory("Unit")]
- public void TotalCost_TwoSingleProductsTaxSummedUp_ReturnsCorrectTotalTaxSum()
+ public void SharedCart_SharingACart_ReturnsCorrectTotalCost()
{
- decimal expected = 20;
+ var cart = CreateCart();
+ var recipient = CreateCustomer("recipient");
- Mock cartProduct = new Mock();
- cartProduct.CallBase = true;
- cartProduct.SetupGet(x => x.Quantity).Returns(1);
- cartProduct.SetupGet(x => x.Tax).Returns(10);
- cartProduct.SetupGet(x => x.Cost).Returns(100);
+ var sharedCart = cart.Share(recipient);
+
+ var expected = 200;
+ var actual = sharedCart.TotalCost;
+ actual.ShouldBeEquivalentTo(expected);
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ public void Add_AddingACartProduct_UpdatesCartProductsCorrectly()
+ {
+ var customer = CreateCustomer("customer");
+ var cart = Cart.Create(customer);
+ var product = Product.Create("Cheese Slices", 1, 99, ProductCode.Create("CheeseAbc"));
+ var expectedCartProduct = CartProduct.Create(customer, cart, product, 1, new Mock().Object);
+
+ cart.Add(expectedCartProduct);
+
+ var contains = cart.Products.Any(p => p.ProductId == product.Id);
+ contains.Should().BeTrue();
+ }
+
+
+ [TestMethod, TestCategory("Unit")]
+ public void Add_AddingACartProduct_RaisesProductAddedEvent()
+ {
+
+ var cart = CreateCart();
+ var cartProduct = CreateCartProduct();
+ var expectedEvent = new ProductAddedCart {CartProduct = cartProduct};
+ ProductAddedCart actualEvent = null;
+ DomainEvents.Register(addedCart => actualEvent = addedCart);
+
+ cart.Add(cartProduct);
+
+ actualEvent.Should().NotBeNull().And.Equals(expectedEvent);
+ }
+
+
+ [TestMethod, TestCategory("Unit")]
+ public void Remove_RemovingACartProduct_RemovesCartProductsCorrectly()
+ {
+ var customer = CreateCustomer("receiver");
+ var cart = Cart.Create(customer);
+ var product = Product.Create("Cheese Slices", 1, 99, ProductCode.Create("CheeseAbc"));
+ var cartProduct = CartProduct.Create(customer, cart, product, 1, new Mock().Object);
+ cart.Add(cartProduct);
+ cart.Remove(product);
+
+ var contains = cart.Products.Contains(cartProduct);
+
+ contains.Should().BeFalse();
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ public void Clear_ClearingACart_ClearsAllProducts()
+ {
+ var customer = Customer.Create("receiver", "v", "c@c.com", new Mock().Object);
+ var cart = Cart.Create(customer);
+ var product = CreateCartProduct();
+ cart.Add(product);
+
+ cart.Clear();
+
+ cart.Products.Count.Should().Be(0);
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ public void Create_CreatingANewCart_ReturnsACorrectCart()
+ {
+ var customer = Customer.Create("receiver", "v", "c@c.com", new Mock().Object);
+
+ var cart = Cart.Create(customer);
+
+ cart.Should().NotBeNull();
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void Create_CreatingANewCart_ThrowsExceptionOnNullCustomer()
+ {
+ Customer customer = null;
+ var cart = Cart.Create(customer);
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void Remove_RemovingACartProduct_ThrowsExceptionOnNullProduct()
+ {
+ var cart = CreateCart();
+ Product nullProduct = null;
+ cart.Remove(nullProduct);
+ }
+
+ [TestMethod, TestCategory("Unit")]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void Add_AddingACartProduct_ThrowsExceptionOnNullProduct()
+ {
+ var customer = Customer.Create("receiver", "v", "c@c.com", new Mock().Object);
+ var cart = Cart.Create(customer);
+ CartProduct cartProduct = null;
+ cart.Add(cartProduct);
+ }
+
+ private static Cart CreateCart()
+ {
+ var product1 = CreateCartProduct();
+ var product2 = CreateCartProduct();
Mock cart = new Mock();
cart.CallBase = true;
cart.SetupGet(x => x.Products)
.Returns(new ReadOnlyCollection(new List()
- {
- cartProduct.Object,
- cartProduct.Object
- }));
+ {
+ product1,
+ product2
+ }));
- decimal actual = cart.Object.TotalTax;
+ return cart.Object;
+ }
- actual.ShouldBeEquivalentTo(expected);
+ private static CartProduct CreateCartProduct()
+ {
+ Mock cartProduct = new Mock();
+ var productId = Guid.NewGuid();
+ cartProduct.CallBase = true;
+ cartProduct.SetupGet(x => x.Quantity).Returns(1);
+ cartProduct.SetupGet(x => x.Tax).Returns(10);
+ cartProduct.SetupGet(x => x.Cost).Returns(100);
+ cartProduct.SetupGet(x => x.ProductId).Returns(productId);
+ return cartProduct.Object;
}
+ private static Customer CreateCustomer(string name)
+ => Customer.Create(name, name.Reverse().ToString(), $"{name}@email.com", new Mock().Object);
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce.Tests/DomainModelLayer/TaxServiceTest.cs b/eCommerce.Tests/DomainModelLayer/TaxServiceTest.cs
index 5b62e5b..a719a07 100644
--- a/eCommerce.Tests/DomainModelLayer/TaxServiceTest.cs
+++ b/eCommerce.Tests/DomainModelLayer/TaxServiceTest.cs
@@ -3,18 +3,13 @@
using eCommerce.DomainModelLayer.Customers;
using Moq;
using FluentAssertions;
-using eCommerce.DomainModelLayer.Purchases;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using FluentAssertions.Equivalency;
-using eCommerce.Helpers.Domain;
-using eCommerce.DomainModelLayer.Services;
using eCommerce.DomainModelLayer;
using eCommerce.Helpers.Repository;
using eCommerce.DomainModelLayer.Tax;
using eCommerce.DomainModelLayer.Countries;
using eCommerce.DomainModelLayer.Products;
using eCommerce.DomainModelLayer.Customers.Spec;
+using eCommerce.DomainModelLayer.Services;
namespace eCommerce.Tests.DomainModelLayer
{
@@ -48,7 +43,7 @@ public void Calculate_OverallProductTax_ReturnsCorrectTax()
product.SetupGet(x => x.Code).Returns(new ProductCode());
//call method
- TaxService taxService = new TaxService(settings.Object, repositoryCountryTax.Object);
+ ITaxService taxService = new TaxService(settings.Object, repositoryCountryTax.Object);
decimal actual = taxService.Calculate(customer.Object, product.Object);
diff --git a/eCommerce.WebService/App_Start/WebApiConfig.cs b/eCommerce.WebService/App_Start/WebApiConfig.cs
index 4ef8406..1fa08c0 100644
--- a/eCommerce.WebService/App_Start/WebApiConfig.cs
+++ b/eCommerce.WebService/App_Start/WebApiConfig.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Linq;
using System.Web.Http;
namespace eCommerce.WebService
@@ -8,14 +6,27 @@ namespace eCommerce.WebService
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
+ {
+ MapRoutes(config);
+ SetJsonToDefaultFormatter(config);
+ config.EnableSystemDiagnosticsTracing();
+ }
+
+ private static void SetJsonToDefaultFormatter(HttpConfiguration config)
+ {
+ var appXmlType =
+ config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t =>
+ t.MediaType == "application/xml");
+ config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
+ }
+
+ private static void MapRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
-
- config.EnableSystemDiagnosticsTracing();
}
}
}
diff --git a/eCommerce.WebService/Controllers/CartController.cs b/eCommerce.WebService/Controllers/CartController.cs
index 43e2bbb..c070d6f 100644
--- a/eCommerce.WebService/Controllers/CartController.cs
+++ b/eCommerce.WebService/Controllers/CartController.cs
@@ -1,10 +1,6 @@
using eCommerce.WebService.Models;
using eCommerce.ApplicationLayer.Carts;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
using System.Web.Http;
namespace eCommerce.WebService.Controllers
@@ -25,73 +21,40 @@ public CartController(ICartService cartService)
}
[HttpGet]
- public Response Add(Guid customerId, [FromUri]CartProductDto cartDto)
- {
- Response response = new Response();
- try
- {
- response.Object = this.cartService.Add(customerId, cartDto);
- }
- catch (Exception ex)
- {
- //log error
- response.Errored = true;
- response.ErrorMessage = ex.Message;
- }
- return response;
- }
+ public Response Add(Guid customerId, [FromUri]CartProductDto cartDto)
+ => CreateResponse(() => this.cartService.Add(customerId, cartDto));
[HttpGet]
- public Response GetById(Guid customerId)
- {
- Response response = new Response();
- try
- {
- response.Object = this.cartService.Get(customerId);
- }
- catch (Exception ex)
- {
- //log error
- response.Errored = true;
- response.ErrorMessage = ex.Message;
- }
- return response;
- }
+ public Response GetById(Guid customerId)
+ => CreateResponse(() => this.cartService.Get(customerId));
[HttpGet]
- public Response Remove(Guid customerId, Guid productId)
- {
- Response response = new Response();
- try
- {
- response.Object = this.cartService.Remove(customerId, productId);
- }
- catch (Exception ex)
- {
- //log error
- response.Errored = true;
- response.ErrorMessage = ex.Message;
- }
- return response;
- }
+ public Response Remove(Guid customerId, Guid productId)
+ => CreateResponse(() => this.cartService.Remove(customerId, productId));
[HttpGet]
- public Response Checkout(Guid customerId)
+ public Response Checkout(Guid customerId)
+ => CreateResponse(() => this.cartService.CheckOut(customerId));
+
+ [HttpGet]
+ public Response Share(Guid cartOwnerId, Guid cartRecipientId)
+ => CreateResponse(() => this.cartService.Share(cartOwnerId, cartRecipientId));
+
+ private Response CreateResponse(Func execute)
{
- Response response = new Response();
+ var response = new Response();
try
{
- response.Object = this.cartService.CheckOut(customerId);
+ response.Object = execute();
}
catch (Exception ex)
{
- //log error
response.Errored = true;
response.ErrorMessage = ex.Message;
}
+
return response;
}
-
}
}
\ No newline at end of file
diff --git a/eCommerce.WebService/Controllers/CustomerController.cs b/eCommerce.WebService/Controllers/CustomerController.cs
index 42d972d..c134598 100644
--- a/eCommerce.WebService/Controllers/CustomerController.cs
+++ b/eCommerce.WebService/Controllers/CustomerController.cs
@@ -1,10 +1,6 @@
using eCommerce.WebService.Models;
using eCommerce.ApplicationLayer.Customers;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
using System.Web.Http;
namespace eCommerce.WebService.Controllers
@@ -16,6 +12,7 @@ namespace eCommerce.WebService.Controllers
* http://localhost:50300/api/customer/IsEmailAvailable?email=smith.john@microsoft.com
* http://localhost:50300/api/customer/RemoveById/5D5020DA-47DF-4C82-A722-C8DEAF06AE23
* http://localhost:50300/api/customer/update?id=5D5020DA-47DF-4C82-A722-C8DEAF06AE23&Email=smith.john@microsoft.com
+ * http://localhost:50300/api/customer/add?FirstName=Eddy&LastName=Carmine&Email=e@as.com&countryId=229074bd-2356-4b5a-8619-cdebba71cc21
*/
public class CustomerController : ApiController
{
diff --git a/eCommerce.WebService/Controllers/ProductController.cs b/eCommerce.WebService/Controllers/ProductController.cs
index e35b675..48a9d4d 100644
--- a/eCommerce.WebService/Controllers/ProductController.cs
+++ b/eCommerce.WebService/Controllers/ProductController.cs
@@ -1,10 +1,6 @@
using eCommerce.WebService.Models;
using eCommerce.ApplicationLayer.Products;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
using System.Web.Http;
namespace eCommerce.WebService.Controllers
diff --git a/eCommerce.WebService/Models/ResponseOfTReturn.cs b/eCommerce.WebService/Models/ResponseOfTReturn.cs
index 41ad75d..e842b19 100644
--- a/eCommerce.WebService/Models/ResponseOfTReturn.cs
+++ b/eCommerce.WebService/Models/ResponseOfTReturn.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-
-namespace eCommerce.WebService.Models
+namespace eCommerce.WebService.Models
{
public sealed class Response : Response
{
diff --git a/eCommerce/ApplicationLayer/Carts/CartService.cs b/eCommerce/ApplicationLayer/Carts/CartService.cs
index d2f2380..7ec501a 100644
--- a/eCommerce/ApplicationLayer/Carts/CartService.cs
+++ b/eCommerce/ApplicationLayer/Carts/CartService.cs
@@ -15,12 +15,12 @@ public class CartService : ICartService
IRepository productRepository;
IRepository cartRepository;
IUnitOfWork unitOfWork;
- TaxService taxDomainService;
- CheckoutService checkoutDomainService;
+ ITaxService taxDomainService;
+ CheckoutService checkoutDomainService;
- public CartService(IRepository customerRepository,
- IRepository productRepository, IRepository cartRepository,
- IUnitOfWork unitOfWork, TaxService taxDomainService, CheckoutService checkoutDomainService)
+ public CartService(IRepository customerRepository,
+ IRepository productRepository, IRepository cartRepository,
+ IUnitOfWork unitOfWork, ITaxService taxDomainService, CheckoutService checkoutDomainService)
{
this.customerRepository = customerRepository;
this.productRepository = productRepository;
@@ -35,21 +35,20 @@ public CartDto Add(Guid customerId, CartProductDto productDto)
CartDto cartDto = null;
Customer customer = this.customerRepository.FindById(customerId);
- if (customer == null)
- throw new Exception(String.Format("Customer was not found with this Id: {0}", customerId));
+ ValidateCustomer(customerId, customer);
Cart cart = this.cartRepository.FindOne(new CustomerCartSpec(customerId));
- if(cart == null)
+ if (cart == null)
{
cart = Cart.Create(customer);
this.cartRepository.Add(cart);
}
Product product = this.productRepository.FindById(productDto.ProductId);
- this.validateProduct(product.Id, product);
+ this.ValidateProduct(product.Id, product);
//Double Dispatch Pattern
- cart.Add(CartProduct.Create(customer, cart, product,
+ cart.Add(CartProduct.Create(customer, cart, product,
productDto.Quantity, taxDomainService));
cartDto = Mapper.Map(cart);
@@ -62,10 +61,10 @@ public CartDto Remove(Guid customerId, Guid productId)
CartDto cartDto = null;
Cart cart = this.cartRepository.FindOne(new CustomerCartSpec(customerId));
- this.validateCart(customerId, cart);
+ this.ValidateCart(customerId, cart);
Product product = this.productRepository.FindById(productId);
- this.validateProduct(productId, product);
+ this.ValidateProduct(productId, product);
cart.Remove(product);
cartDto = Mapper.Map(cart);
@@ -76,7 +75,7 @@ public CartDto Remove(Guid customerId, Guid productId)
public CartDto Get(Guid customerId)
{
Cart cart = this.cartRepository.FindOne(new CustomerCartSpec(customerId));
- this.validateCart(customerId, cart);
+ this.ValidateCart(customerId, cart);
return Mapper.Map(cart);
}
@@ -86,11 +85,11 @@ public CheckOutResultDto CheckOut(Guid customerId)
CheckOutResultDto checkOutResultDto = new CheckOutResultDto();
Cart cart = this.cartRepository.FindOne(new CustomerCartSpec(customerId));
- this.validateCart(customerId, cart);
+ this.ValidateCart(customerId, cart);
Customer customer = this.customerRepository.FindById(cart.CustomerId);
- Nullable checkOutIssue =
+ Nullable checkOutIssue =
this.checkoutDomainService.CanCheckOut(customer, cart);
if (!checkOutIssue.HasValue)
@@ -107,16 +106,36 @@ public CheckOutResultDto CheckOut(Guid customerId)
return checkOutResultDto;
}
- private void validateCart(Guid customerId, Cart cart)
+ public CartDto Share(Guid cartOwnerId, Guid cartRecipientId)
+ {
+ var cart = this.cartRepository.FindOne(new CustomerCartSpec(cartOwnerId));
+ this.ValidateCart(cartOwnerId, cart);
+
+ var recipient = this.customerRepository.FindById(cartRecipientId);
+ ValidateCustomer(cartRecipientId, recipient);
+
+ var sharedCart = cart.Share(recipient);
+ this.cartRepository.Add(sharedCart);
+
+ return Mapper.Map(sharedCart);
+ }
+
+ private void ValidateCart(Guid customerId, Cart cart)
{
if (cart == null)
throw new Exception(String.Format("Customer was not found with this Id: {0}", customerId));
}
- private void validateProduct(Guid productId, Product product)
+ private void ValidateProduct(Guid productId, Product product)
{
if (product == null)
throw new Exception(String.Format("Product was not found with this Id: {0}", productId));
}
+
+ private void ValidateCustomer(Guid customerId, Customer customer)
+ {
+ if (customer == null)
+ throw new ArgumentNullException($"Customer was not found with this Id: {customerId}");
+ }
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/ApplicationLayer/Carts/ICartService.cs b/eCommerce/ApplicationLayer/Carts/ICartService.cs
index b26b771..9ebebd5 100644
--- a/eCommerce/ApplicationLayer/Carts/ICartService.cs
+++ b/eCommerce/ApplicationLayer/Carts/ICartService.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using eCommerce.DomainModelLayer.Carts;
namespace eCommerce.ApplicationLayer.Carts
{
@@ -12,5 +8,6 @@ public interface ICartService
CartDto Remove(Guid customerId, Guid productId);
CartDto Get(Guid customerId);
CheckOutResultDto CheckOut(Guid customerId);
+ CartDto Share(Guid cartOwnerId, Guid cartRecipientId);
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/ApplicationLayer/Customers/ICustomerService.cs b/eCommerce/ApplicationLayer/Customers/ICustomerService.cs
index 30364f2..9308aea 100644
--- a/eCommerce/ApplicationLayer/Customers/ICustomerService.cs
+++ b/eCommerce/ApplicationLayer/Customers/ICustomerService.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace eCommerce.ApplicationLayer.Customers
{
@@ -14,7 +12,6 @@ public interface ICustomerService
CustomerDto Get(Guid customerId);
CreditCardDto Add(Guid customerId, CreditCardDto creditCard);
List GetAllCustomerPurchaseHistoryV1();
-
List GetAllCustomerPurchaseHistoryV2();
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/DomainModelLayer/Carts/Cart.cs b/eCommerce/DomainModelLayer/Carts/Cart.cs
index 505c2cf..6ee773c 100644
--- a/eCommerce/DomainModelLayer/Carts/Cart.cs
+++ b/eCommerce/DomainModelLayer/Carts/Cart.cs
@@ -12,41 +12,26 @@ public class Cart : IAggregateRoot
{
public virtual Guid Id { get; protected set; }
- private List cartProducts = new List();
+ private readonly List _cartProducts = new List();
- public virtual ReadOnlyCollection Products
- {
- get { return cartProducts.AsReadOnly(); }
- }
+ public virtual ReadOnlyCollection Products => _cartProducts.AsReadOnly();
public virtual Guid CustomerId { get; protected set; }
- public virtual decimal TotalCost
- {
- get
- {
- return this.Products.Sum(cartProduct => cartProduct.Quantity * cartProduct.Cost);
- }
- }
+ public virtual decimal TotalCost => Products.Sum(cartProduct => cartProduct.Quantity * cartProduct.Cost);
- public virtual decimal TotalTax
- {
- get
- {
- return this.Products.Sum(cartProducts => cartProducts.Tax);
- }
- }
+ public virtual decimal TotalTax => Products.Sum(cartProducts => cartProducts.Tax);
public static Cart Create(Customer customer)
{
if (customer == null)
- throw new ArgumentNullException("customer");
+ throw new ArgumentNullException(nameof(customer));
Cart cart = new Cart();
cart.Id = Guid.NewGuid();
cart.CustomerId = customer.Id;
- DomainEvents.Raise(new CartCreated() { Cart = cart });
+ DomainEvents.Raise(new CartCreated { Cart = cart });
return cart;
}
@@ -56,9 +41,9 @@ public virtual void Add(CartProduct cartProduct)
if (cartProduct == null)
throw new ArgumentNullException();
- DomainEvents.Raise(new ProductAddedCart() { CartProduct = cartProduct });
+ DomainEvents.Raise(new ProductAddedCart { CartProduct = cartProduct });
- this.cartProducts.Add(cartProduct);
+ _cartProducts.Add(cartProduct);
}
public virtual void Remove(Product product)
@@ -67,16 +52,20 @@ public virtual void Remove(Product product)
throw new ArgumentNullException("product");
CartProduct cartProduct =
- this.cartProducts.Find(new ProductInCartSpec(product).IsSatisfiedBy);
+ _cartProducts.Find(new ProductInCartSpec(product).IsSatisfiedBy);
- DomainEvents.Raise(new ProductRemovedCart() { CartProduct = cartProduct });
+ DomainEvents.Raise(new ProductRemovedCart() { CartProduct = cartProduct });
- this.cartProducts.Remove(cartProduct);
+ _cartProducts.Remove(cartProduct);
}
- public virtual void Clear()
+ public virtual void Clear() => _cartProducts.Clear();
+
+ public Cart Share(Customer receiver)
{
- this.cartProducts.Clear();
+ var cart = Create(receiver);
+ Products.ToList().ForEach(product => cart.Add(product));
+ return cart;
}
}
}
diff --git a/eCommerce/DomainModelLayer/Carts/CartCreated.cs b/eCommerce/DomainModelLayer/Carts/CartCreated.cs
index e1b9a60..36adda6 100644
--- a/eCommerce/DomainModelLayer/Carts/CartCreated.cs
+++ b/eCommerce/DomainModelLayer/Carts/CartCreated.cs
@@ -1,8 +1,4 @@
using eCommerce.Helpers.Domain;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace eCommerce.DomainModelLayer.Carts
{
diff --git a/eCommerce/DomainModelLayer/Carts/CartProduct.cs b/eCommerce/DomainModelLayer/Carts/CartProduct.cs
index c06192f..cd8b072 100644
--- a/eCommerce/DomainModelLayer/Carts/CartProduct.cs
+++ b/eCommerce/DomainModelLayer/Carts/CartProduct.cs
@@ -1,31 +1,33 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using eCommerce.DomainModelLayer.Products;
-using eCommerce.DomainModelLayer.Services;
-using eCommerce.Helpers.Domain;
using eCommerce.DomainModelLayer.Customers;
+using eCommerce.DomainModelLayer.Services;
namespace eCommerce.DomainModelLayer.Carts
{
public class CartProduct
{
- public virtual Guid CartId { get; protected set; }
- public virtual Guid CustomerId { get; protected set; }
- public virtual int Quantity { get; protected set; }
- public virtual Guid ProductId { get; protected set; }
- public virtual DateTime Created { get; protected set; }
- public virtual decimal Cost { get; protected set; }
- public virtual decimal Tax { get; set; }
-
- public static CartProduct Create(Customer customer, Cart cart, Product product, int quantity, TaxService taxService)
+ public virtual Guid CartId { get; private set; }
+ public virtual Guid CustomerId { get; private set; }
+ public virtual int Quantity { get; private set; }
+ public virtual Guid ProductId { get; private set; }
+ public virtual DateTime Created { get; private set; }
+ public virtual decimal Cost { get; private set; }
+ public virtual decimal Tax { get; private set; }
+
+ public static CartProduct Create(Customer customer, Cart cart, Product product, int quantity, ITaxService taxService)
{
+ if (cart == null)
+ throw new ArgumentNullException(nameof(customer));
+
if(cart == null)
- throw new ArgumentNullException("cart");
+ throw new ArgumentNullException(nameof(cart));
if (product == null)
- throw new ArgumentNullException("product");
+ throw new ArgumentNullException(nameof(product));
+
+ if (taxService == null)
+ throw new ArgumentNullException(nameof(taxService));
CartProduct cartProduct = new CartProduct()
{
diff --git a/eCommerce/DomainModelLayer/Carts/CheckOutIssue.cs b/eCommerce/DomainModelLayer/Carts/CheckOutIssue.cs
index f11e9e5..09b1dc0 100644
--- a/eCommerce/DomainModelLayer/Carts/CheckOutIssue.cs
+++ b/eCommerce/DomainModelLayer/Carts/CheckOutIssue.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace eCommerce.DomainModelLayer.Carts
+namespace eCommerce.DomainModelLayer.Carts
{
public enum CheckOutIssue
{
diff --git a/eCommerce/DomainModelLayer/Carts/CustomerCartSpec.cs b/eCommerce/DomainModelLayer/Carts/CustomerCartSpec.cs
index f1f5313..1519434 100644
--- a/eCommerce/DomainModelLayer/Carts/CustomerCartSpec.cs
+++ b/eCommerce/DomainModelLayer/Carts/CustomerCartSpec.cs
@@ -1,9 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using eCommerce.Helpers.Repository;
-using eCommerce.DomainModelLayer.Products;
using System.Linq.Expressions;
using eCommerce.Helpers.Specification;
@@ -11,19 +6,14 @@ namespace eCommerce.DomainModelLayer.Carts
{
public class CustomerCartSpec : SpecificationBase
{
- readonly Guid customerId;
+ private readonly Guid _customerId;
public CustomerCartSpec(Guid customerId)
{
- this.customerId = customerId;
+ _customerId = customerId;
}
- public override Expression> SpecExpression
- {
- get
- {
- return cart => cart.CustomerId == this.customerId;
- }
- }
+ public override Expression> SpecExpression =>
+ cart => cart.CustomerId == _customerId;
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/DomainModelLayer/Carts/ProductAddedCart.cs b/eCommerce/DomainModelLayer/Carts/ProductAddedCart.cs
index c38e829..e2bf9af 100644
--- a/eCommerce/DomainModelLayer/Carts/ProductAddedCart.cs
+++ b/eCommerce/DomainModelLayer/Carts/ProductAddedCart.cs
@@ -1,8 +1,4 @@
using eCommerce.Helpers.Domain;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace eCommerce.DomainModelLayer.Carts
{
@@ -18,4 +14,4 @@ public override void Flatten()
this.Args.Add("Quantity", this.CartProduct.Quantity);
}
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/DomainModelLayer/Carts/ProductInCartSpec.cs b/eCommerce/DomainModelLayer/Carts/ProductInCartSpec.cs
index 76941a9..007c5db 100644
--- a/eCommerce/DomainModelLayer/Carts/ProductInCartSpec.cs
+++ b/eCommerce/DomainModelLayer/Carts/ProductInCartSpec.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using eCommerce.Helpers.Repository;
using eCommerce.DomainModelLayer.Products;
using System.Linq.Expressions;
using eCommerce.Helpers.Specification;
@@ -11,19 +7,14 @@ namespace eCommerce.DomainModelLayer.Carts
{
public class ProductInCartSpec : SpecificationBase
{
- readonly Product product;
+ private readonly Product _product;
public ProductInCartSpec(Product product)
{
- this.product = product;
+ _product = product;
}
- public override Expression> SpecExpression
- {
- get
- {
- return cartProduct => cartProduct.ProductId == this.product.Id;
- }
- }
+ public override Expression> SpecExpression =>
+ cartProduct => cartProduct.ProductId == this._product.Id;
}
-}
+}
\ No newline at end of file
diff --git a/eCommerce/DomainModelLayer/Carts/ProductRemovedCart.cs b/eCommerce/DomainModelLayer/Carts/ProductRemovedCart.cs
index ec1175c..587602e 100644
--- a/eCommerce/DomainModelLayer/Carts/ProductRemovedCart.cs
+++ b/eCommerce/DomainModelLayer/Carts/ProductRemovedCart.cs
@@ -1,8 +1,4 @@
using eCommerce.Helpers.Domain;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace eCommerce.DomainModelLayer.Carts
{
diff --git a/eCommerce/DomainModelLayer/Services/ITaxService.cs b/eCommerce/DomainModelLayer/Services/ITaxService.cs
new file mode 100644
index 0000000..d8dbe6a
--- /dev/null
+++ b/eCommerce/DomainModelLayer/Services/ITaxService.cs
@@ -0,0 +1,10 @@
+using eCommerce.DomainModelLayer.Customers;
+using eCommerce.DomainModelLayer.Products;
+
+namespace eCommerce.DomainModelLayer.Services
+{
+ public interface ITaxService
+ {
+ decimal Calculate(Customer customer, Product product);
+ }
+}
diff --git a/eCommerce/DomainModelLayer/Services/TaxService.cs b/eCommerce/DomainModelLayer/Services/TaxService.cs
index 5ba805a..c96d398 100644
--- a/eCommerce/DomainModelLayer/Services/TaxService.cs
+++ b/eCommerce/DomainModelLayer/Services/TaxService.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using eCommerce.DomainModelLayer.Customers;
using eCommerce.DomainModelLayer.Products;
using eCommerce.Helpers.Repository;
@@ -11,15 +8,15 @@
namespace eCommerce.DomainModelLayer.Services
{
- public class TaxService : IDomainService
+ public class TaxService : IDomainService, ITaxService
{
- readonly IRepository countryTax;
- readonly Settings settings;
+ readonly IRepository _countryTax;
+ readonly Settings _settings;
public TaxService(Settings settings, IRepository countryTax)
{
- this.countryTax = countryTax;
- this.settings = settings;
+ _countryTax = countryTax;
+ _settings = settings;
}
public decimal Calculate(Customer customer, Product product)
@@ -30,8 +27,8 @@ public decimal Calculate(Customer customer, Product product)
if (product == null)
throw new ArgumentNullException("product");
- CountryTax customerCountryTax = this.countryTax.FindOne(new CountryTypeOfTaxSpec(customer.CountryId, TaxType.Customer));
- CountryTax businessCountryTax = this.countryTax.FindOne(new CountryTypeOfTaxSpec(settings.BusinessCountry.Id, TaxType.Business));
+ CountryTax customerCountryTax = this._countryTax.FindOne(new CountryTypeOfTaxSpec(customer.CountryId, TaxType.Customer));
+ CountryTax businessCountryTax = this._countryTax.FindOne(new CountryTypeOfTaxSpec(_settings.BusinessCountry.Id, TaxType.Business));
return (product.Cost * customerCountryTax.Percentage)
+ (product.Cost * businessCountryTax.Percentage);
diff --git a/eCommerce/DomainModelLayer/Settings.cs b/eCommerce/DomainModelLayer/Settings.cs
index c5ecdf6..e85e53b 100644
--- a/eCommerce/DomainModelLayer/Settings.cs
+++ b/eCommerce/DomainModelLayer/Settings.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using eCommerce.DomainModelLayer.Countries;
+using eCommerce.DomainModelLayer.Countries;
namespace eCommerce.DomainModelLayer
{
diff --git a/eCommerce/eCommerce.csproj b/eCommerce/eCommerce.csproj
index dc7bc9d..fde4b7e 100644
--- a/eCommerce/eCommerce.csproj
+++ b/eCommerce/eCommerce.csproj
@@ -95,6 +95,7 @@
+