Wholesale and Tagging

This here is the place where all things wholesale and customer tagging that the UK team are getting the AU team to build will be defined in February.

Continuing the conversation from:
Enterprises can create and apply custom ‘tags’ to products and variants
Tagging for Products and Customers
Customers can be ‘members’, ‘volunteers’, ‘staff’ etc
UK Backlog
Build customer accounts interface (for enterprise user)


Customers can currently be tagged, which allows for information about customers to be used in some reports, but that is about all. There is lots of room for leveraging this feature to do more useful things, especially on the shopfront.

Customer Tagging

In the shopfront

Most of the discussion has been around the use of customer tags to tailor the shopping experience.

  1. Alter prices (eg. discounts for members, volunteers, staff)
  2. Change product visibility in the shopfront, such as wholesale/retail, or member only products (this would probably require Variant tagging to be implemented as well) - (Or when we have inventory lists this may be a better solution/we could just tag a list)
  3. Make different payment / shipping methods available (eg. make ‘Store Credit’ an available payment option for trusted customers)
  4. Restrict access to the shop (eg. private, member-only shops)
  5. Application of different enterprise fees for different customers

In The Backend

There have also been elements to the discussion around making customer tagging useful in the backend as well:

  1. Delivery runs (I need to some help with fully understanding how this would manifest)

Product/Variant Tagging

