Search code examples
umbracoumbraco-ucommerce

uCommerce - add dynamic property to order line


I have hit a problem building a uCommerce site based on top of the demo razor store available http://thesitedoctor.co.uk/portfolio/avenue-clothingcom/

The demo uses servicestack and the ucommerceapi for its basket functions.

I am trying to add a dynamic property to the basket (on an order line) at the point where the user clicks buy. I traced through the productpage.js file and amended the code to add a new property ('message'):

function (data) {
var variant = data.Variant;
$.uCommerce.addToBasket(
{
    sku: variant.Sku,
    variantSku: variant.VariantSku,
    quantity: qty,
    message: $('#personalisedMessage').val()
},
function () {
    updateCartTotals(addToCartButton);
}
);
});

using firebug, i checked the data that is being posted

addToExistingLine: true
message: "this is a message"
quantity:"1" 
sku: "Product (options: none)"
variantSku:""

Posting this does not cause an error, but I cannot tell if it has worked either - I cannot find it in the database, assuming that it would be stored in OrderProperty table. In this scenario, I am 'buying' a product with no variations.

Any help is greatly appreciated with this.


Solution

  • Out of the box you can't add order/line item properties via the API like that. The API payload that you've added to is specified although valid JSON won't get interpreted/used by the API.

    Instead what you'll need to do is add your own method to the API. To do this you'll need to implement a service from IUCommerceApiService and then you can do what you need. I've created an example (untested) below and will get it added to the demo store as I think it's a useful bit of functionality to have.

    public class AddOrderLineProperty
    {
        public int? OrderLineId { get; set; }
    
        public string Sku { get; set; }
    
        public string VariantSku { get; set; }
    
        public string Key { get; set; }
    
        public string Value { get; set; }
    }
    public class AddOrderLinePropertyResponse : IHasResponseStatus
    {
        public AddOrderLinePropertyResponse() { }
    
        public AddOrderLinePropertyResponse(UCommerce.EntitiesV2.OrderLine line)
        {
            if (line == null)
            {
                UpdatedLine = new LineItem();
                return;
            }
    
            var currency = SiteContext.Current.CatalogContext.CurrentCatalog.PriceGroup.Currency;
            var lineTotal = new Money(line.Total.Value, currency);
    
            UpdatedLine = new LineItem()
            {
                OrderLineId = line.OrderLineId,
                Quantity = line.Quantity,
                Sku = line.Sku,
                VariantSku = line.VariantSku,
                Price = line.Price,
                ProductName = line.ProductName,
                Total = line.Total,
                FormattedTotal = lineTotal.ToString(),
                UnitDiscount = line.UnitDiscount,
                VAT = line.VAT,
                VATRate = line.VATRate
            };
        }
    
        public ResponseStatus ResponseStatus { get; set; }
    
        public LineItem UpdatedLine { get; set; }
    }
    public class AddOrderLinePropertyService : ServiceBase<AddOrderLineProperty>, IUCommerceApiService
    {
        protected override object Run(AddOrderLineProperty request)
        {
            var orderLineId = request.OrderLineId;
            var sku = request.Sku;
            var variantSku = request.VariantSku;
    
            var orderLine = findOrderLine(orderLineId, sku, variantSku);
            addPropertyToOrderLine(orderLine, request.Key, request.Value);
    
            TransactionLibrary.ExecuteBasketPipeline();
            var newLine = findOrderLine(orderLineId, sku, variantSku);
            return new AddOrderLinePropertyResponse(newLine);
        }
    
        private void addPropertyToOrderLine(OrderLine orderLine, string key, string value)
        {
            if (orderLine == null)
                return;
    
            orderLine[key] = value;
    
            orderLine.Save();
        }
    
        private static OrderLine findOrderLine(int? orderLineId, string sku, string variantSku)
        {
            return orderLineId.HasValue
                                ? getOrderLineByOrderLineId(orderLineId)
                                : getOrderLineBySku(sku, variantSku);
        }
    
        private static OrderLine getOrderLineBySku(string sku, string variantSku)
        {
            return String.IsNullOrWhiteSpace(variantSku)
                                ? getOrderLines().FirstOrDefault(l => (l.Sku == sku))
                                : getOrderLines().FirstOrDefault(l => (l.Sku == sku && l.VariantSku == variantSku));
        }
    
        private static OrderLine getOrderLineByOrderLineId(int? orderLineId)
        {
            return getOrderLines().FirstOrDefault(l => l.OrderLineId == orderLineId);
        }
    
        private static ICollection<OrderLine> getOrderLines()
        {
            return TransactionLibrary.GetBasket().PurchaseOrder.OrderLines;
        }
    }
    

    You'll need to add the new method to uCommerce.jQuery.js as well something like this:

    addOrderLineProperty: function (options, onSuccess, onError) {
        var defaults = {
            orderLineId: 0
        };
        var extendedOptions = $.extend(defaults, options);
        callServiceStack({ AddOrderLineProperty: extendedOptions }, onSuccess, onError);
    }
    

    Let me know if you have any issues using it.

    Tim