From 88225a771993a45dbda770dfa8c68286994ec7b9 Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Fri, 3 May 2024 11:54:07 +0200 Subject: [PATCH] Added slimmed mutable aggregate solution --- .../Mutable/ShoppingCart.cs | 5 - .../Immutable/BusinessLogicTests.cs | 2 +- .../PricingCalculator.cs | 2 +- .../{Products => Pricing}/ProductItems.cs | 2 +- .../Immutable/ShoppingCart.cs | 2 +- .../Immutable/ShoppingCartService.cs | 2 +- .../Mutable/BusinessLogicTests.cs | 95 +++++++++---------- .../{ => Pricing}/PricingCalculator.cs | 2 +- .../Mutable/ShoppingCart.cs | 59 +++++------- 9 files changed, 76 insertions(+), 95 deletions(-) rename Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/{Products => Pricing}/PricingCalculator.cs (97%) rename Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/{Products => Pricing}/ProductItems.cs (98%) rename Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/{ => Pricing}/PricingCalculator.cs (97%) diff --git a/Workshops/IntroductionToEventSourcing/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs b/Workshops/IntroductionToEventSourcing/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs index 7a2c97efe..38eeb895c 100644 --- a/Workshops/IntroductionToEventSourcing/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs +++ b/Workshops/IntroductionToEventSourcing/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs @@ -98,7 +98,6 @@ private ShoppingCart(Guid id, Guid clientId, DateTimeOffset now) var @event = new ShoppingCartOpened(id, clientId, now); Enqueue(@event); - Apply(@event); } //just for default creation of empty object @@ -126,7 +125,6 @@ DateTimeOffset now var @event = new ProductItemAddedToShoppingCart(Id, pricedProductItem, now); Enqueue(@event); - Apply(@event); } private void Apply(ProductItemAddedToShoppingCart productItemAdded) @@ -160,7 +158,6 @@ public void RemoveProduct(PricedProductItem productItemToBeRemoved, DateTimeOffs var @event = new ProductItemRemovedFromShoppingCart(Id, productItemToBeRemoved, now); Enqueue(@event); - Apply(@event); } private bool HasEnough(PricedProductItem productItem) @@ -202,7 +199,6 @@ public void Confirm(DateTimeOffset now) var @event = new ShoppingCartConfirmed(Id, now); Enqueue(@event); - Apply(@event); } private void Apply(ShoppingCartConfirmed confirmed) @@ -220,7 +216,6 @@ public void Cancel(DateTimeOffset now) var @event = new ShoppingCartCanceled(Id, now); Enqueue(@event); - Apply(@event); } private void Apply(ShoppingCartCanceled canceled) diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/BusinessLogicTests.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/BusinessLogicTests.cs index e3855b109..26cc032f4 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/BusinessLogicTests.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/BusinessLogicTests.cs @@ -1,4 +1,4 @@ -using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Products; +using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Pricing; using Ogooreck.BusinessLogic; using Xunit; diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/PricingCalculator.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/PricingCalculator.cs similarity index 97% rename from Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/PricingCalculator.cs rename to Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/PricingCalculator.cs index 065851d8e..d58bf0201 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/PricingCalculator.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/PricingCalculator.cs @@ -1,4 +1,4 @@ -namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Products; +namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Pricing; public interface IProductPriceCalculator { diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/ProductItems.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/ProductItems.cs similarity index 98% rename from Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/ProductItems.cs rename to Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/ProductItems.cs index 582f4ff62..30bac2768 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Products/ProductItems.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/Pricing/ProductItems.cs @@ -1,7 +1,7 @@ using System.Collections.Immutable; using IntroductionToEventSourcing.BusinessLogic.Slimmed.Tools; -namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Products; +namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Pricing; using ProductId = Guid; using ProductIdWithPrice = string; diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCart.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCart.cs index bd37a6c98..91f96db15 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCart.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCart.cs @@ -1,4 +1,4 @@ -using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Products; +using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Pricing; namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable; diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCartService.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCartService.cs index f2bc1b3d5..1d996be2c 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCartService.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Immutable/ShoppingCartService.cs @@ -1,4 +1,4 @@ -using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Products; +using IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable.Pricing; namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Immutable; diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/BusinessLogicTests.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/BusinessLogicTests.cs index 1a68b8b16..cde0a21c9 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/BusinessLogicTests.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/BusinessLogicTests.cs @@ -1,3 +1,4 @@ +using IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable.Pricing; using Ogooreck.BusinessLogic; using Xunit; @@ -12,9 +13,9 @@ public class BusinessLogicTests public void OpensShoppingCart() => Spec.Given([]) .When(() => - ShoppingCart.Open(shoppingCartId, clientId, now) + ShoppingCart.Open(clientId, now) ) - .Then(new ShoppingCartOpened(shoppingCartId, clientId, now)); + .Then(new Opened(clientId, now)); // Add [Fact] @@ -32,7 +33,7 @@ public class BusinessLogicTests [Fact] public void AddsProductItemToEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now) + new Opened(clientId, now) ]) .When(state => state.AddProduct( @@ -42,9 +43,7 @@ public class BusinessLogicTests ) ) .Then( - new ProductItemAddedToShoppingCart( - shoppingCartId, - new PricedProductItem + new ProductItemAdded(new PricedProductItem { ProductId = ProductItem().ProductId, Quantity = ProductItem().Quantity, UnitPrice = Price }, @@ -56,8 +55,8 @@ public class BusinessLogicTests [Fact] public void AddsProductItemToNonEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), ]) .When(state => state.AddProduct( @@ -67,9 +66,7 @@ public class BusinessLogicTests ) ) .Then( - new ProductItemAddedToShoppingCart( - shoppingCartId, - new PricedProductItem + new ProductItemAdded(new PricedProductItem { ProductId = OtherProductItem().ProductId, Quantity = OtherProductItem().Quantity, @@ -82,9 +79,9 @@ public class BusinessLogicTests [Fact] public void CantAddProductItemToConfirmedShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartConfirmed(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Confirmed(now) ]) .When(state => state.AddProduct( @@ -98,9 +95,9 @@ public class BusinessLogicTests [Fact] public void CantAddProductItemToCanceledShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartCanceled(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Canceled(now) ]) .When(state => state.AddProduct( @@ -123,16 +120,14 @@ public class BusinessLogicTests [Fact] public void RemovesExistingProductItemFromShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), ]) .When(state => state.RemoveProduct(PricedProductItemWithQuantity(1), now) ) .Then( - new ProductItemRemovedFromShoppingCart( - shoppingCartId, - PricedProductItemWithQuantity(1), + new ProductItemRemoved(PricedProductItemWithQuantity(1), now ) ); @@ -140,8 +135,8 @@ public class BusinessLogicTests [Fact] public void CantRemoveNonExistingProductItemFromNonEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, OtherPricedProductItem(), now), + new Opened(clientId, now), + new ProductItemAdded(OtherPricedProductItem(), now), ]) .When(state => state.RemoveProduct(PricedProductItemWithQuantity(1), now) @@ -151,9 +146,9 @@ public class BusinessLogicTests [Fact] public void CantRemoveExistingProductItemFromCanceledShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartConfirmed(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Confirmed(now) ]) .When(state => state.RemoveProduct(PricedProductItemWithQuantity(1), now) @@ -163,9 +158,9 @@ public class BusinessLogicTests [Fact] public void CantRemoveExistingProductItemFromConfirmedShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartCanceled(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Canceled(now) ]) .When(state => state.RemoveProduct(PricedProductItemWithQuantity(1), now) @@ -185,7 +180,7 @@ public class BusinessLogicTests [Trait("Category", "SkipCI")] public void CantConfirmEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), + new Opened(clientId, now), ]) .When(state => state.Confirm(now) @@ -195,22 +190,22 @@ public class BusinessLogicTests [Fact] public void ConfirmsNonEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), ]) .When(state => state.Confirm(now) ) .Then( - new ShoppingCartConfirmed(shoppingCartId, now) + new Confirmed(now) ); [Fact] public void CantConfirmAlreadyConfirmedShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartConfirmed(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Confirmed(now) ]) .When(state => state.Confirm(now) @@ -220,9 +215,9 @@ public class BusinessLogicTests [Fact] public void CantConfirmCanceledShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartCanceled(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Canceled(now) ]) .When(state => state.Confirm(now) @@ -242,7 +237,7 @@ public class BusinessLogicTests [Fact] public void CancelsEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), + new Opened(clientId, now), ]) .When(state => state.Cancel(now) @@ -252,22 +247,22 @@ public class BusinessLogicTests [Fact] public void CancelsNonEmptyShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), ]) .When(state => state.Cancel(now) ) .Then( - new ShoppingCartCanceled(shoppingCartId, now) + new Canceled(now) ); [Fact] public void CantCancelAlreadyCanceledShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartCanceled(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Canceled(now) ]) .When(state => state.Cancel(now) @@ -277,9 +272,9 @@ public class BusinessLogicTests [Fact] public void CantCancelConfirmedShoppingCart() => Spec.Given([ - new ShoppingCartOpened(shoppingCartId, clientId, now), - new ProductItemAddedToShoppingCart(shoppingCartId, PricedProductItem(), now), - new ShoppingCartConfirmed(shoppingCartId, now) + new Opened(clientId, now), + new ProductItemAdded(PricedProductItem(), now), + new Confirmed(now) ]) .When(state => state.Cancel(now) diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/PricingCalculator.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/Pricing/PricingCalculator.cs similarity index 97% rename from Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/PricingCalculator.cs rename to Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/Pricing/PricingCalculator.cs index e805ce8ea..343d3da82 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/PricingCalculator.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/Pricing/PricingCalculator.cs @@ -1,4 +1,4 @@ -namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable; +namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable.Pricing; public interface IProductPriceCalculator { diff --git a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs index 7a2c97efe..fcbc74369 100644 --- a/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs +++ b/Workshops/IntroductionToEventSourcing/Solved/07-BusinessLogic.Slimmed/Mutable/ShoppingCart.cs @@ -1,3 +1,5 @@ +using IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable.Pricing; + namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable; using static ShoppingCartEvent; @@ -5,31 +7,26 @@ namespace IntroductionToEventSourcing.BusinessLogic.Slimmed.Mutable; // EVENTS public abstract record ShoppingCartEvent { - public record ShoppingCartOpened( - Guid ShoppingCartId, + public record Opened( Guid ClientId, DateTimeOffset OpenedAt ): ShoppingCartEvent; - public record ProductItemAddedToShoppingCart( - Guid ShoppingCartId, + public record ProductItemAdded( PricedProductItem ProductItem, DateTimeOffset AddedAt ): ShoppingCartEvent; - public record ProductItemRemovedFromShoppingCart( - Guid ShoppingCartId, + public record ProductItemRemoved( PricedProductItem ProductItem, DateTimeOffset RemovedAt ): ShoppingCartEvent; - public record ShoppingCartConfirmed( - Guid ShoppingCartId, + public record Confirmed( DateTimeOffset ConfirmedAt ): ShoppingCartEvent; - public record ShoppingCartCanceled( - Guid ShoppingCartId, + public record Canceled( DateTimeOffset CanceledAt ): ShoppingCartEvent; @@ -68,45 +65,43 @@ public override void Evolve(ShoppingCartEvent @event) { switch (@event) { - case ShoppingCartOpened opened: + case Opened opened: Apply(opened); break; - case ProductItemAddedToShoppingCart productItemAdded: + case ProductItemAdded productItemAdded: Apply(productItemAdded); break; - case ProductItemRemovedFromShoppingCart productItemRemoved: + case ProductItemRemoved productItemRemoved: Apply(productItemRemoved); break; - case ShoppingCartConfirmed confirmed: + case Confirmed confirmed: Apply(confirmed); break; - case ShoppingCartCanceled canceled: + case Canceled canceled: Apply(canceled); break; } } - public static ShoppingCart Open(Guid cartId, Guid clientId, DateTimeOffset now) + public static ShoppingCart Open(Guid clientId, DateTimeOffset now) { - return new ShoppingCart(cartId, clientId, now); + return new ShoppingCart(clientId, now); } public static ShoppingCart Initial() => new(); - private ShoppingCart(Guid id, Guid clientId, DateTimeOffset now) + private ShoppingCart(Guid clientId, DateTimeOffset now) { - var @event = new ShoppingCartOpened(id, clientId, now); + var @event = new Opened(clientId, now); Enqueue(@event); - Apply(@event); } //just for default creation of empty object private ShoppingCart() { } - private void Apply(ShoppingCartOpened opened) + private void Apply(Opened opened) { - Id = opened.ShoppingCartId; ClientId = opened.ClientId; Status = ShoppingCartStatus.Pending; } @@ -123,13 +118,12 @@ DateTimeOffset now var pricedProductItem = productPriceCalculator.Calculate(productItem); - var @event = new ProductItemAddedToShoppingCart(Id, pricedProductItem, now); + var @event = new ProductItemAdded(pricedProductItem, now); Enqueue(@event); - Apply(@event); } - private void Apply(ProductItemAddedToShoppingCart productItemAdded) + private void Apply(ProductItemAdded productItemAdded) { var pricedProductItem = productItemAdded.ProductItem; var productId = pricedProductItem.ProductId; @@ -157,10 +151,9 @@ public void RemoveProduct(PricedProductItem productItemToBeRemoved, DateTimeOffs if (!HasEnough(productItemToBeRemoved)) throw new InvalidOperationException("Not enough product items to remove"); - var @event = new ProductItemRemovedFromShoppingCart(Id, productItemToBeRemoved, now); + var @event = new ProductItemRemoved(productItemToBeRemoved, now); Enqueue(@event); - Apply(@event); } private bool HasEnough(PricedProductItem productItem) @@ -172,7 +165,7 @@ private bool HasEnough(PricedProductItem productItem) return currentQuantity >= productItem.Quantity; } - private void Apply(ProductItemRemovedFromShoppingCart productItemRemoved) + private void Apply(ProductItemRemoved productItemRemoved) { var pricedProductItem = productItemRemoved.ProductItem; var productId = pricedProductItem.ProductId; @@ -199,13 +192,12 @@ public void Confirm(DateTimeOffset now) if (ProductItems.Count == 0) throw new InvalidOperationException($"Cannot confirm empty shopping cart"); - var @event = new ShoppingCartConfirmed(Id, now); + var @event = new Confirmed(now); Enqueue(@event); - Apply(@event); } - private void Apply(ShoppingCartConfirmed confirmed) + private void Apply(Confirmed confirmed) { Status = ShoppingCartStatus.Confirmed; ConfirmedAt = confirmed.ConfirmedAt; @@ -217,13 +209,12 @@ public void Cancel(DateTimeOffset now) throw new InvalidOperationException( $"Canceling cart in '{Status}' status is not allowed."); - var @event = new ShoppingCartCanceled(Id, now); + var @event = new Canceled(now); Enqueue(@event); - Apply(@event); } - private void Apply(ShoppingCartCanceled canceled) + private void Apply(Canceled canceled) { Status = ShoppingCartStatus.Canceled; CanceledAt = canceled.CanceledAt;