public ActionResult CheckOut(CheckOutViewModel model) { // ToDo: Load the cart... remember the other ways of doing this var cart = _orderRepository.Load <ICart>(GetContactId(), DefaultCartName).FirstOrDefault(); if (cart == null) { throw new InvalidOperationException("No cart found"); // make nicer } // ToDo: Add an OrderAddress IOrderAddress theAddress = AddAddressToOrder(cart); // ToDo: Define/update Shipping AdjustFirstShipmentInOrder(cart, theAddress, model.SelectedShipId); // ToDo: Discounts for the cart, not in exercises yet... // a lot easier than before, does promotionEngine.Run(orderGroup, settings); // Return IEnumerable<RewardDescription> var rewards = cart.ApplyDiscounts(); // ToDo: Add a Payment to the Order AddPaymentToOrder(cart, model.SelectedPayId); // ToDo: Add a transaction scope and convert the cart to PO IPurchaseOrder purchaseOrder; OrderReference orderReference; using (var scope = new TransactionScope()) { var validationIssues = new Dictionary <ILineItem, ValidationIssue>(); // Added - sets a lock on inventory... could come earlier (outside tran) depending on TypeOf-"store" _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.InProgress, (item, issue) => validationIssues.Add(item, issue)); if (validationIssues.Count >= 1) { throw new Exception("Not possible right now"); // ...change approach and fork } // ECF 10 - void back cart.ProcessPayments(); // ECF 11 //IEnumerable<PaymentProcessingResult> PaymentProcessingResult = cart.ProcessPayments(); //var xyz = PaymentProcessingResult.First().IsSuccessful; // just looking around - (nice extension methods) var cartTotal = cart.GetTotal(); var handling = cart.GetHandlingTotal(); // OG-Calculator... aggregate on "all forms" var form = cart.GetFirstForm(); // var formHandling = form.HandlingTotal; // "handling" sits here on OF /* orderGroupCalculator does: * - Catches up with the "IOrderFormCalculator" * - GetSubTotal - Form-Calculator does * - GetHandlingTotal - Form-Calc does * - GetShippingCost - Form-Calc. does with ShippingCalc. - "processes" the shipment * - GetTaxTotal - FormCalc. does with Tax-Calc. */ var totalProcessedAmount = cart.GetFirstForm().Payments.Where (x => x.Status.Equals(PaymentStatus.Processed.ToString())).Sum(x => x.Amount); // could do more than this, but we just processed payment(s) if (totalProcessedAmount != cart.GetTotal(_orderGroupCalculator).Amount) { // ...we're not happy, put back the reserved request _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Cancelled, (item, issue) => validationIssues.Add(item, issue)); #region OldSchool Inventory check //List<InventoryRequestItem> requestItems = new List<InventoryRequestItem>(); // holds the "items" //InventoryRequestItem requestItem = new InventoryRequestItem(); //// calls for some logic //requestItem.RequestType = InventoryRequestType.Cancel; // as a demo //requestItem.OperationKey = reqKey; //requestItems.Add(requestItem); //InventoryRequest inventoryRequest = new InventoryRequest(DateTime.UtcNow, requestItems, null); //InventoryResponse inventoryResponse = _invService.Service.Request(inventoryRequest); //InventoryRecord rec4 = _invService.Service.Get(LI.Code, wh.Code); #endregion OldSchool throw new InvalidOperationException("Wrong amount"); // maybe change approach } // we're happy // ...could do this here - look at dhe different statuses cart.GetFirstShipment().OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; // decrement inventory and let it go _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Completed, (item, issue) => validationIssues.Add(item, issue)); #region OldSchool Inventory check //List<InventoryRequestItem> requestItems1 = new List<InventoryRequestItem>(); // holds the "items" //InventoryRequestItem requestItem1 = new InventoryRequestItem(); //// calls for some logic //requestItem1.RequestType = InventoryRequestType.Complete; // as a demo //requestItem1.OperationKey = reqKey; //requestItems1.Add(requestItem1); //InventoryRequest inventoryRequest1 = new InventoryRequest(DateTime.UtcNow, requestItems1, null); //InventoryResponse inventoryResponse1 = _invService.Service.Request(inventoryRequest1); #endregion OldSchool // we're even happier orderReference = _orderRepository.SaveAsPurchaseOrder(cart); _orderRepository.Delete(cart.OrderLink); scope.Complete(); } // End TransactionScope // ToDo: Housekeeping (Statuses for Shipping and PO, OrderNotes and save the order) // ...may need this below purchaseOrder = _orderRepository.Load <IPurchaseOrder>(orderReference.OrderGroupId); //_orderRepository.Load<IPurchaseOrder>() // check the below var theType = purchaseOrder.OrderLink.OrderType; var toString = purchaseOrder.OrderLink.ToString(); // Gets ID and Type ... combined #region ThisAndThat // should/could do some with OrderStatusManager, slightly old-school // OrderStatusManager. OrderStatus poStatus; poStatus = purchaseOrder.OrderStatus; //purchaseOrder.OrderStatus = OrderStatus.InProgress; //var info = OrderStatusManager.GetPurchaseOrderStatus(PO); // old-school //PO.Status = OrderStatus.InProgress.ToString(); var shipment = purchaseOrder.GetFirstShipment(); var status = shipment.OrderShipmentStatus; //shipment. ... no that much to do //shipment.OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; // Don't use OrderNoteManager ... it doesn't see the "new" stuff var notes = purchaseOrder.Notes; // IOrderNote is 0 Mediachase.Commerce.Orders.OrderNote otherNote = new OrderNote //IOrderNote { // Created = DateTime.Now, // do we need to set this ?? Nope .ctor does CustomerId = new Guid(), // can set this - regarded Detail = "Order ToString(): " + toString + " - Shipment tracking number: " + shipment.ShipmentTrackingNumber, LineItemId = purchaseOrder.GetAllLineItems().First().LineItemId, // OrderGroupId = 12, R/O - error // OrderNoteId = 12, // can define it, but it's disregarded - no error Title = "Some title", Type = OrderNoteTypes.Custom.ToString() }; // not intended to be used, as it's "Internal" //IOrderNote theNote = new EPiServer.Commerce.Order.Internal.SerializableNote(); purchaseOrder.Notes.Add(otherNote); // void back purchaseOrder.ExpirationDate = DateTime.Now.AddMonths(1); // ...need to come after adding notes _orderRepository.Save(purchaseOrder); #endregion // Final steps, navigate to the order confirmation page StartPage home = _contentLoader.Get <StartPage>(ContentReference.StartPage); ContentReference orderPageReference = home.Settings.OrderPage; // the below is a dummy, change to "PO".OrderNumber when done //string passingValue = String.Empty; string passingValue = purchaseOrder.OrderNumber; return(RedirectToAction("Index", new { node = orderPageReference, passedAlong = passingValue })); }
//Exercise (E2) Do CheckOut public ActionResult CheckOut(CheckOutViewModel model) { var cart = _orderRepository.LoadCart <ICart>(GetContactId(), DefaultCart); var isAutenticated = PrincipalInfo.CurrentPrincipal.Identity.IsAuthenticated; var orderAddress = AddAddressToOrder(cart); AdjustFirstShipmentInOrder(cart, orderAddress, model.SelectedShippingId); AddPaymentToOrder(cart, model.SelectedPaymentId); var validationMessages = ValidateCart(cart); if (!string.IsNullOrEmpty(validationMessages)) { model.Warnings = validationMessages; } // Adding this for test var cartReference = _orderRepository.Save(cart); IPurchaseOrder purchaseOrder; OrderReference orderReference; using (var scope = new TransactionScope()) { var validationIssues = new Dictionary <ILineItem, ValidationIssue>(); _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.InProgress, (item, issue) => validationIssues.Add(item, issue)); if (validationIssues.Count >= 1) { throw new Exception("Not possible right now"); } try { cart.ProcessPayments(); } catch (Exception e) { foreach ( var p in cart.GetFirstForm().Payments.Where(p => p.Status != PaymentStatus.Processed.ToString())) { cart } _orderRepository.Save(cart); throw new Exception("Payment failed"); } var totalProcessedAmount = cart.GetFirstForm().Payments.Where (x => x.Status.Equals(PaymentStatus.Processed.ToString())).Sum(x => x.Amount); var cartTotal = cart.GetTotal(); if (totalProcessedAmount != cart.GetTotal(_orderGroupCalculator).Amount) { _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Cancelled, (item, issue) => validationIssues.Add(item, issue)); throw new InvalidOperationException("Wrong amount"); // maybe change approach } // ...could do this here cart.GetFirstShipment().OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; // decrement inventory and let it go _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Completed, (item, issue) => validationIssues.Add(item, issue)); orderReference = _orderRepository.SaveAsPurchaseOrder(cart); purchaseOrder = _orderRepository.Load <IPurchaseOrder>(orderReference.OrderGroupId); _orderRepository.Delete(cart.OrderLink); scope.Complete(); } var note = _orderGroupFactory.CreateOrderNote(purchaseOrder); note.CustomerId = GetContactId(); note.Title = "Order Created"; note.Detail = "Order Created by Commerce Training Fundamentals"; note.Type = OrderNoteTypes.Custom.ToString(); purchaseOrder.Notes.Add(note); _orderRepository.Save(purchaseOrder); // Final steps, navigate to the order confirmation page StartPage home = _contentLoader.Get <StartPage>(ContentReference.StartPage); ContentReference orderPageReference = home.Settings.orderPage; // the below is a dummy, change to "PO".OrderNumber when done string passingValue = purchaseOrder.OrderNumber; return(RedirectToAction("Index", new { node = orderPageReference, passedAlong = passingValue })); }