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 })); }
// This method is about what we ended up with in "Fund." - with a few changes done for Adv. public ActionResult CheckOut(CheckOutViewModel model) { // SplitPay is in a Session-variable (bool) string paymentProcessResult = String.Empty; // Load the cart, it should be one there var cart = _orderRepository.Load <ICart>(GetContactId(), "Default").FirstOrDefault(); if (cart == null) { throw new InvalidOperationException("No cart found"); // make nicer } #region What actually happens when loading a cart - Adv. //Cart cart = OrderContext.Current.GetCart( // "SomeCart" // , CustomerContext.Current.CurrentContactId // , MarketId.Default); // ...is still what happens in behind #endregion // should clean-up among payments here if the first time failed - Qty 10 test // quick fixdon in the base class // From Fund IOrderAddress theAddress = AddAddressToOrder(cart); // ToDo: Added this field for Adv. & Find ... doing it simple now using one Address // The address is for Find, but we need to add it to MDP to be able to use it properly // This is a Serialized cart, so doesn't crash if the field is not added to MDP theAddress.Properties["AddressType"] = "Shipping"; #region Ship & Pay from Fund // ToDo: Define Shipping - From Fund AdjustFirstShipmentInOrder(cart, theAddress, model.SelectedShipId); // ...as a Shipment is added by epi // ToDo: Define Payment - From Fund AddPaymentToOrder(cart, model.SelectedPayId); // ...as this is not added by default #endregion #region Split Pay // RoCe: Fix this - addSecondPayment comes in as a param (bool) // ... force for now if BF-Card is found ... using Session if ((bool)Session["SecondPayment"] == true) { ccService.AddSecondPaymentToOrder(cart); } // gathered info this.frontEndMessage = ccService.FrontEndMessage; #endregion // Possible change of the cart... adding this // would have this done if a flag were set var cartReference = _orderRepository.Save(cart); // Original Fund... (with additions) IPurchaseOrder purchaseOrder; OrderReference orderReference; #region Transaction Scope using (var scope = new Mediachase.Data.Provider.TransactionScope()) // one in BF, also { 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 } // just checking the cart in watch window var theShipping = cart.GetFirstShipment(); var theLineItems = cart.GetAllLineItems(); var firstPayment = cart.GetFirstForm().Payments.First(); // no "GetFirstPayment()" var theforms = cart.Forms; //_lineItemCalculator.GetDiscountedPrice() // second payment is added in the Trousers-Controller // ...fiddling with the GiftCarde as well // before 11 //cart.ProcessPayments(_paymentProcessor, _orderGroupCalculator); // Gets the older one //IEnumerable<PaymentProcessingResult> theResult // = cart.ProcessPayments(_paymentProcessor, _orderGroupCalculator); //paymentProcessResult = theResult.First().Message; PaymentProcessingResult otherResult = _paymentProcessor.ProcessPayment(cart, cart.GetFirstForm().Payments.First(), cart.GetFirstShipment()); frontEndMessage += otherResult.Message; if (otherResult.IsSuccessful) { IPayment thePay = cart.GetFirstForm().Payments.First(); thePay.Status = PaymentStatus.Processed.ToString(); } else { IPayment thePay = cart.GetFirstForm().Payments.First(); thePay.Status = PaymentStatus.Failed.ToString(); throw new System.Exception("Bad payment"); // could have more grace } // A custom "shipping-processor" created (needs to do OldSchool-things right now) // Have a custom (very simple) Shipping-Provider added to the solution. // the processor can be cleaned up a lot, no need to show it // Custom thing... Error in 11... on currency... check later //ShippingProcessor p = new ShippingProcessor(); //p.ProcessShipments(cart as OrderGroup); // have to go Old-school // ...only one form, still var totalProcessedAmount = cart.GetFirstForm().Payments.Where (x => x.Status.Equals(PaymentStatus.Processed.ToString())).Sum(x => x.Amount); // nice extension method var cartTotal = cart.GetTotal(); // Do inventory - decrement or put back in stock if (totalProcessedAmount != cart.GetTotal(_orderGroupCalculator).Amount) { // put back the reserved request _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Cancelled, (item, issue) => validationIssues.Add(item, issue)); #region OldSchool Inventory - no demo,just checking ... were undocumented and wrong in SDK //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 } // RoCe: have to do Promos here also ... move stuff from cart to "base" // simulation... should be an "else" cart.GetFirstShipment().OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; // decrement inventory and let it go _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Completed, (item, issue) => validationIssues.Add(item, issue)); // Should do the ClubCard thing here - ClubMembers are logged in // PaymentMethodName = "GiftCard" if (CustomerContext.Current.CurrentContact != null) { // check if GiftCard was used, don't give bonus for that payment IEnumerable <IPayment> giftCardPayment = cart.GetFirstForm().Payments.Where (x => x.PaymentMethodName.Equals("GiftCard")); if (giftCardPayment.Count() >= 1) { ccService.UpdateClubCard(cart, totalProcessedAmount - giftCardPayment.First().Amount); } else { // no GiftCard, but collecting points ccService.UpdateClubCard(cart, totalProcessedAmount); } } #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); //InventoryRecord rec3 = _invService.Service.Get(LI.Code, wh.Code); // inventory reserved, but not decremented #endregion OldSchool orderReference = _orderRepository.SaveAsPurchaseOrder(cart); _orderRepository.Delete(cart.OrderLink); //InventoryRecord rec5 = _invService.Service.Get(LI.Code, wh.Code); // just checking scope.Complete(); } // End Tran #endregion #region JustChecking //Guid custLock; //OrderGroupLockManager.IsOrderGroupLocked(orderReference.OrderGroupId, out (Guid)CustomerContext.Current.CurrentContact.PrimaryKeyId)); /* * OrderGroupLockManager.LockOrderGroup(orderReference.OrderGroupId * , (Guid)CustomerContext.Current.CurrentContact.PrimaryKeyId); * * OrderGroupLockManager.UnlockOrderGroup(orderReference.OrderGroupId); */ #endregion // just demoing (Find using this further down) purchaseOrder = _orderRepository.Load <IPurchaseOrder>(orderReference.OrderGroupId); // check the below var theType = purchaseOrder.OrderLink.OrderType; var toString = purchaseOrder.OrderLink.ToString(); // Gets ID and Type ... combined #region ThisAndThat - from Fund // should do some with OrderStatusManager OrderStatus poStatus; poStatus = purchaseOrder.OrderStatus; //purchaseOrder.OrderStatus = OrderStatus.InProgress; //var info = OrderStatusManager.GetPurchaseOrderStatus(PO); var shipment = purchaseOrder.GetFirstShipment(); var status = shipment.OrderShipmentStatus; //shipment. ... no that much to do shipment.OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; #region Old-School, but some useful stuff //OrderStatusManager.ReleaseOrderShipment(purchaseOrder.GetFirstShipment() as Shipment); //OrderStatusManager.ReleaseOrderShipment(PO.OrderForms[0].Shipments[0]); // it gets released //OrderStatusManager.HoldOrder(PO); // it gets hold //OrderStatusManager. // seems to be a DTO involved... don't neeed to set the time like this... could use the new ordernote //OrderNotesManager.AddNoteToPurchaseOrder(PO, DateTime.UtcNow.ToShortDateString() + " done some for shipping", OrderNoteTypes.System, CustomerContext.Current.CurrentContactId); // _orderRepository.Save(purchaseOrder); // check if it's like before ... yes it is needed to save again #endregion var notes = purchaseOrder.Notes; // IOrderNote is 0 // RoCe - possible BUG // PO.OrderNotes works and contain the note above //IOrderNote theNewNote = 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() }; // bug issued purchaseOrder.Notes.Add(otherNote); // void back purchaseOrder.ExpirationDate = DateTime.Now.AddMonths(1); PurchaseOrder oldPO = (PurchaseOrder)purchaseOrder; //oldPO.OrderAddresses. // yes, still need to come after adding notes _orderRepository.Save(purchaseOrder); // checking down here ... yes it needs to be saved again #endregion string conLang0 = ContentLanguage.PreferredCulture.Name; //string conLang1 = ContentLanguage.PreferredCulture.NativeName; //string conLang2 = ContentLanguage.PreferredCulture.TwoLetterISOLanguageName; // original shipment, could rewrite and get the dto so it can be used for the second shipment also // or grab the dto when loading into the dropdowns ShippingMethodDto.ShippingMethodRow theShip = ShippingManager.GetShippingMethod(model.SelectedShipId).ShippingMethod.First(); #region Find & Queue plumbing // would be done async... if (IsOnLine) // just checking if the below is possible, if we have network access { // index PO and addresses for BoughtThisBoughtThat & demographic analysis IClient client = Client.CreateFromConfig(); // native FindQueries Qs = new FindQueries(client, true); Qs.OrderForFind(purchaseOrder); } if (poToQueue) // could have better tran-integrity, Extraction later in PO_Extract.sln/Sheduled job { // ToDo: Put a small portion of data from the PO to msmq, will eventually (out-of-process) go to the ERP string QueueName = ".\\Private$\\MyQueue"; MessageQueue Q1 = new MessageQueue(QueueName); MyMessage m = new MyMessage() { poNr = purchaseOrder.OrderNumber, status = purchaseOrder.OrderStatus.ToString(), orderGroupId = orderReference.OrderGroupId }; Q1.Send(m); } #endregion // Final steps, navigate to the order confirmation page StartPage home = _contentLoader.Get <StartPage>(ContentReference.StartPage); ContentReference orderPageReference = home.Settings.orderPage; string passingValue = frontEndMessage + paymentProcessResult + " - " + purchaseOrder.OrderNumber; return(RedirectToAction("Index", new { node = orderPageReference, passedAlong = passingValue })); }
// This method is about what we ended up with in "Fund." - with a few changes done for Adv. public ActionResult CheckOut(CheckOutViewModel model) { // SplitPay is in a Session-variable (bool) string paymentProcessResult = String.Empty; // Load the cart, it should be one there var cart = _orderRepository.Load <ICart>(GetContactId(), "Default").FirstOrDefault(); if (cart == null) { throw new InvalidOperationException("No cart found"); // make nicer } // From Fund IOrderAddress theAddress = AddAddressToOrder(cart); // ToDo: Added this field for Adv. & Find ... doing it simple now using one Address // The address is for Find, but we need to add it to MDP to be able to use it properly // This is a Serialized cart, so doesn't crash if the field is not added to MDP theAddress.Properties["AddressType"] = "Shipping"; #region Ship & Pay from Fund // ToDo: Define Shipping - From Fund AdjustFirstShipmentInOrder(cart, theAddress, model.SelectedShipId); // ...as a Shipment is added by epi // ToDo: Define Payment - From Fund AddPaymentToOrder(cart, model.SelectedPayId); // ...as this is not added by default #endregion #region Split Pay // RoCe: Fix this - addSecondPayment comes in as a param (bool) // ... force for now if BF-Card is found ... using Session if ((bool)Session["SecondPayment"] == true) { ccService.AddSecondPaymentToOrder(cart); } // gathered info this.frontEndMessage = ccService.FrontEndMessage; #endregion // Possible change of the cart... adding this // would have this done if a flag were set var cartReference = _orderRepository.Save(cart); // Original Fund... (with additions) IPurchaseOrder purchaseOrder; OrderReference orderReference; #region Transaction Scope using (var scope = new Mediachase.Data.Provider.TransactionScope()) // one in BF, also { 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 } // just checking the cart in watch window var theShipping = cart.GetFirstShipment(); var theLineItems = cart.GetAllLineItems(); var firstPayment = cart.GetFirstForm().Payments.First(); // no "GetFirstPayment()" var theforms = cart.Forms; PaymentProcessingResult otherResult = _paymentProcessor.ProcessPayment(cart, cart.GetFirstForm().Payments.First(), cart.GetFirstShipment()); frontEndMessage += otherResult.Message; if (otherResult.IsSuccessful) { IPayment thePay = cart.GetFirstForm().Payments.First(); thePay.Status = PaymentStatus.Processed.ToString(); } else { IPayment thePay = cart.GetFirstForm().Payments.First(); thePay.Status = PaymentStatus.Failed.ToString(); throw new System.Exception("Bad payment"); // could have more grace } // ...only one form, still var totalProcessedAmount = cart.GetFirstForm().Payments.Where (x => x.Status.Equals(PaymentStatus.Processed.ToString())).Sum(x => x.Amount); // nice extension method var cartTotal = cart.GetTotal(); // Do inventory - decrement or put back in stock if (totalProcessedAmount != cart.GetTotal(_orderGroupCalculator).Amount) { // put back the reserved request _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Cancelled, (item, issue) => validationIssues.Add(item, issue)); throw new InvalidOperationException("Wrong amount"); // maybe change approach } // RoCe: have to do Promos here also ... move stuff from cart to "base" // simulation... should be an "else" cart.GetFirstShipment().OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; // decrement inventory and let it go _inventoryProcessor.AdjustInventoryOrRemoveLineItem(cart.GetFirstShipment() , OrderStatus.Completed, (item, issue) => validationIssues.Add(item, issue)); // Should do the ClubCard thing here - ClubMembers are logged in // PaymentMethodName = "GiftCard" if (CustomerContext.Current.CurrentContact != null) { // check if GiftCard was used, don't give bonus for that payment IEnumerable <IPayment> giftCardPayment = cart.GetFirstForm().Payments.Where (x => x.PaymentMethodName.Equals("GiftCard")); if (giftCardPayment.Count() >= 1) { ccService.UpdateClubCard(cart, totalProcessedAmount - giftCardPayment.First().Amount); } else { // no GiftCard, but collecting points ccService.UpdateClubCard(cart, totalProcessedAmount); } } orderReference = _orderRepository.SaveAsPurchaseOrder(cart); _orderRepository.Delete(cart.OrderLink); scope.Complete(); } // End Tran #endregion // just demoing (Find using this further down) purchaseOrder = _orderRepository.Load <IPurchaseOrder>(orderReference.OrderGroupId); // check the below var theType = purchaseOrder.OrderLink.OrderType; var toString = purchaseOrder.OrderLink.ToString(); // Gets ID and Type ... combined #region ThisAndThat - from Fund OrderStatus poStatus; poStatus = purchaseOrder.OrderStatus; //purchaseOrder.OrderStatus = OrderStatus.InProgress; //var info = OrderStatusManager.GetPurchaseOrderStatus(PO); var shipment = purchaseOrder.GetFirstShipment(); var status = shipment.OrderShipmentStatus; //shipment. ... no that much to do shipment.OrderShipmentStatus = OrderShipmentStatus.InventoryAssigned; var notes = purchaseOrder.Notes; // IOrderNote is 0 // have getters & setters... not good 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() }; // bug issued purchaseOrder.Notes.Add(otherNote); // void back purchaseOrder.ExpirationDate = DateTime.Now.AddMonths(1); // yes, still need to come after adding notes _orderRepository.Save(purchaseOrder); // checking down here ... yes it needs to be saved again #endregion string conLang0 = ContentLanguage.PreferredCulture.Name; // original shipment, could rewrite and get the dto so it can be used for the second shipment also // or grab the dto when loading into the dropdowns ShippingMethodDto.ShippingMethodRow theShip = ShippingManager.GetShippingMethod(model.SelectedShipId).ShippingMethod.First(); #region Find & Queue plumbing // would be done async... if (IsOnLine) // just checking if the below is possible, if we have network access { // index PO and addresses for BoughtThisBoughtThat & demographic analysis IClient client = Client.CreateFromConfig(); // native FindQueries Qs = new FindQueries(client, true); Qs.OrderForFind(purchaseOrder); } if (poToQueue) // could have better tran-integrity, Extraction later in PO_Extract.sln/Sheduled job { // ToDo: Put a small portion of data from the PO to msmq, will eventually (out-of-process) go to the ERP string QueueName = ".\\Private$\\MyQueue"; MessageQueue Q1 = new MessageQueue(QueueName); MyMessage m = new MyMessage() { poNr = purchaseOrder.OrderNumber, status = purchaseOrder.OrderStatus.ToString(), orderGroupId = orderReference.OrderGroupId }; Q1.Send(m); } #endregion // Final steps, navigate to the order confirmation page StartPage home = _contentLoader.Get <StartPage>(ContentReference.StartPage); ContentReference orderPageReference = home.Settings.orderPage; string passingValue = frontEndMessage + paymentProcessResult + " - " + purchaseOrder.OrderNumber; return(RedirectToAction("Index", new { node = orderPageReference, passedAlong = passingValue })); }