There is at least some crossover here with limiting availability of products in the shopfront, so I thought I would at least mention other possibilities that have been raised around tagging of products / variants:

  1. Providing more detailed information about products / variants on the shopfront using arbitrary tags like ‘leafy greens’, ‘high in antioxidants’, or ‘in-season’. See discussion here. We can allow enterprise to have control over defining and applying these.
  2. Using tags on variant-overrides to filter inventories (when we actually have them) (eg. buying groups can use a single shared inventory, and only load products tagged ‘wholesale’ or ‘retail’ from that inventory into their shopfront, depending on their preference)


  • The administrator can see and define and apply tags.
  • With discounts applied through tags, do you want the shop showing the full price and then members getting a discount after logging in at checkout. Or do you want to see the discounted price with a fee applied after you checkout as a non-member. Or do you force ‘login’ to a shopfront before you can even browse.
  • Customer tags should be hub specific.
  • Could we create ‘zapier -like’ rules. E.g. if customer XX shops at XX hub and has XXX tag then apply XX discount.
  • Do customers see their tags?
  • When are promo codes suitable? Can they handle % discounts and $ discounts. Do they expire? Can you have >1 code?
  • Is a standing order a kind of tag? Can holiday leave from a standing order be a tag?
  • If we have lots of tags (on products, cusotmers and delivery runs, we need to make sure we know how they’ll interact.
  • Is there an alternative to tagging that is better?
  • If tags are used for multiple purposes they risk becoming interwoven and confusing.
  • Can tags expire (Bondi lets people place one trial order, to see if they want to join)?

Hi all! The plan is to run this along the following lines:

  1. Gather requirements (information and discussions already held on the topics on Discourse/GitHub, talking with enterprises like Stroudco and Food Connect about what they’d like and any problems they have in managing wholesale now, etc).

  2. Brainstorm on the features and functions to be built, based on all the knowledge gathered of what people want and how they’ll use it.

  3. Develop a backlog of estimated development tasks that has been prioritised (to be done with current funding; to be done at a later date). And a plan of when this first round of work will be done.

@Sara - @oeoeaio @sstead will be working on the defining of scope with you in the next couple of weeks.

@NickWeir and @lin_d_hop and @pmackay - you guys are very welcome to get involved or to watch the progress on this page and contribute.

@serenity - any inputs or insights from the Food Connect perspective can go here as well.

Happy speccing :smiley:

@Sara, we were wondering if you were available for a Skype chat next week? Here are the dates/times that @sstead and @oeoeaio are available, let us know which of these works best for you:

Wednesday 10 February:
Option 1 - 8am Melbourne time / 9pm UK time
Option 2 - 7pm Melbourne time / 8am UK time

Friday 12 February:
Option 1 - 8am Melbourne time / 9pm UK time

If you can choose one of these, then we will organise the logistics!

Cheers :smiley:

Best for me would be Option 1. I’ll see if I can get Oliver at Stroudco to join us too

I’d love to listen in as Stroudco too is developing a wholesale arm. However, I have used OFN too little so far to make concrete suggestions.

@oeoeaio @sstead @Sara here are some of the whiteboard write ups from our sessions today. Rob will be using them and his big brain to update this wiki page with a proposed solution for us all to review.

Pinging @danielle, @Sara, @sstead, @lin_d_hop, @Olivier, @NickWeir



This is my current understanding of what is required based on my reading to date and discussions I’ve had this week with @Sara, @danielle and @sstead. If anyone has any reservations, thoughts or alternative proposals, let me know. I’m still trying to work out a vague estimate for all of this work, as you can see it’s a massive job.

There are lots of elements to this, but we think we have come up with a way of providing most of the features we are looking at in a relatively cohesive package. In keeping with our existing design principals, we tried to design a system with the potential to allow a high degree of flexibility for power users, but which hides complicated functionality for new / inexperienced users by default and has simple initial iterations for proof-of-concept.


Our thinking to date has narrowed in on an expansion of the tagging system found in the customers interface, allowing tags to also be applied to shipping methods to begin with for a proof of concept, then to variants (in the inventory, rather than globally), outgoing exchanges in order cycles (essentially a shopfront instance) and payment methods, and then potentially things like fees at some point in a future iteration.

In and of themselves, tags on customers, variants or outgoing exchanges would have no effect whatsoever on the behaviour of those objects. This would allow tags to be used for simple information management if that is the desired use case.

The way that we propose to implement the functionality that we are looking at around customisable user experiences in the shopfront is to have a set of “Tag Rules” defined at the enterprise level that describe the effects that tags have when they are applied to customers, variants, and outgoing exchanges. This is very much going along the Zapier path of having a defined (yet highly extensible) set of options for describing interactions between tagged objects.

As a first phase, the idea would be to build a few desirable “pre-canned” (simple and work “out of the box”) rules that apply to a named customer tag, with the understanding that more complex rule types could be added later on. Rules would be grouped by the tag on customer for readability.

I’ve identified five basic rules types that I think cover the most commonly requested use cases (let me know if you think something should be included or excluded):

  • “For customers tagged X: hide order cycles tagged Y”
  • “For customers tagged X: show order cycles tagged Y”
  • “For customers tagged X: hide products tagged Y”
  • “For customers tagged X: show products tagged Y”
  • “For customers tagged X: give discount of X%” (or $X)

Basic wireframe:

I propose that we do this work in a couple of phases, to give us a chance to look at what we’ve built and make sure we are going down the right path. There is a bit of background work that I propose we do before actually implementing tagging and rules.

Phase 1: Basic infrastructure + Proof Of Concept Rules

Adding the bare minimum set of features required to test that tagging is going to be an effective way of defining rules about customisation of shopfront experience, plus some very simple rules to prove the concept.

  • [Feature] Enterprise user can require login for their shopfront and display a message to users who are not logged in.
    • This feature has come up in this discussion, but is not itself dependent on tags and is not overly complex, I say we build it and get it over and done with.
  • [Feature] Allow enterprise users to manually create customers for their hub (without that customer necessarily having to place an order with the hub first)
  • Routing, views, controller actions for creating customers
  • Logic around what to do when a user with the given email does not yet exist
    • Add the customer anyway, so that tags can be added
    • (Optionally?) Send an email to the address provided, suggesting they create an account
    • Associate customer with user when it is created?
      • what is the benefit of this?
  • [Feature] Enterprise user can shipping methods
  • Add acts_as_taggable_on to shipping method model
  • Add tagging input to shipping method edit interface
  • [Feature] User can manage tag rules to apply two basic rule types to their shopfront: whole order discounts for certain customers and availability or otherwise of shipping methods for tagged customers.
  • Design and build the model that will contain information about which rules apply and how they are applied to the shopfront.
  • Add “Tag Management” or “Tag Rules” tab to Enterprise edit interface
    • Basic version allows user to create new rules, edit them, and delete them
  • To begin with will aim to support three basic rules types:
  • “For customers tagged X: give discount of X%” (or $X)
  • “For customers tagged X: prevent use of shipping method Y”
  • “For customers tagged X: allow use of shipping method Y” (eg. could show “Free shipping” for #local customers)
  • [Feature] Rules defined by the user have their intended effect in the shopfront
  • For discount rule this applies when products are added to the cart
    • Need to investigate whether Spree’s existing promotions infrastructure could be useful, though I suspect that getting this to work may be more trouble than it is worth…
  • For shipping method availability rules, this just applies on the checkout.

Phase 2: Wholesale and Usability Improvements

Some additional user experience improvements will be necessary after the initial round to make tagging useable and intuitive. This phase will also introduce six new rule types for use by shops that want to offer wholesale functionality by showing/hiding products and/or whole order cycles, as well as offering different payment terms to customers based on tags.

  • [Feature] Tag assignment interfaces (on customers, variant overrides, order cycle exchanges) expose information about which tags are affected by rules, with links to view/edit rules.
  • [Improvement] Other as-yet-unknown improvements to usability that come out of phase 1.
  • [Feature] Enterprise user can tag variants in inventory
    • Add acts_as_taggable_on to variant_override model
    • Add tagging input to inventory interface
  • [Feature] Enterprise user can tag outgoing exchanges
    • Add acts_as_taggable_on to exchange model
    • Adding tagging input to existing interface
  • [Feature] Enterprise user can payment methods
  • Add acts_as_taggable_on to payment method model
  • Add tagging input to payment method edit interface
  • [Feature] User can manage more types of tag rules for implementation of “wholesale functionality”.
  • Add support for six more “pre-canned” rule types:
    • “For customers tagged X: hide products tagged Y”
    • “For customers tagged X: show products tagged Y”
    • “For customers tagged X: hide order cycles tagged Y”
    • “For customers tagged X: show order cycles tagged Y”
    • “For customers tagged X: prevent use of payment method Y”
    • “For customers tagged X: allow use of payment method Y”
  • [Feature] Rules defined by the user have their intended effect in the shopfront
  • For order cycle rules, these apply when the shop page is loaded
    • Do we want some intelligent logic around which order cycle gets loaded when a choice is available and we have additional information about customer type via tagging?
  • For product/variant visibility rules, these apply when the shop page is loaded

Phase 3: Cover more of the most requested use cases for customer tagging

  • Build a rule creation wizard
  • Add basic rules for payment method availability
  • Add rules about how fees are applied
  • Add more complex rule construction capabilities for power users eg. “For customers tagged W, apply a X% discount, on products tagged Y, for order cycles tagged Z”


Thank you for all your work on this Rob. The Stroudco team is happy with your proposal and has nothing to add. Thanks

@oeoeaio Two things that seem to be missing from the canned list:

  1. Free shipping (to cover the ‘local’ scenario that @Sara raised)
  2. Discount on a product (to cover when only particular products in an OC are discounted for particular customers).

@NickWeir and @Sara - they should be included too?

Yes please …

Me too! Also if we can get the first bit of Phase 1 i.e. the shopfront login done as a pre-phase 1 that would be a quick way to perhaps get this up and running with the system as is? Also a thing to add on the customer record would be the company name i.e. the name of the cafe, restaurant, shop which was ordering.

Well done, this is great @oeoeaio ! Sounds like a great solution that will encompass lots of stuff!
Dani, these work arounds might suffice… For free shipping, just have a ‘free’ shipping method ‘show’ for a particular customer tag.
For product specific discounts, you can have two variants, the full priced one showing for ‘tag1’ and the discounted variant showing for ‘tag2’.

@Sara we’ve picked up this work and will be working on phase 1 this month. @oeoeaio is doing the rules design and development, while @maikel develops the first 3 features. All going to plan you’ll have these by the end of the month in release v1.6:

We are excited about this. Please let me know what you want me to test and when

@Sara @NickWeir @pmackay @Oliver @danielle @sstead

The first cut of the bulk of Phase 1 is now in the branch named tags-phase1 in the main repo. If you want to have a look at what is there, feel free. I am away for 10 days from this coming Tuesday and I get back on the Friday that 1.6 is released. At this stage I have a couple of tweaks that I would like to add to my branch but it will basically be released as is unless I hear anything urgent back in the next day or two.

###What is done

  • Shipping methods can be tagged, and those tags used to define rules.
  • Three rule types available: 1. Apply a percentage discount, 2. Show shipping methods only for certain customers, 3. Hide shipping methods only for certain customers
  • Tag Rules can be created, updated and deleted from their very own tab in the Enterprise edit interface.
  • Rules seem to actually work (yay!) Let me know if you find anything to the contrary
  • Maikel is working on a separate branch to implement the logged-in only shopfront functionality, this will be merged in later

###What is not done (and will not be done this sprint)

  • We axed the task to allow enterprise users to create a new customer from scratch, mainly because I ran out of time this sprint and it seemed like the least urgent feature.

###What I am going to try to fix by Monday

  • Cart part does not show an item for discounts applied using tags (displayed total is correct)
  • Tweak UI for shipping method show/hide rules to allow shipping method tags to be specified independently of customer tags (the model already allows for this but I put off the design challenge of building a UI to handle it)

Testing notes. I’ll start with things which I think are not quite working as we would eventually desire. Then list some general observations.

  • It seems that the system only recognises me as a tagged customer if I login before I start shopping. If I login halfway through, or when promted just before checkout, it still treats me as a guest (no tags). Also if I select to checkout as a guest, but then type in my recognised customer email (with tags) it will continue to treat me as an untagged guest.
  • Can we make it so that spaces are ignored in tags? And make them upper/lower case insensitive? I typed in a tag, and hit space, thinking it would apply the tag, it didn’t, so I hit enter. Then one tag was “wholesale_” and one was “wholesale” and they didn’t work together. Similarly “wholesale” and “Wholesale” aren’t considered the same tag.
  • To prevent people applying conflicting tags (ie make shipping visible and make shipping invisible for the same tag, could we have it so that once you’ve selected a tag rule, it can’t be chosen a second time. (I found when both visible/not visible is applied the shipping method is not visible).
  • Can we make it more clear in the Tag Rules that if you set up a rule for two tags (such as ‘wholesale’ and ‘member’) that the rules will apply to customers tagged EITHER of the tags, not BOTH.
  • Tax seems not to be calculating on the discounted price…

    and the tax report isn’t capturing discount
  • I think a few extra words might make these rules clearer…
  • Reports may not quite be displaying discounts correctly.

    General comments:
  • Shipping fees and enterprise fees are not discounted by a tag rule.
  • You can apply negative discounts (a markup)

Testing notes from G#871 (duplicated here for users without Github)
The ‘shopfront requires login’ setting is working :slight_smile: potential rephrase of info tab…

If a shopfront requires login, this is the landing message… I think it could be made a bit more friendly (and not red, red is a angry colour :P)? But I assume this is just a placeholder text, and eventually the message will be customisable by the enterprise? In which case this message is fine for now.

The only issue I’m seeing is that ANY user can login to see a shopfront currently. It’s not yet limited to customers on the enterprise’s customer list. I can be a user that’s never shopped at that shop before. Or I can be a new user and register with any email and then see the shop (that email isn’t confirmed at any point). Lets restrict this to customers on an enterprise’s customer list.

@sara and @NickWeir, the work for #849 in Github, that is the functionality for logging in to the shopfront to view it, is ready for you to look at on our staging1. @maikel / @sstead can one of you please provide them with a link so that they can see how it works? It will make it easier to then understand Sally’s testing notes.

Ta :smiley:

The ‘shop requires customer to login’ feature is staged on https://staging1.openfood.com.au/

You can view a shopfront there: https://staging1.openfood.com.au/demo-hub/shop

A customer that is allowed to view the shopfront has these login details:
customer@example.org hugo21

An enterprise user that can change the settings of that shop has these:
enterprise@example.com hugo21

As enterprise user, you can login, hover over the gear sign, click Administration. Then you can click Enterprises, select Demo Hub and change stuff.

@sstead: Sorry I deleted your post because I don’t want your login details public, because you can login with these on several servers. I don’t want random people doing destructive things with your account. The ones above will be deleted when we deploy the next thing on staging1.

1 Like

@sara and @NickWeir: Did you have a chance to test the require-login on staging1?