1

I'm making from scratch the website of my agency, an online food order and delivery service.

I'm trying to improve at best the promotion system: every restaurant has its own promotions, and some of them has a certain priority above others.

For example, if the client orders three pizzas and for every ordered pizza there is a free can the site will suggest a big bottle instead of three little cans. There may be more types of promotions:

  1. if your order is higher than a threshold, you will get something for free (e.g. if order is more than 20$, you get one free beer);
  2. a certain product has something for free associated, even if you order only one of it (e.g. one free beer for every sausage and pepperoni pizza);
  3. if you order a generic product belonging to a precise category, you get something for free (e.g. every ordered pizza you get a beer for free, no matter the type of pizza you order);
  4. if you order more than one product, you get something for free (e.g. if you order more than one pizza or more than one kebab, you get something for free).

Some restaurants provide only one of the four promotions above, or a combination of them: some of them may conflit each other.

The old website was a mess, a pyramid of doom of nested if and they want me to make it better and easier to handle (insertion and removal of promotions must be easy).

I'm trying to recall what university left me, and I thought about Deterministic finite automata (DFA): the grammar would be the rules of precedence in considering promotions, the tokens of alphabet would be the dishes and the free products, the language would be the set of possible promotions. But:

  • every restaurant would have its set of promotions, i.e. its grammar, its DFA (it may be an overkill to develop a DFA for such a small set of free products);
  • grammar design may be hard (some promotions might conflit with some others if a restaurant offers more types of promotions; furthermore, the precedence of some promotions over others may be hard to design with grammar rules and easier to describe with some "weight" concept).

What would be the more appropriate algorithm / data structure to use in these cases?

2
  • 2
    "insertion and removal of promotions must be easy" - easy for an end user, or easy for a programmer who maintains the system?
    – Doc Brown
    Commented Aug 24, 2017 at 10:57
  • For us programmers: we add a new restaurant at least once a week; plus, restaurants change their promotions.
    – elmazzun
    Commented Aug 24, 2017 at 11:01

2 Answers 2

5

What you probably need is called a Business Rule Engine. That may sound more sophisticated as it is, you will probably don't need some overdesigned generic rule engine with a 100K$ rule management system. A simple system with the rules stored in a tabular form, including

  • the rule type
  • parameters to describe the precondition for the specific promo
  • the promo item(s) itself which are granted by this rule

and a specific interpreter for these rules should at least solve 80% of your problem. For example, the preconditions can define which product or category or price limit invokes the promo. There may by als preconditions where already granted promo items from an earlier rule block granting another item.

The idea should be to have one of these tables for each of the restaurants, and to apply the rules one after another to any order, with a set of promo items as output. The order of the rules in the table might be enough to control their precedence.

You will probably have to add some postprocessing rules for grouping promo items together (like your initial three-can example), not granting the same item more than once, or for solving other conflicts. The postprocessing rules might be added to the table above as well, but if they are too complicated to be solved in a generic fashion, just make a postprocessing rule SpecialProcessingRestaurant_Foo and implement the specific code for restaurant "Foo" in there.

That should reduce the individual amount of code you need for each restaurant not to zero, but to a minimum. Since you don't have the requirement to let non-programmers manage the rules, I guess that might be suffient for your case.

2
  • Thank you, I'll propose it to my collegue and see if we can achieve something. Since we two use PHP, I just found out about Ruler rules engine: might worth a shot.
    – elmazzun
    Commented Aug 24, 2017 at 11:51
  • 1
    @elmazzun: note when I wrote this, I had a interpreter in mind which is most probably simple enough you can implement it easily from scratch. But if you find some generic 3rd party component which is appropriate for you, go ahead.
    – Doc Brown
    Commented Aug 24, 2017 at 12:42
0

This works if you are willing to implement a gui/database modell to manage the promotions.

I have implented a java class Promotion that contains

  • special invisible cart-Items "PromotionAdvantage"
  • a list of one or more PromotionExpressions-s each returning true or false.

THe Promotion engine tries to find the Promotions where all expressions are matching and applies the advantage to the cart.

A promotion might look like this

  • Promotion name "free bottle of wine"

    • PromotionExpression: RestaurantPromotionEpression("Kreta-Nyc", "Samos-La")
    • PromotionExpression: MinValuePromotionEpression("20 USD")
    • PromotionExpression: CartContainsProduct("Giros Pita", "Souvlaki")

    • PromotionAdvantage: FreeGiftPromotionAdvantave("free bottle of wine")

    • PromotionAdvantage: RefundPromotionAdvantave("0.99 USD")

    • allow more Promotions: false

so the customer get a discount of 0.99 usd and a free bottle of wine if the order comes from the paricipationg restaurants "Kreta-Nyc" or "Samos-La" has a total of at least 20 USD and the order contains at least "Giros Pita" or "Souvlaki"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.