Copied to clipboard

Flag this post as spam?

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


  • Tarek 9 posts 29 karma points
    Jan 28, 2016 @ 06:38
    Tarek
    0

    Scenario Challenge: Headoffice ordering for Branch

    Hi Rusty,

    Hien Nguyen and I are working on a Merchello implementation that requires us to implement the following -

    We need a way for a headoffice user (Member with Property IsHeadOffice = true) to order products on behalf of a branch.

    This is main reason for Hien questions about setting the CustomerKey.

    Basically, headoffice user will log into Merchello and place an order for a branch.

    We have been trying a whole bunch of different ways to change the customer key on an invoice to be the branch office. We seem to be trying change the customer much to late in the process and this results in weird behaviour such as:

    • itemCacheService exploding when trying to delete the items from the cache (because the customer does not exist in the cache)

    • Invoice is not returned using invoice service until you clear the cache.

    Do you have any suggestions on changing out the customer key in a supported way?

    Regards, Tarek

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 28, 2016 @ 17:01
    Rusty Swayne
    0

    Hey Tarek,

    I've been trying to answer as best I can, but I don't understand why the logged in Member with Property IsHeadOffice = true does not have a Merchello managed customer. I assume it's just another member type in Umbraco that can be added to the merchello.config just like any standard customer and not something that needs to be managed after the fact.

    The only caveat to this, is if you are allowing the user to checkout anonymously (without logging in first) and then need to allow them to sign in after the transaction is complete in which case the invoice would have been generated and saved as an anonymous customer and would need to have the customer key associated with the newly logged in customer.

    If you are trying to associate more than one Member with a single Merchello Customer, I'd suggest writing your own CustomerContext which can be done by inheriting from the CustomerContextBase and implementing three pretty simple methods.

    In any case, the customer is rarely created manually. It is generally accessed through:

     var customer = CustomerContext.CurrentCustomer;  
    

    Then the basket is

     var basket = customer.Basket();
    

    The Sale preparation is (1.14.0 introduces the CheckoutManager to supersede this)

     var preparation = basket.SalePreparation();
    

    To checkout

     // This generates and saves the invoice and applies customer key if the customer is logged in.  Otherwise the invoice will have a null customer key
     var result = preparation.AuthorizePayment(...
    

    If your customer logs in after the payment

      var invoice = result.invoice;
    
      // save the invoice key into the Merchello cookie to persist between page loads
      CustomerContext.SetValue("invoiceKey", invoice.Key.ToString());
    

    Then log in the member which will update the CustomerContext.

       var customer = CustomerContext.CurrentCustomer;
    
        if (!customer.IsAnonymous) {
    
              var invoiceKey = CustomerContext.GetValue("invoiceKey");
    
              if (!string.isNullOrWhitespace(invoiceKey)) 
              {
                    var key = new Guid(invoiceKey);
                    var invoice = MerchelloContext.Current.Services.InvoiceService.GetByKey(key);
    
                    if (invoice != null) 
                    {
                          invoice.CustomerKey = customer.Key;
                          MerchelloContext.Current.Services.InvoiceService.Save(invoice);
                    }
              }
        }
    
  • Tarek 9 posts 29 karma points
    Jan 28, 2016 @ 21:06
    Tarek
    0

    Hi Rusty,

    Many thanks for replying.

    Just to clarify, the whole website is protected so everyone will to be logged in to access. There is no support for anonymous users.

    Our client provides company specific products so you must be logged in as Company X to see the products for Company X.

    However, some of these companies want their headoffice users to order to products on behalf of a branch.

    So headoffice user logs in ... products for Company X are displayed. They add 1 or more items to the cart and checkout.

    When filling out their billing address, they are presented with a dropdown containing all of the various branches (branches are Umbraco member called office and property IsHeadoffice = false). They select Branch 1 and proceed with checkout.

    Currently, the default behaviour will result in the invoice being created with the HeadOffice user attached to the invoice.

    We actually need the Branch selected in the dropdown to be attached to the invoice.

    I am happy to create CustomerContext, however, at what point do I need to switch out the default implementation? We store the dropdown value in session.

    Hope this makes more sense

    Regards, Tarek

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 29, 2016 @ 00:54
    Rusty Swayne
    0

    Hey Tarek - ok that makes more sense.

    To rephrase, if a member is logged in with a member type that has the IsHeadoffice property == true then that user has the ability to checkout as one of several customers that represent a branch.

    The quickest way I see to get this sorted is to create a mapping between the members "branch collection" and a customer which can be added directly through the back office (and not managed through the customer context).

    The trick there will be to make sure the email address (login Name) of the user is not used by any member in the membership provider ... so maybe a distribution/group email address ...

    Then, in your drop down to select the branch, use the mapping to find the loginName ...

     var branchCustomer = MerchelloContext.Current.Services.CustomerService.GetByLoginName(branchCustomerLoginName);
    
    // get the invoice as discussed above
    var invoice = MerchelloContext.Current.Services.InvoiceService.GetByKey(invoiceKey);
    
    invoice.CustomerKey = branchCustomer.Key;
    MerchelloContext.Current.Services.InvoiceService.Save(invoice);
    
  • Tarek 9 posts 29 karma points
    Jan 29, 2016 @ 01:11
    Tarek
    0

    Hi Rusty,

    We have tried something code like your recent post several times.

    We just don't know where to put it and get the following issues -

    1. We cant retrieve the record by the new customer key (event though Customer Key is correct in database. This seems to be a caching issues because stopping and starting the site fixes the issue.

    2. We get an error in SalePreparationBaseOnFinalizing when calling this itemCacheService.Delete(itemCache); It seems to try and find something in the cache using the logged in user customer key .. but we switched it out using the code you described earlier so the method tried to delete a null item.

    Also, I did create CustomerContext and got it to load .. however, it didn't really do anything because CurrentCustomer is always the logged in user. Was to scared to override it because i find out what customer to use right at the end.

    Regards, Tarek

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 29, 2016 @ 03:48
    Rusty Swayne
    0

    I tried to explain the ItemCache delete in a previous post. What I believe is happening is you are managing a customer outside of the CustomerContext and still using the Basket -> SalePreparation process to manage the checkout workflow. So essentially you have two different customers that somewhere in your specific application code is causing an issue with the customer relation.

    Said another way, the Basket and SalePreparation objects are very much tied to the CustomerContext and by circumventing that things are getting muddled.

    If the code where you are creating the customer and allowed the checkout to complete as designed, this would remove that issue.

    Ironically, handling the SalePreparationBase.Finalizing event would be a really good place to do your CustomerKey swap - but you would have to somehow store which branch was selected (if any at checkout). I noticed you were already using the Session object - maybe just shove the branch selection there?

Please Sign in or register to post replies

Write your reply to:

Draft