Skip to content

Instantly share code, notes, and snippets.

@xrisdoc
Last active February 24, 2017 14:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xrisdoc/1620f4ae38b1aa19a895b604a656e23d to your computer and use it in GitHub Desktop.
Save xrisdoc/1620f4ae38b1aa19a895b604a656e23d to your computer and use it in GitHub Desktop.
using My.OrderPortal.Models;
using Merchello.Core.Gateways.Payment;
using Merchello.Core.Gateways.Shipping;
using Merchello.Core.Models;
using Merchello.Web;
using Merchello.Web.Mvc;
using Constants = Merchello.Providers.Constants;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Merchello.Core;
using Merchello.Web.Pluggable;
using Merchello.Providers.Payment.PurchaseOrder;
using Merchello.Web.Store.Models;
using Merchello.Web.Models.VirtualContent;
using Merchello.Web.Models.Ui;
namespace My.OrderPortal.Controllers
{
public class CheckoutController : MerchelloSurfaceController
{
/// <summary>
/// Specifies the the key for the default Shipping Method (Standard Shipping)
/// </summary>
private const string _shipMethodKey = "7271fa1f-4ad4-461d-9f88-ff0a42dee256";
/// <summary>
/// Specifies the the key for the default Payment Method (Purchase Order)
/// </summary>
private const string _paymentMethodKey = "b7660d30-8f2c-4029-9943-5c8570aa914f";
/// <summary>
/// Specifies the Id of the page that will be used for the Confirmation page
/// </summary>
private const int _confirmationPageId = 1104;
/// <summary>
/// The prefix to be added to the invoice number when it is generated.
/// </summary>
private const string _invoicePrefix = "GWAC";
/// <summary>
///
/// </summary>
protected MerchelloHelper Merchello { get; }
public CheckoutController()
{
Merchello = new MerchelloHelper();
}
public ActionResult CheckoutSummary()
{
var model = new CheckoutPlaceOrderModel();
var checkoutManager = Basket.GetCheckoutManager();
// Get the current customer as an instance of ICustomer.
var customer = (ICustomer)CurrentCustomer;
var currentBillingAddress = checkoutManager.Customer.GetBillToAddress();
var currentShippingAddress = checkoutManager.Customer.GetShipToAddress();
IAddress customerBillingAddress = null;
IAddress customerShippingAddress = null;
if (currentBillingAddress == null)
{
// Set the billing address to that of the Current Customer's default billing address
var defaultBillingAddress = customer.DefaultCustomerAddress(AddressType.Billing);
customerBillingAddress = new Address()
{
Organization = defaultBillingAddress.Company,
Address1 = defaultBillingAddress.Address1,
Address2 = defaultBillingAddress.Address2,
Locality = defaultBillingAddress.Locality,
CountryCode = defaultBillingAddress.CountryCode,
PostalCode = defaultBillingAddress.PostalCode,
Name = customer.FullName,
Phone = defaultBillingAddress.Phone,
Email = customer.Email
};
checkoutManager.Customer.SaveBillToAddress(customerBillingAddress);
}
if(currentShippingAddress == null)
{
// Set the shipping address to that of the Current Customer's default shipping address
var defaultShippingAddress = customer.DefaultCustomerAddress(AddressType.Shipping);
customerShippingAddress = new Address()
{
Organization = defaultShippingAddress.Company,
Address1 = defaultShippingAddress.Address1,
Address2 = defaultShippingAddress.Address2,
Locality = defaultShippingAddress.Locality,
CountryCode = defaultShippingAddress.CountryCode,
PostalCode = defaultShippingAddress.PostalCode,
Name = customer.FullName,
Phone = defaultShippingAddress.Phone,
Email = customer.Email
};
checkoutManager.Customer.SaveShipToAddress(customerShippingAddress);
}
if(customerShippingAddress != null)
{
// Set the default shipping method (Standard Shipping).
var shipment = Basket.PackageBasket(customerShippingAddress).FirstOrDefault();
var shipmentQuote = shipment.ShipmentRateQuoteByShipMethod(_shipMethodKey);
checkoutManager.Shipping.SaveShipmentRateQuote(shipmentQuote);
}
// Set the default payment method (Purchase Order)
var gatewayMethod = GatewayContext.Payment.GetPaymentGatewayMethodByKey(new Guid(_paymentMethodKey));
var paymentMethod = gatewayMethod.PaymentMethod;
checkoutManager.Payment.SavePaymentMethod(paymentMethod);
// Prepare the invoice for review.
// This won't actually create an invoice, but will give us a representation of what the invoice will be.
// So, we can use this to present that data to the user to review their order before they actually confirm an place the order.
var invoice = checkoutManager.Payment.PrepareInvoice();
model.Items = invoice.Items.Select(CreateLineItemModel).ToList();
model.Total = invoice.Total;
model.BillingAddress = invoice.GetBillingAddress();
model.ShippingAddress = invoice.GetShippingAddresses().FirstOrDefault();
return PartialView(model);
}
protected StoreLineItemModel CreateLineItemModel(ILineItem item)
{
var lineItem = new StoreLineItemModel
{
Key = item.Key,
Name = item.Name,
Sku = item.Sku,
Quantity = item.Quantity,
Amount = item.Price,
LineItemType = item.LineItemType,
ExtendedData = item.ExtendedData.AsEnumerable()
};
if (item.LineItemType == LineItemType.Product)
{
// Get the product key from the extended data collection
// This is added internally when the product was added to the basket
var productKey = item.ExtendedData.GetProductKey();
// Get an instantiated IProductContent for use in the basket table design
var product = (item.LineItemType == LineItemType.Product && productKey.Equals(Guid.Empty) == false) ?
Merchello.TypedProductContent(productKey) :
null;
// Get a list of choices the customer made.
// This can also be done by looking at the variant (Attributes) but this is a bit quicker and is something commonly done.
var customerChoices = item.GetProductOptionChoicePairs();
// Modifiy the BasketItemModel generated in the base factory
lineItem.Product = product;
lineItem.ProductKey = productKey;
lineItem.CustomerOptionChoices = customerChoices;
}
return lineItem;
}
[HttpPost]
[ActionName("PlaceOrder")]
public ActionResult PlaceOrder(CheckoutPlaceOrderModel model)
{
if(ModelState.IsValid)
{
var checkoutManager = Basket.GetCheckoutManager();
var paymentMethod = checkoutManager.Payment.GetPaymentMethod();
// Set the prefix for the invoice number.
checkoutManager.Context.Settings.InvoiceNumberPrefix = _invoicePrefix;
// Create the processor argument collection, where we'll pass in the purchase order
var args = new ProcessorArgumentCollection
{
{ Constants.PurchaseOrder.PoStringKey, model.PurchaseOrderNumber }
};
var attempt = checkoutManager.Payment.AuthorizePayment(paymentMethod.Key, args);
if (attempt.Payment.Success)
{
var invoice = attempt.Invoice;
// Set the invoiceKey on the currnet customer.
// This is so that we know what invoice to display on the receipt page
this.CustomerContext.SetValue("invoiceKey", invoice.Key.ToString());
// Capture a payment of £0.00.
// This seems to be required so that we can enable the Fulfill button on the relevant invoice page.
var gatewayMethod = GatewayContext.Payment.GetPaymentGatewayMethodByKey(new Guid(_paymentMethodKey));
invoice.CapturePayment(attempt.Payment.Result, gatewayMethod, 0m);
TempData.Add("OrderReceipt.IsNewOrder", "true");
// Get the billing address and check if it has an email address.
// The email address is required to send the order confirmation.
var billing = invoice.GetBillingAddress();
if (!string.IsNullOrWhiteSpace(billing.Email))
{
Notification.Trigger("OrderConfirmation", attempt, new[] { billing.Email });
}
// Redirect to the confirmation page (i.e. Receipt Page)
var confirmationPage = Umbraco.TypedContent(_confirmationPageId);
if (confirmationPage != null)
{
return RedirectToUmbracoPage(confirmationPage);
}
}
}
return CurrentUmbracoPage();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment