Automatic discount based on customer discount-level with set amounts per product

I would like to setup automatic discounting based on customer discount-level (a customer custom field), where each product has fixed discounts depending on this level.

For example:

The customer entity has a custom field Discount-level, which can be level1, level2 or level3.

Each product has three custom tags:

  • level-1-discount
  • level-2-discount
  • level-3-discount

This tag contains the exact amount to be discounted from the product price depending on the customer’s discount-level.
If the tag is empty or zero, it means no discount.

I would also need to be able to track these discounts in accounting and custom reporting.

Can anybody point me to how I best implement this (and whether it’s even possible)?

I have read several of the discounting tutorials, but haven’t seen anything that seems to be suitable for this.
One thing I’m worried might be a problem is when you first add orders to the ticket and then select/change a customer, you would have to change the discount for orders already on the ticket.

EDIT: Here’s the solution, provided by @emre:

Add a custom field Discount to your Customer entity

Fill in this field for your customers (Under Entities/Entities).
D1: first discount-level
D2: second discount-level
D3: third discount-level

Under Ticket/Order Tags, click Add Order Tag Group:

Add these order tags:

Under Program Settings/General Settings, add these Custom Product Tags:

Under Products/Product List, for each of your products, fill in these three custom tags:

D1: amount or percentage of discount for this product if customer’s discount level is D1
D2: amount or percentage of discount for this product if customer’s discount level is D2
D3: amount or percentage of discount for this product if customer’s discount level is D3

Add the following actions under Automation/Actions:

Add the following rules under Automation/Actions:

Discount Name: {ENTITY DATA:Customer:Discount}
Discount Value:
For amount-based discount: [=-1*(TN(’{QUANTITY}’)TN(’{ITEM TAG:{ENTITY DATA:Customer:Discount}}’))]
For percentage-based discount: [=-1
TN(’{PRICE}’)*(TN(’{ITEM TAG:{ENTITY DATA:Customer:Discount}}’)/100)]

Note: You need V4.1.75 or higher for this to function properly. Some issue with refreshing of the ticket was resolved in that version.

Here’s an import file for all the actions & rules and the order tag group: (1.4 KB)
(You still need to do the first 5 steps manually, except for the order tag group)


It should be doable…

We have access to Ticket Entity Changed rule event.

I know, but then how do you retroactively change the discount for orders already added to the ticket?
That is, when using order tags anyway.
When using calculation types, it will work for orders already added, but that only works for a full ticket discount, not for individual order discounts.

Good question I would have to build this and play with it.

1 Like

I think this would be a very nice way to do discounting.
I don’t want my cashiers to decide what discount to give to customers, that’s not their task. I want the discounts to be based on the type of customer, so the only thing the staff needs to decide is who the customer is, and the system will be setup to decide automatically what discount is appropriate based on type of customer (regular/student/staff/owner/friends/etc), loyalty(how many visits before/total amount spent) and such.
At the same time I also don’t want a discount applied on the whole ticket value, since some items have a bigger profit margin than others, so discounts shouldn’t be the same for each type of product…

I have long pondered this myself. My regular customers get discounted prices on several products, so what I ended up doing initially was to create duplicate products (with lesser prices) and have a VIP menu Category. The issue with this of course is that the staff needs to know who gets to order from the VIP menu, and who doesn’t - not a big issue here since I have a small operation, and this is the setup that I still use today.

My original go at this was to try to use Price Definitions, and change to the VIP Price Tag when a customer was selected, but then it would not revert back to the Regular Price Tag, and it also conflicted with the Happy Hour triggers and HH Price Tag. It was @emre that pointed out that Price Definitions were not intended to be used this way, and that’s why it wouldn’t work the way I wanted.

Then I though of using Product Tags, but as you mention, you either need to select the Customer first, or you need to devise a way to cycle through the Orders to retroactively apply/remove the discounts when the customer Entity is selected afterwards, or is changed, or is removed. I am convinced this could be done, but I haven’t researched it any further yet… I think this would be a great mechanism to build that a lot of people would want and use immediately.

I look forward to seeing what you come up with! :stuck_out_tongue_winking_eye:

1 Like

I’m trying to find something, but I’m not very optimistic.
The closest I could find until now is this:

I imagine this also won’t help much, because than we would need different order tags for each specific amount of discount and also a way to loop through these tags. Plus we wouldn’t be able to get the values from the product tags either…

Right now all I can think off is some new functionality, which already a few times I’ve considered to be something that would be very useful:

  • a Loop through ticket orders action
  • a Order reached in loop event, where we can update (or delete) the order based on order, ticket and entity values

I know @emre has considered something like this, I’m interested to know what happened with that…

I am thinking we need to make it apply the discount only when we know for sure customer will not change… We can prep it and have it flagged already as getting the discount but not actually apply it until we are 100% sure it needs to be… This might be able to be done with States… We can easily make it display a price without making the actual calculation… maybe a combination of this somehow might work. I am going to build this it has really gotten my interest but I am out of town right now when I get back ill start.

1 Like

Umm, what??? That sounds like exactly what we want! Now I’m very curious…

Ok, I’m losing my mind now… I cannot for the life of me get the CustomData Field to appear for a Customer

But no problem for Employee Entity …

Has to be something you missed because other than name there isn’t anything different. Is there something in the type?

Strange, it must be a caching issue. If I create new Customer via POS, I still can not see the new Field, but if I create a new Customer Entity via Manage, the new Field appears.

In order to EDIT an existing Customer Entity, I need to change the Entity Type to something else (i.e. Table), then switch back to Customer, and the Field magically appears…

1 Like

@Qmckay, I think by Update Order Tag, @emre probably meant Update Order Tag Price and Update Order Tag Quantity actions.
I suppose (I might be wrong though) this just changes the price for a specific tag to a fixed amount that you give the action, and then updates the whole ticket to show the price change.

I don’t think this would help for this case because

  • you would need to have a new order tag for every specific discount amount that you have for each product
  • then you would need a way to find out in your Ticket Entity Changed rule which order tags exist in the ticket
  • then you would need to have a way loop through these order tags and update each tag price individually
  • you would also need a way to get the right price for each order tag from the Product tag for the order

Unless you can think of another way to do it or I’m just seeing it wrong…

I like @Jesse’s suggestion to just read the amounts first and apply them later…

I’m not sure if this is exactly what you mean @Jesse, but I’m thinking like this:

  • whenever an order is added to the ticket
    – you get the amounts for each discount-level, and add them to a program setting or ticket tag
    – if there’s already a customer entity linked to the ticket, you apply the appropriate discount to the ticket, based on the customer’s custom data
  • whenever an order is removed from the ticket
    – you get the amounts for each discount-level, and distract them from the program setting or ticket tag
    – if there’s already a customer entity linked to the ticket, you apply the appropriate discount to the ticket, based on the customer’s custom data
  • when the Ticket Entity Changed event is fired:
    – if there’s a customer entity, you apply the appropriate discount to the ticket, based on the customer’s custom data
    – if there’s no customer entity (the customer has been removed), you discard any ticket discount that was already there

Does this sound about right?
Or were you thinking of an even better way where you can actually have the discount applied to each order instead of the whole ticket?

I capture Order Added Event, and fire Tag Order or Update Order Tag, but it isn’t working so far, though the data is there…

What’s Update Order Tag? I can’t see this in my action list.
Do you mean Update Order Tag Price?

@pipo that is similar to what I was thinking. I still have not had time to look into it.

1 Like

Yes, I meant Update Order Tag Price. Scratch what I said, I have it working to add the discount based on level…

This item is regular 60 but at Customer DiscountLevel 1, it is discounted by 10 as defined by Product Tag D1…

Product Tags D1, D2, D3:

Customer DiscountLevel 1:

Order Tags:

Action - Tag Order:

Rule - Order Added to Ticket - Tag Order:


I see you immediately found a good use for that feature @emre forgot even existed before :smile:


Strange, I just tried your setup, but for me it’s not even showing {ENTITY DATA:Customer:Discount-level} in ShowMessage…