🪅Rules

Introduction

Rules in the Leclerc platform are written in JavaScript and can either return a boolean or an object.

  • Boolean rules tell if the participation is valid or not ;

return true; // Valid
return false; // Invalid
  • Object rules give the participation a number of chances to the IG (direct prize), to the TAS (selection at the end of the campaign), or to both.

return { game: 1, tas: 0 }; // One chance to the IG, but none to the TAS.
return { game: 0, tas: 1 }; // One chance to the TAS, but none to the IG.
return { games: 1, tas: 2 }; // One chance to the IG, and two chances to the TAS.

Please note that a single _false_** result** will set the participation as invalid.

return true;
return true;
return false;

= false; // Invalid

Also, although it isn't recommended for clarity purposes, object rules works the same way and multiples rules can award chances.

return { game: 3, tas: 0 };
return { game: 0, tas: 2 };
return { game: 1, tas: 4 };

= { game: 4, tas: 6 }; // Sum of chances

Finally, do not forget that a participation with no game chances ( { game: 0 } ) won't be able to play a game, which means customers with no chances won't see that page in the FOL.

---

Boolean rules

A first set of rules is related to the provider, in other terms, to where the customer is coming from.

// This rule only allows participations from the MonLeclerc app.
return provider.provider == 'Leclerc.Eshop.MonLeclerc';

// This rule means only customers without provider (stores/offline) can participate.
return (!provider.provider || provider.provider == '');

In some campaigns, only some shops will be eligible. For those, a list of shops must first be imported in the platform for the rule to work.

// This rule checks if:
// there are shops linked to the operation (a)
// the customer has a shop (from provider_data) (b)
// and if the shop is in the list. (c)
return (pdvs.length > 0 && helper.get('shopid') && helper.isEligiblePDV());

For online providers, many things can be retrieved, and evaluated from provider_data.

// Check if the customer has a loyalty card.
return !!helper.get('loyaltyCard');

// Retrieve order amount and check if eligible.
const amountHR = parseFloat(helper.get('totalCmdHR')) || 0;
return amountHR >= 30;

// Check if customer is valid (CIAM CCU is currently needed for online operations).
return (poke.segment && poke.segment == 'CIAM');

// Evaluate if we have enough info on customer.
return (!!helper.get('mail') || !!helper.get('accountId'));

// Or enough info on his/her order.
return (!!helper.get('cmd') && !!helper.get('date') && !!helper.get('basket'));

While much info can be accessed directly from the helper.get() function, some data needs to be retrieved either by a dedicated function or an API from the backend.

// Check if the order hasn't been played yet (max 1 participation per order).
// Please note that the verification is made on the item_uid field, which is the concatenation of provider and order number.
// Ex: leclerc.drive.infomil_0123456789
const orderParticipations = await helper.uniqueParticipation({ "selection": [["item_uid"]], "participation_type": ["normal"] });
return orderParticipations == 0;

// Check how many times a customer played already (max depends on the campaign).
// Check is usually made on user_uid (customer ID), source_type (provider) and order_at (order date for online and participation date for offline).
const userParticipations = await helper.uniqueParticipation({ "selection": [["user_uid", "source_type", "order_at"]], "participation_type": ["normal"] });
return userParticipations < 2;

Obviously, the few rules detailed above are only examples as the rules systems allows to merge items together, and some boolean rules can also be used in object rules. For example, a campaign can check if a customer has a loyalty card (mandatory - boolean rule, yes or no) or give an extra chance if he/she has one (optional, object rule, +1 or +0).

---

Object rules

While boolean rules allow us to block participations that aren't allowed, object rules are the ones that actually let eligible customers play. Indeed, even if a participation gets true to every boolean rules, it will still have { game: 0, tas: 0 }, which means no chances to play/win!

In some cases, allowing chances will be easy, as passing each of the boolean rules means you got one chance to the game, and then you can just type:

return { game: 1, tas: 0 };

But in most cases, chances are dynamic and based on the customer's order (order amount, eligible products, etc.), its info (loyalty card, account type, etc.), or codes he may have received in-store.

// ONLINE
// Check if the customer bought eligible products (EANs must be imported in the backend first)
// and give one chance to the game for each one.
const EANs = await helper.countEAN(cart, true).count;
return { game: EANs, tas: 0 };

// OFFLINE
// Give one chance to the game for each code a customer added.
const { evolutel } = await helper.countProof();
return { game: evolutel, tas: 0 };

In those rules above, we didn't give a fixed chances amount to the customers (as we did in the Introduction part), but the chances they got are directly based on their order/input, and that's the strength of the rules system has it accept any kind of rules based on any combination of the data we have, either from the order data, the customer data, its input or the other operation data we already have in the DB!

---

Test

Knowledge check: What is the result of this rule?

const EANs = 4;
const hasCarteFid = false;
const chances = 1 + (EANs >= 2 ? 1 : 0) + (hasCarteFid ? 1 : 0);
return (chances > 0 ? { game: chances, tas: chances * 2 } : false);

---

Triggers

We discussed the rules and their content, but an important part, if not the most, is their trigger. Indeed, rules can be evaluated at any step (aka "screen") of the operation, but you must always ensure that the data you need will already be available at that moment, or the customers won't be able to participate.

This rule is evaluated at the loading of the game page.

For instance, checks on provider_data can already be done on the welcome page, and they should be to avoid a customer going to game before getting a You cannot play! message, but you can't checks for offline codes before the page were the customer can actually enters them!

In some cases, you could also have customers that will skip some pages (if they don't need to accept opt-ins anymore, for example), so you need to take that into account when you write your rule. Should it be on page 2? Or on page 1? Or on both, maybe? It all depends on the operation and what is best for the customer.

---

Finally, it's not exactly a rule but is linked to them, the children creation.

Default children creation is on the game page.

The children creation is the process where the chances are actually "given" to the participation. In other words, if your rules says { game: 2, tas: 2 }, but you haven't got to the page where children are created, you basically have 0 chances.

The default for children creation is the game page as, if you have a game, you MUST have chances before getting to the game. But in some cases, you might want to create your virtual children earlier, or later. Also note that if you set your children creation on a page the customer won't visit (either because it's hidden or the customer skips it because of a page rule), children won't be created, so always be very careful of your setup and test it, many times!

Corentin, as of 17/10/2022.

Last updated