public static IList<OrderDetail> Deserialize(string raw)
 {
     var details = new List<OrderDetail>();
     if (!String.IsNullOrWhiteSpace(raw))
     {
         var lines = raw.Split(new[] { RecordBreak }, StringSplitOptions.RemoveEmptyEntries);
         foreach (var line in lines)
         {
             var fields = line.Split(FieldBreak);
             OrderDetail detail = new OrderDetail
             {
                 Deleted = false,
                 Id = Convert.ToInt32(fields[0], CultureInfo.InvariantCulture),
                 OrderRecord_Id = Convert.ToInt32(fields[1], CultureInfo.InvariantCulture),
                 ProductPartRecord_Id = Convert.ToInt32(fields[2], CultureInfo.InvariantCulture),
                 Quantity = Convert.ToInt32(fields[3], CultureInfo.InvariantCulture),
                 UnitPrice = Convert.ToDecimal(fields[4], CultureInfo.InvariantCulture),
                 GSTRate = Convert.ToDecimal(fields[5], CultureInfo.InvariantCulture),
                 Description = StringDecode(fields[6]),
                 Sku = StringDecode(fields[7])
             };
             details.Add(detail);
         }
     }
     return details;
 }
        public OrderPart CreateOrder(int customerId, IEnumerable<ShoppingCartItem> items)
        {

            if (items == null)
                throw new ArgumentNullException("items");

            // Convert to an array to avoid re-running the enumerable
            var itemsArray = items.ToArray();

            if (!itemsArray.Any())
                throw new ArgumentException("Creating an order with 0 items is not supported", "items");

            var orderPart = CreateOrder();
            orderPart.CustomerId = customerId;
            orderPart.Status = OrderStatus.New;
        
            // Create an order detail for each item
            foreach (var item in itemsArray)
            {
                // This is not very fast but it is flexible and gathers the info we need
                // NOTE the use of a dynamic type below so we don't have to take a dependency on the 
                // external Cascade.ArtStock module for the ArtworkPart.

                var product = _contentManager.Get<ProductPart>(item.ProductId);
                var description = _contentManager.GetItemMetadata(product).DisplayText;
                if (product.ContentItem.Parts.Any(p => p.TypeDefinition.Name == "Artwork"))
                {
                    dynamic part = product;
                    description += " (" + part.ArtworkPart.ArtistRecord.Name + ")";
                }
                else
                    description += " (" + product.ContentItem.TypeDefinition.Name + ")";

                var detail = new OrderDetail
                {
                    OrderRecord_Id = orderPart.Id,
                    ProductPartRecord_Id = product.Id,
                    Quantity = item.Quantity,
                    UnitPrice = product.UnitPrice,
                    GSTRate = .1m,
                    Sku = product.Sku,
                    Description = description
                };

                orderPart.Details.Add(detail);
            }

            orderPart.UpdateTotals();

            return orderPart;
        }
        private void AddItem(PaypalRequest pr, int lineNumber, OrderDetail detail)
        {
            //var productPart = _services.ContentManager.Get<ProductPart>(detail.ProductPartRecord_Id);

            pr.Add("L_PAYMENTREQUEST_0_NAME" + lineNumber, detail.Sku);
            pr.Add("L_PAYMENTREQUEST_0_DESC" + lineNumber, detail.Description);
            pr.Add("L_PAYMENTREQUEST_0_QTY" + lineNumber, detail.Quantity.ToString("f2"));
            pr.Add("L_PAYMENTREQUEST_0_AMT" + lineNumber, detail.UnitPrice.ToString("f2"));
        }