Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Martin 81 posts 246 karma points
    Dec 16, 2014 @ 22:42
    Martin
    0

    Creating a product on the fly

    Hi Rusty,

    Could you please provide some sample code for creating a dynamic product as it doesn't seem to be documented anywhere. I would like to assign it a price, title and then some custom properties - in my particular case, two dates.

    The user will fill out some form data, this will be posted to the controller which will calculate price, create the product and then display it for the customer to see. The user should then be able to click 'add to basket' or 'add to basket and checkout'.

  • DFBerry 53 posts 130 karma points
    Dec 16, 2014 @ 22:56
    DFBerry
    0

     Martin,

     

    What do you mean by dynamic product? Do you mean a product that changes over time somehow?

     

    Products with variants can be added in this way:

    var productService = MerchelloContext.Current.Services.ProductService;
    var product = productService.CreateProduct(name, sku, price);

    //Assert.IsFalse(product.HasIdentity, "The product was saved");

    product.TrackInventory = false;
    product.Shippable = true;
    product.Weight = 10M;
    product.Manufacturer = "Mindfly";
    productService.Save(product);
               

    -Dina

     

     

     

     

     

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 17, 2014 @ 01:13
    Rusty Swayne
    100

    Hi Martin,

    When something is shippable you should also associate the product with a catalog.

            var productService = MerchelloContext.Current.Services.ProductService;
    
            var product = productService.CreateProduct(name, sku, 0);
            product.Available = true;
            product.TrackInventory = false;
            product.Shippable = true;
            // Taxable is false since they are included
            product.Taxable = false;
    
            _productService.Save(product);
    
            var warehouse = _warehouseService.GetDefaultWarehouse();
            var catalog = warehouse.WarehouseCatalogs.FirstOrDefault();
    
            if (catalog == null)
            {
                var error = new NullReferenceException("The default warehouse did not have any catalogs");
                throw error;
            }
    
            product.AddToCatalogInventory(catalog);
    
            productService.Save(product);
    

    If you are asking about an existing product that you want to add to the basket and change the price on the fly you could try one of the basket overloads.

    Merchello's basket is really more about the meta data in the extended data collection than a strict association with the product in the catalog - so you can do this by:

      var basket = CurrentCustomer.Basket();
    
      var product = Merchello.Query.Product.GetByKey( ... your product key ... );
    
      // assuming you don't have variants - you still need to get the master variant which represents a single product.
      // or get your variant by it's key
      var variant = product.GetProductVariantForPurchase();
    
      // now we build the extended data collection for the checkout work flow.  
      var extendedData = new ExtendedDataCollection();
    
      extendedData.AddProductVariantValues(variant);  // serializes all of the variant information used in the work flow
    
      // while the price is also serialized, the real values we want for the checkout are in the line item - so you 
      // can skip updating the extendedData price and simply add to the basket with
    
      basket.AddItem(product.Name, product.Sku, [your quantity], [your calculated price], extendedData);
    

    Make sense?

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 17, 2014 @ 01:19
    Rusty Swayne
    0

    Hi Martin ... sorry I missed your custom properties.

    before adding the item to the basket you could stuff your dates into the extendedData collection - so after the line

     extendedData.AddProductVariantValues(variant);
    
     // add your custom properties
     extendedData.SetValue("key-for-date1", date1.ToShortDateString());
     extendedData.SetValue("key-for-date2", date2.ToShortDateString());
    

    You can later retrieve those from the basket line item, invoice line item and order line item (also used in shipments) by using the GetValue on the ExtendedDataCollection for the line item with the matching sku. ... meaning the line items are copied from the basket to and invoice, from the invoice to an order ...

  • Biagio Paruolo 1593 posts 1824 karma points c-trib
    Aug 20, 2015 @ 10:29
    Biagio Paruolo
    0

    Is there a better and full example?

  • Flavio Spezi 128 posts 314 karma points
    Dec 21, 2014 @ 13:06
    Flavio Spezi
    0

    I prefere to do not use the built-in Merchello catalogue. Then I would add "not-codified" products in Basket.

    I look that it is not possible, then your code create a newest product for any article for any Basket.

    I am another idea:

    • create single generic product in Catalog with Merchello Backoffice ui, code "FormProduct".
    • when a buyer compile the form, will be add the "FormProduct" product to Basket, with custom Name, Description and Price.
    • if buyer requires another custom product, will be add another row to Basket, with same "FormProduct", another custom Name, Description and Price.

    Is it possible to use this solution?
    Will Merchello right behavior in any step of Basket life-cycle?

    Thanks

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 21, 2014 @ 19:17
    Rusty Swayne
    0

    Hi Flavio,

    I'm don't think I'm following what you mean by "not-codify" products in the basket but from what I understand your idea implies I think it is possible.

     var basket = CurrentCustomer.Basket();
    
     var fromProduct = Merchello.Query.Product.GetByKey( [your generic product key] );
    
     // assuming you do not have any options (thus other variants on the generic product)
     fromProduct.Price = "your price";
     fromProduct.Sku  = "your sku";  // sku is used in the basket to group line items
    
     // description is not a Merchello Product property - so if you need this you will need to add it to the extendedData collection 
     // at this point ... otherwise
    
     CurrentCustomer.Basket().AddItem(fromProduct, [your name], [your quantity]);
    

    ... does this work for you?

  • Flavio Spezi 128 posts 314 karma points
    Dec 22, 2014 @ 09:23
    Flavio Spezi
    0

    Thanks @Rusty.

    With "not-codify" product I mean a product that it is not in catalogue, because I think that the catalogue must be contains only standard articles.
    My eCommerce website will sell carpenter products. Then I will fill catalogue with tables, chairs, and so on. But a customer can compile a simplest form to indicates custom variants of a standard table, for example he can ask a table more or less length, or height. It can be a variant of standard article, but the special request is special, then I think that it is not to save to catalogue.
    But the website offers the opportunity to ask a newest article. Then it cann't be added as variant of product.

    I think that your code is what I need. But I understand the comment of "SKU"; can you spell more?

  • Flavio Spezi 128 posts 314 karma points
    Dec 22, 2014 @ 10:53
    Flavio Spezi
    0

    I am trying your code but I can't compile it: AddItem method does not expose an overload with ProductDisplay as type of product argument.
    Maybe I wrong to get the product? I have not a Merchello.Query, then I solved it with this:

    var merchHelper = new MerchelloHelper()
    var product = merchHelper.Query.Product.GetByKey( [-product key-] )
    
  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 22, 2014 @ 17:30
    Rusty Swayne
    1

    Flavio - totally sorry - my bad.

    it should be:

      var productService = MerchelloContext.Current.Services.ProductService;
    
      var fromProduct =  productService.GetByKey( [-product key-] );
    
      // assuming you do not have any options (thus other variants on the generic product)
      fromProduct.Price = "your price";
      fromProduct.Sku  = "your sku";  // sku is used in the basket to group line items
    
      // description is not a Merchello Product property - so if you need this you will need to add it to the extendedData collection 
      // at this point ... otherwise
      CurrentCustomer.Basket().AddItem(fromProduct, [your name], [your quantity]);
    
  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 22, 2014 @ 17:40
    Rusty Swayne
    0

    Missed your previous comment asking about the SKU.

    The SKU is a "product code", usually unique per specific product.

    Example.

    Maybe you sell:

    1 table - $1,100 - SKU: TBL123

    4 chairs without arms - $950 - SKU: chair123

    2 chairs with arms - $500 = SKU: chair123-plus

  • Biagio Paruolo 1593 posts 1824 karma points c-trib
    May 27, 2015 @ 15:10
    Biagio Paruolo
    0

    You could add some notes to the order if there are on fly and not fixed variants.

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Aug 20, 2015 @ 14:35
    Rusty Swayne
    0

    @Biagio - I've been considering this as a stub for a report of some sort.

  • Ben McKean 272 posts 549 karma points
    Jul 14, 2016 @ 08:58
    Ben McKean
    0

    Hi Rusty,

    I appreciate this is an old post but how do I get the line item URL? I know how to get the product/sku URL but I want the user to be able to navigate back to the variant that they have created. Is this possible?

    I suppose it'd be the URL of a line item.

    I'm adding a product to the basket with extended data (its actually form data that they fill in on the product page to customise the product). So I want users to be able to have an "edit" link from the basket page which will take them back to their customised product page.

    Thanks

    Ben

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jul 14, 2016 @ 21:22
    Rusty Swayne
    0

    The productKey will be in the extended data collection so you should be able to:

     var product = merchelloHelper.TypedProductContent([productKey]);
    
     var url = product.Url;
    
  • Ben McKean 272 posts 549 karma points
    Jul 14, 2016 @ 21:30
    Ben McKean
    0

    But will that take the user to the product page or the instance of the product?

    So in my example, the user will initially view a product page, on that page they'll add custom data to it. It's actually charity gifts, so users will add data to the product to add a personalised message. Then they'll add it to their basket.

    Then I want them to be able to click edit on the basket page that will take them back to their produc with their personalised message.

    Is that possible?

    Maybe I'm misunderstand but what is difference between the sku and product key?

    Finally, from the basket, is it possible to loop through each item in the basket (not line item)? As I want to have a row for each instance of a product in the basket.

    Sorry for the many questions!!

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jul 14, 2016 @ 21:49
    Rusty Swayne
    0

    It's probably me not understanding what you are entirely doing. How are you saving the "custom configurations" ... in the extended data collection?

    The Url will get you back to just the product page so if you have some sort of specific "state" you would need to pass other parameters.

    For the product "items"

        var products = basket.Items.Select(x => merchelloHelper.TypedProductContent(x.ExtendedData.GetProductKey()));
    
  • Ben McKean 272 posts 549 karma points
    Jul 15, 2016 @ 09:18
    Ben McKean
    0

    I'll try to explain again :)

    Here are the steps and what I'm currently doing at each step

    User visits a product page

    User adds custom data (for now I'm just adding a datestamp in the controller) and adds the item to their basket

    This will then go to my controller which will add the item with the custom data to the basket, this is how I'm doing it, button link first then controller code:

    @Url.SurfaceAction("AddToBasket", "BasketManager", new { productKey  Model.Key})
    
        public ActionResult AddToBasket(string productKey)
        {
            var merchello = new MerchelloHelper(false);
    
            var product = merchello.Query.Product.GetByKey(new Guid(productKey));
    
            var extendedData = new ExtendedDataCollection();
    
            extendedData.SetValue("ItemDate", DateTime.Now.ToString("F"));
    
            Basket.AddItem(product, product.Name, 1, extendedData);
            Basket.Save();
    
            var siteSettings = UmbracoHelpers.GetSiteSettings().As<ViewModels.Data.SiteSettings>();
    
            if(siteSettings.Basket != null)
            {
                return RedirectToUmbracoPage(siteSettings.Basket.Id);
            }
    
            return Redirect(CurrentPage.Url);
        }
    

    However the above only seems to add one item to the basket. When I view the same product page and try to add to basket again, it just overwrites the previous item. I want it to add a new item.

    Finally, on my view I want to loop through all of the items (not products) in the basket). Currently I do this but its just looping through the products:

                        @foreach (var item in customerBasket.Items)
                        {}
    

    But again, this is just looping through products and not items. I want to get a URL to go back to the item (or product instance)

    Thanks in advance

    Ben

  • Ben McKean 272 posts 549 karma points
    Jul 28, 2016 @ 09:29
    Ben McKean
    0

    Hi Rusty,

    Please could you help with this? Its starting to become a blocker for me

    Thanks

    Ben

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jul 28, 2016 @ 21:08
    Rusty Swayne
    1

    Hey Ben,

    I'm not sure why it would be overwriting the previous product, rather it should be changing the quantity to two ...

    The collection is SKU based, so unless you change the SKU, the item will always be viewed as the same item in the basket - so you will need to append something to the SKU to make it unique in the item collection.

    Storing values in extended data is just fine, but when you go back to the product page, it may be helpful to somehow pass the line item key (or the generated SKU) of the item in the basket so that you can retrieve the previously saved values in the extended data collection more easily.

Please Sign in or register to post replies

Write your reply to:

Draft