Console

Web admin console manuals (CMS, Marketing, Kiosk, Employees).

Getting started

Signing in, your profile, finding your way around, and why you see what you see.

Getting started

Signing in

Audience: anyone using the console for the first time.

Signing in

You sign in with your employee identifier — the same one your company uses for you, not an email address — and your password.

If you don't have a password yet, you cannot create one yourself. Someone with employee management rights sets it for you; point them at Employees - Password.

Two things the console may tell you at sign-in

Your account has an expiry. Employee accounts expire, and as the date approaches you are told how many days remain. This is a warning, not an error — you can still work. Ask whoever manages employees to extend it before it runs out, because once it does you cannot sign in to ask.

Your password may be flagged as weak. If it doesn't meet the strength rules you are told so, and you should change it — see Your profile and password.

Neither message blocks you. Both are worth acting on the day you see them rather than the day they become a problem.

If you can't sign in

Work through these in order:

Check What to do
Is the identifier right? It is your employee identifier, not an email
Do you have a password at all? A new employee has none until someone sets it
Has your account expired? Ask for it to be extended — you can't do this yourself
Right customer/environment? The console is per customer; confirm you are on the right address

If all four are fine and it still fails, ask whoever manages employees to confirm your record exists and is active — see Finding an employee.

After you're in

Getting started

Your profile and password

You need: nothing beyond being signed in. Your profile is your own record.

What your profile shows

Your own details as held in your employee record: your identifier, name, and contact details such as email, phone, city, address and date of birth where they are filled in.

It is a view of your record — the same record an employee manager sees in the Employees area, from your side.

If something here is wrong, you generally cannot correct it yourself. Ask whoever manages employees — see Editing an employee.

Changing your password

You can change your own password whenever you like, and you should if it was assigned to you by someone else.

The rules are narrower than most systems, so read them before choosing:

Rule Value
Minimum length 8 characters
Maximum length 10 characters
Must contain At least one uppercase letter

The maximum is the one that catches people out. A long passphrase will be rejected — you need something between 8 and 10 characters with at least one capital.

Within that, favour something unpredictable over something memorable-but-guessable, and don't reuse a password from elsewhere.

If you're told your password is weak

The console flags a password that doesn't meet the rules at sign-in. That flag doesn't lock you out, so it is easy to ignore for months.

Change it when you see it. It takes a minute and you already have the screen open.

If you've forgotten it

There is no self-service reset. Someone with employee management rights sets a new one for you — see Employees - Password. They cannot tell you your old password; they can only replace it.

Getting started

Finding your way around

Audience: anyone finding their way around for the first time.

The areas

The console is organised by what you are doing, not by which team owns it.

Area What you do there Chapter
Hub Work live orders: assign, cancel, log incidents The Hub: what it is and who can do what
Delivery Configure how orders get assigned: zones, carriers, stores, the dispatcher What the dispatcher does
Marketing Issue promotions, vouchers, subscriptions, wallet credit Marketing: the five areas
CMS Maintain content customers see, and the complaints tree CMS: what it covers
Reports Read performance data Reports and Metrics: which to use
Metrics Investigate a specific order Order logs and timelines
Employees Maintain staff records and drivers Employees: what this area covers
Roles Decide who can do and see what Roles and scope: the two ideas

You will not see all of these. The menu reflects what your roles allow — see What you can see, and why.

Brands

If your company runs more than one brand, most screens work within one brand at a time and offer a brand selector. With a single brand, the selector usually doesn't appear at all.

This matters more than it looks:

Check the selector before creating or changing anything.

Live versus historical

A recurring distinction across the console, and choosing wrongly wastes the most time:

You want to… Go to
Act on something happening now Hub
Understand something that already happened Metrics
See how a period went Reports
Change how things will behave Delivery, Marketing, CMS

Language

The console is available in more than one language, and the documentation exists in parallel: every page here has a twin in the other language.

Note that content language is separate from interface language. Banners and documents are stored per language and must each be filled in — see Resources and sources.

Two pages worth bookmarking

When a screen isn't there

An area missing from your menu is almost always a permission, not a fault. What you can see, and why explains how to tell, and who can change it.

Getting started

What you can see, and why

Audience: anyone wondering why their console looks different from a colleague's.

Two separate things decide what you get. Almost every "why can't I…" question is one of them.

Decides Set by
Your roles What you can do Whoever manages employees
Your scope What data you can see The same person, separately

They are independent. You can have full rights over a narrow slice of data, or read-only rights over everything.

Why a menu item is missing

Because your roles don't include that area. The console shows what you can act on; it doesn't list things and then refuse them.

If you need an area, ask for the role that covers it — the catalogue is in The role catalogue, and most real jobs are two roles combined rather than one perfect fit.

Why you see fewer rows than a colleague

Because your scope is narrower. Scope filters every screen to the brands, stores and sources you are allowed to see.

This is expected behaviour, and both of you are seeing the correct answer for yourselves. A store manager's report should differ from a regional manager's.

This is the single most reported "the report is wrong", and it usually isn't. See How scope works in practice.

Why you can do something in one place but not another

Because permissions are granular. Being able to view orders in the Hub does not mean being able to cancel one; those are separate permissions, deliberately, so that critical actions can be given to fewer people.

Access by section is the full grid of who can reach what.

Getting something changed

You need Ask for
A whole area you don't have A role — The role catalogue
One specific ability An individual exception — Individual permission exceptions
To see more data A wider scope — Setting an employee's scope

Whoever manages employees can do all three. A brand-new role definition is rarer and goes through a request — see Requesting a new or changed role.

Before you ask

Check whether it is scope rather than permission: can you see the screen but not the data, or not the screen at all? The first is scope, the second is a role. Saying which saves a round trip.

Delivery & Dispatcher

How automatic order assignment decides which driver or carrier delivers which order, and how to configure it.

Delivery & Dispatcher

What the dispatcher does

Audience: Operations and dispatch managers who configure, supervise, or explain automatic order assignment to their team. Purpose: Understand what the dispatcher does and why it makes a given decision.

The Dispatcher is the system that automatically decides which driver (or external carrier) delivers which order, and when. It runs on its own, on a schedule you control, and re-evaluates every store's pending orders each time it runs.

These pages explain the logic behind those decisions in business terms: what the algorithm optimises for, what determines priority, which settings are available to you, and what to expect — or not expect — from it.

How to read this chapter

You don't need to read it front to back. Most questions land on one page:

If you want to know… Go to
What a term means Dispatcher glossary
What happens on each run The assignment cycle, step by step
Why an order stayed with an external carrier Re-checking orders already with a carrier
Why one driver was chosen over another Driver classification and priority
Why an order changed driver When an order changes driver
Why an order was left unassigned Last-Option: the final safety net and the Dispatcher FAQ
How often it runs, and how to start or stop it Scheduling plans: how the automatic cycle works
Where to change a particular setting Where each setting lives
The whole flow on one page End-to-end overview
A rule, without the explanation Quick reference rules
How to report something that looks wrong Reporting a dispatcher issue

Once the dispatcher has made its decisions, the live board where a person can intervene is the Hub — see The Hub: what it is and who can do what.

What it does not do

The dispatcher is deliberately bounded. It does not try to find a mathematically perfect plan across every driver and every order at once, it never touches an order that has already left the store, and it does not reorder work just because one order is more urgent than another. Those limits are listed in full under Known system boundaries — they are design decisions, not faults, and knowing them saves a lot of guesswork.

Delivery & Dispatcher

Dispatcher glossary

The terms below are used consistently throughout the Delivery & Dispatcher chapter.

Term Meaning
Own Fleet / Own Drivers Your restaurant's own delivery staff — delivery riders and, in some cases, kitchen staff who can also deliver
Third-Party Carrier An external delivery provider (e.g. a courier platform) used when your own fleet isn't the best option
Priority Customers (Platinum) An optional feature that gives certain orders — typically loyalty or VIP customers — a better chance of being delivered on time, without unfairly harming regular orders
PG Mode A first-in-first-out (FIFO) assignment method: orders are assigned to the best available driver in the order they came in
Google OR-Tools An advanced route-optimisation engine, normally used when there are more pending orders than available drivers, so routes can be planned more efficiently
Last-Option A final, same-cycle safety net for orders that couldn't be placed by the normal process — see Last-Option: the final safety net
Idle A driver with zero orders currently assigned
Waiting A driver who has orders assigned but hasn't left the store yet
On The Way A driver who has already left the store to deliver at least one order
At-Store Zone Being within roughly 350 metres of the store — close enough to be treated as "at the store" for assignment purposes
Time To Branch Estimated time for a driver to arrive back at the store
Time To Delivery Estimated time for a driver to complete a delivery
Assignment Cycle / Run One full execution of the algorithm across all your stores, triggered automatically on the schedule you define
Clubbing Grouping more than one order onto the same driver or carrier for a single trip
Critical An order that is still unassigned and already past its promised delivery time
Pending An order that is still unassigned but not yet late
Delivery & Dispatcher

The assignment cycle, step by step

Every time the dispatcher runs, it processes each store independently, following five steps in order.

The five steps

# Step What happens
1 Fetch data Pulls current orders, available drivers, and store and zone configuration. This is also when any order still sitting with a Third-Party carrier from a previous cycle gets re-examined — see Re-checking orders already with a carrier.
2 Cache check If nothing has changed since the last run, the store is skipped rather than re-processed, to save time and resources.
3 Assign orders The core decision-making step, covered in The three assignment mechanisms. This is where Third-Party, your own fleet and — optionally — Priority Customers logic all come together.
4 Post-process Results are categorised (new assignments, still-pending orders, orders sent to Third-Party, and so on), orders that can be grouped onto the same driver are identified, and anything still unassigned gets one final relaxed attempt — see Last-Option: the final safety net — before being marked Pending or Critical.
5 Save and notify Final assignments are saved, drivers are notified by push notification, and any relevant alarms are processed.

Step 2 is the reason a run can complete almost instantly for a quiet store. A skipped store is not an error, and nothing is lost — the next cycle picks it up the moment anything changes.

What "independently, per store" means in practice

Each store is solved on its own. A driver shortage at one store never pulls drivers from another, and a store whose data hasn't changed is skipped without affecting the rest. This is also why a report of a dispatcher problem should always name the store — see Reporting a dispatcher issue.

Where the deeper detail lives

Steps 1 and 3 carry almost all of the decision-making, and each has its own page:

Delivery & Dispatcher

Re-checking orders already with a carrier

Before the dispatcher evaluates any new assignments, it first re-examines every order that is already sitting with a Third-Party carrier from a previous cycle — meaning a carrier has been given the order but hasn't yet left the store with it.

This happens during step 1 of The assignment cycle, step by step, for every store, every cycle. It never touches brand-new orders or orders already assigned to your own fleet.

The three questions, in order

For each carrier-held order, up to three questions are asked. The first one that resolves the order stops the sequence.

1. Has the carrier been sitting on this order too long?

Governed by Max time to accept (set per store, per carrier — see Where each setting lives).

2. Is the carrier's own estimate for reaching the store slipping too far?

Governed by Max time to reach store (per store, per carrier).

If the carrier's estimated arrival at the store has drifted past this limit, the order is cancelled immediately — regardless of whether an alternative is available. An unreliable estimate from the carrier itself is reason enough to give up on it.

3. Are we still inside the free-cancellation window, and does our own fleet have room?

Governed by Free-cancellation window (per carrier, company-wide).

If yes to both, the order is reset to look unassigned — only in the dispatcher's working memory. Nothing is saved, and nothing is cancelled with the carrier yet. The order simply rejoins the normal assignment process for that store, exactly like any other unassigned order in that cycle.

This is not a special "try own fleet" routine. From this point on, the dispatcher has no notion that the order was ever with a carrier — it goes through PG Mode, Google OR-Tools and Third-Party like everything else, under all the same rules.

If the normal process assigns an own driver to it, two things then happen in strict order:

  1. A real cancellation is sent to the original Third-Party carrier.
  2. Only if that cancellation succeeds, the new internal-driver assignment is saved.

If the cancellation fails, step 2 never happens: nothing changes and the order stays with the carrier. This avoids a confusing state where one order looks assigned in two places at once.

If the normal process doesn't place it with an own driver, the in-memory reset is discarded. The order goes back to exactly how it was — still validly assigned to the carrier — as if the reset had never happened. No cancellation is ever sent in this case.

Questions 1 and 2 look similar but compare different things

This is the single most common source of confusion on this page.

Question What it actually compares Consequence
Max time to accept Real elapsed time — now, versus when the order was given to the carrier. Only fails once enough wall-clock time has genuinely passed. Cancels, but only if an alternative exists
Max time to reach store The carrier's own promise — their reported arrival estimate, versus when the order was given to them. It never looks at the current time at all. Can fail seconds after assignment, if the carrier's own estimate is already too far out. Cancels regardless of alternatives
Free-cancellation window Same style of comparison as Max time to accept (now versus assignment time), but with a different consequence: passing it cancels nothing by itself. It only opens the door to the no-commitment own-fleet attempt described above. Enables the risk-free retry

What happens if the own-fleet attempt doesn't work out

The order is deliberately skipped from that same cycle's Third-Party fallback pass — it is not re-evaluated against carriers again in this run.

This is intentional. The order is already validly assigned to a carrier, so re-running the fallback would be redundant at best, and risks producing a second, conflicting carrier assignment for an order that already has one. It carries on with its existing assignment until the next relevant check — a future cycle, or an actual delivery-time failure.

Why this matters

Without this check, an order could sit with a slow or unresponsive carrier indefinitely, or stay there even after your own fleet became free to take it sooner.

The own-fleet attempt is deliberately risk-free: if it doesn't pan out the order is left exactly as it was, the carrier is none the wiser, and nothing is ever cancelled without a confirmed replacement already lined up.

Delivery & Dispatcher

When does an alternative exist?

The first question on Re-checking orders already with a carrier only cancels a slow carrier if there is a genuine alternative ready to take over.

That check has two independent halves — whether your own fleet could take it, and whether another Third-Party carrier could take it. They differ a lot in depth. Either one being true is enough.

Own fleet — one simple check

Check What it verifies Where it's configured
Free capacity slot At least one own-fleet driver (in-house or own-fleet contractor) currently has room for one more order Maximum orders per driver — see Where each setting lives

This is intentionally a quick, optimistic check. It only asks "does any driver have a free slot" — not whether that driver is close enough, idle, or actually able to take this order. It exists purely to answer "is it even worth cancelling the carrier's order?" The real evaluation happens afterwards, once the order rejoins the normal assignment process.

Third-Party — several checks, and only carriers further down the list

An important scoping rule first: this only looks at carriers that come after the currently-assigned one in that zone's configured carrier order. Carriers earlier in the list are never considered here, even if they would otherwise qualify. The search stops at the first carrier that passes every check below — it does not look for the "best" one.

For each candidate carrier, in order, all of the following must pass:

Check What it verifies
Enabled & order-type match The carrier's master switch is on, and it applies to this order's type and sales channel
Payment compatibility Cash orders don't exceed the carrier's cash-on-delivery limit; card orders are only offered if the carrier accepts cards
Product restrictions None of the order's products fall into a category this carrier is excluded from
Capacity at this store The carrier still has a free slot in its shared per-store capacity pool
Distance The store-to-customer distance is within the carrier's allowed range
Operating schedule The current time falls within the carrier's configured working hours for this store

The first candidate to pass all six counts as "an alternative exists", and the search stops there.

Deliberately not checked here: the normal delivery-time-window check is skipped. At this point the system is only confirming that a carrier could structurally take the order — enabled, payment, products, capacity, distance, hours. Whether it could deliver it on time is evaluated later, if and when the order is actually offered to that carrier.

All of these settings live on the carrier's general or per-store configuration — see Where each setting lives.

Delivery & Dispatcher

The three assignment mechanisms

Every order is ultimately resolved using one — or a combination — of three mechanisms.

Mechanism When it's used
PG Mode (FIFO) You have enough own drivers to cover pending orders
Google OR-Tools There are more pending orders than own drivers, so routes need planning more efficiently
Third-Party Carriers Your external delivery network

Which of PG Mode or Google OR-Tools is used for a given store is decided automatically, from the ratio of pending orders to available drivers — unless you force one specific mode in the scheduling plan. See Scheduling plans: how the automatic cycle works.

How they combine

Zone configuration decides whether Third-Party gets the first attempt or only acts as a safety net. Everything else works the same either way.

Standard zone — own fleet first:

  1. Own solver (PG Mode or Google OR-Tools).
  2. Idle driver retry — free store drivers the solver didn't use.
  3. Third-Party fallback — last resort.

Third-Party-first zone — carrier first:

  1. Third-Party carrier, one attempt. If assigned, done.
  2. Own solver (PG Mode or Google OR-Tools).
  3. Idle driver retry.
  4. No further fallback — the order already had its Third-Party turn.

The rule that keeps it fair

Each order gets exactly one attempt with each resource type — own fleet and Third-Party — per assignment cycle.

The zone configuration only decides which one goes first, never how many attempts an order gets:

Zone type Attempt order Total attempts
Standard Own fleet → Third-Party 2
Third-Party-first Third-Party → Own fleet 2

Always two. Never three, never one.

Before the order is left for the next cycle

There is one more relaxed attempt within the same cycle — see Last-Option: the final safety net.

If the order is still unassigned after that, the next scheduled run starts completely fresh, including a brand-new Third-Party attempt. How soon that happens is set by the store's scheduling plan.

Delivery & Dispatcher

Last-Option: the final safety net

After the own solver and the Third-Party attempt have each had their one shot at an order, some orders may still be unassigned. Rather than leaving them for the next cycle straight away, the dispatcher makes one more attempt — per store, at the end of the same cycle — called Last-Option.

What problem it solves

Last-Option only looks at orders still unassigned after the normal process. Its goal is simple: avoid leaving an order completely unassigned if there is any reasonable way to place it, even if that means being more flexible than the normal rules.

How candidates are found

Candidates are sourced differently depending on where they come from, and Last-Option relaxes some checks the normal process enforces.

Source How the candidate is chosen What's relaxed
Own fleet (in-house and own-fleet contractors) Best available driver, by capacity and how soon they could leave The usual delivery-time window is not re-checked
Third-Party carriers Any carrier already tried and rejected earlier in this same cycle The original rejection reason is not re-checked — only whether capacity has since freed up

Whichever candidate can start the delivery soonest is the one chosen.

Order of processing

Orders are processed one at a time, most urgent first, by promised delivery time.

Priority Customers (Platinum) status does not affect which order gets a shot at Last-Option first. Platinum only affects the sequence of multiple orders already on the same driver's route.

Step by step

  1. Collect the orders still unassigned after the own solver and the Third-Party attempt.
  2. Sort them by promised time, most urgent first.
  3. For each order in turn, gather candidates:
    • the best available own driver — capacity checked, delivery-time window not re-checked;
    • carriers rejected earlier this cycle, reconsidered only if capacity has since freed up.
  4. Pick whichever candidate can start the delivery soonest.
  5. If none is available, the order stays unassigned and is marked Critical or Pending.

If even Last-Option can't place it

The order is categorised as Critical (already past its promised time) or Pending (not yet late). The very next scheduled run tries again from scratch, including a brand-new Third-Party attempt.

Trade-off to be aware of: because Last-Option relaxes the normal delivery-time check for own drivers, an order placed through it may end up with a slightly later estimated arrival than the normal tolerance allows. This is intentional — better to get it moving, slightly delayed, than leave it unassigned entirely.

Delivery & Dispatcher

Driver classification and priority

Drivers are ranked by three things: their current status, their type, and how close they are to the store.

By status

Status Description
Idle Has zero orders currently assigned — fully available
Waiting Has orders assigned, but none have left the store yet
On The Way Has at least one order already out for delivery

By type

Type Description Priority
Internal delivery driver Your dedicated delivery staff Highest
Internal kitchen staff (can deliver) Kitchen staff who can also deliver when needed Medium
External / own-fleet contractor Externally contracted own-fleet driver Lower
Third-Party carrier External delivery platform Used per zone and configuration rules

Status and location combined

The "At-Store Zone" is roughly 350 metres from the store.

Category Status Location Priority
1 Idle At store Highest
2 Idle Away from store High
3 Waiting At store Medium
4 Waiting Away from store Lower
5 On The Way Out delivering Lowest

The reasoning is straightforward: an idle driver already at the store is the fastest possible option, so they are always preferred. A driver already out delivering is the last resort, since assigning them a new order means adding it to an existing route.

Where "at store versus away" actually matters

This distinction is not only used for the ranking above. It changes real decisions in several places:

Upcoming change, currently in internal testing. Today, whether a driver counts as "at the store" uses an estimated driving distance compared against the ~350 m threshold, not a straight-line distance. This is being replaced by a straight-line ("as the crow flies") calculation, because a driving-route estimate can be inaccurate right around a store. The change is not yet active for all accounts; this page will be updated once it ships.

Delivery & Dispatcher

Priority Customers (Platinum)

This page only applies if your account has Priority Customers (Platinum) evaluation enabled. It is not part of the core flow — it runs as an extra layer on top of it, only for stores where it's switched on, and only when there are Platinum orders to consider.

What it does

When enabled, the dispatcher runs a double simulation for each store before committing to a decision:

  1. Normal run — orders are processed in their regular order.
  2. Platinum-first run — Platinum orders move to the front of the queue and get a little more delivery-time flexibility.

The two results are compared, and the dispatcher picks whichever one better protects Platinum orders without excessively harming regular orders.

How the choice is made

  1. Are there at-risk Platinum orders in the normal run?
    • No → use the normal run as-is. The second simulation never runs.
    • Yes → continue.
  2. Run the Platinum-first simulation.
  3. Count how many regular orders would be newly harmed by it.
    • Below the impact threshold → use the Platinum-first result.
    • At or above the threshold → discard it and use the normal result.

A Platinum order counts as "at risk" if it wouldn't be assigned at all, or if its estimated delivery would fall outside an acceptable refund-risk window.

What you can configure

Setting What it controls
Enable / disable Turns the entire layer on or off
Buffer minutes Extra delivery-time flexibility given specifically to the Platinum-first simulation
Impact threshold Maximum number of regular orders allowed to be newly harmed before the Platinum-first result is rejected

What it deliberately does not do

Platinum protection works only through the double simulation above. There is no rebalancing of existing routes to make room for a Platinum order — that limit and the others are listed in Known system boundaries.

Platinum status also plays no part in ordinary reassignment (When an order changes driver) or in the Last-Option queue order (Last-Option: the final safety net).

If the layer is not enabled, Platinum orders are treated exactly like any other order.

Delivery & Dispatcher

When an order changes driver

Before every assignment attempt, the dispatcher checks whether an order already assigned to one driver should instead go to a different one — but only on driver priority, never on how urgent or important the order itself is.

When a reassignment is allowed

Situation Result
Order has no driver yet Assign freely
Previously assigned driver is no longer available Assign freely
Same driver being considered again No change needed
New driver has better priority Reassign
Current driver has equal or better priority Keep as-is

Priority is defined in Driver classification and priority.

Common scenarios

Current driver Candidate driver Outcome
External driver Internal driver Reassigned — better type
Idle, at store Idle, at store No change — both equally good
Idle, away from store Idle, at store Reassigned — better location
Waiting, at store Idle, away from store No change — current is still better
External, away from store External, away from store No change — no real improvement

Passing the priority check is not a delivery guarantee

Passing it only means the dispatcher will attempt the assignment. It still has to verify the new driver can actually deliver on time:

Driver situation Delivery time checked?
Idle, at store No — always the fastest possible option
Idle, away from store Yes
Waiting (already has orders) Yes — must be able to deliver everything
On The Way Yes — the full route is recalculated

If the delivery-time check fails, the assignment is reverted and the order stays available for the next driver in line. It isn't lost.

Rules that never change

Delivery & Dispatcher

Scheduling plans: how the automatic cycle works

The dispatcher runs on a schedule you define per store, or per group of stores. Scheduling and assignment behaviour are configured together, in the same plan.

How the automatic cycle works

Scheduling settings

Setting Default What it does
Plan name — A label to help you identify this plan. Optional, free text
Stores — The stores this plan applies to. One plan can cover several
Active Off Whether the automatic cycle is currently running for this plan
Run interval 60 seconds How often the dispatcher re-runs. Allowed range: 60–300 seconds
Daily time window None Optional start and end time. If not set, the plan runs 24/7
Last run — Read-only. When this plan last actually ran

Assignment behaviour settings

Setting Default What it does
Assignment mode Automatic Forces PG Mode or Google OR-Tools, or leaves the choice automatic (recommended)
Routing strategy Automatic Only relevant when Google OR-Tools is used
Stop time at customer 5 min Extra time accounted for at each customer stop
Stop time at store 3 min Extra time accounted for at each store stop
Maximum orders per driver 3 Most orders bundled onto a single own driver. Allowed range: 1–5
Offline driver grace period 5 min How long a briefly-offline driver is tolerated before being treated as unavailable
Apply results On When off, the run is a simulation only and nothing is changed
Extra time margin 10 min Additional slack allowed. Only relevant to Google OR-Tools
Minimum orders to accept a plan 0 How many orders Google OR-Tools must successfully assign for its plan to be accepted
Priority Customers (Platinum) Disabled Enables and configures the Platinum layer — see Priority Customers (Platinum)
Traffic-aware estimates Off More accurate time estimates, at a higher cost
Traffic estimate type — Optimistic, pessimistic or best guess. Only used when traffic-aware estimates are on
Return-time reuse — Advanced. Controls how aggressively previously calculated driver-to-store times are reused instead of recalculated

Store-level delivery settings

Two further settings live at the store level, not inside the scheduling plan. They are configured from the store's dispatcher settings and control how much delay is tolerated before an order is treated as at risk.

Setting Applies to What it does
Own-fleet delay tolerance Your own fleet — in-house and own-fleet contractors, treated equally The delay tolerance used when checking whether your own fleet can deliver on time. If a store has no in-house drivers at all, this value is automatically replaced by the Third-Party tolerance below, so an all-contractor store isn't held to a stricter standard than it can meet
Third-Party delay tolerance Third-Party carriers The delay tolerance used to decide whether a carrier can be trusted to deliver on time. It always applies to carriers, whether or not the store also has in-house drivers

Capacity works differently from delay tolerance. Your own fleet has a per-driver limit — each vehicle carries up to the configured maximum at once. Third-Party carriers have a single shared pool per store, per carrier company — for example "this carrier can handle 10 concurrent orders at this store", however many individual couriers they have on the road. This is why a carrier can appear full for a store even when it looks like it has plenty of drivers: the limit is set at company level, not per courier.

Activating and pausing a plan

This is the part most likely to cause confusion.

Action Starts the cycle? Stops the cycle?
Create a plan with Active switched on Yes —
Create a plan with Active switched off No — it stays dormant —
Edit an existing plan and switch Active on No effect — it only updates the stored value —
Edit an existing plan and switch Active off — Yes, from the next run onwards
Use the dedicated Activate action Yes —
Use the dedicated Pause action — Yes
Delete a plan — Yes

Recommendation: don't rely on editing the Active field through a general edit form. Always use the dedicated Activate and Pause actions — editing the field directly can leave a plan marked active but not actually running.

Delivery & Dispatcher

Where each setting lives

Beyond the scheduling plan, several other parts of the product hold settings that directly affect dispatcher decisions. This page lists them by where you'd actually go to change them, and only includes settings you can edit.

For the scheduling plan itself, see Scheduling plans: how the automatic cycle works.

Zones

Edited from the zone's driver-availability settings.

Setting What it controls
Own vs. Third-Party priority Whether orders in this zone go straight to carriers first, or start with your own fleet as usual
Third-Party ranking rule When more than one carrier is available for the zone, the order they're tried in: your configured order, lowest cost first, or fastest time first
Allowed Third-Party carriers Which carriers can be offered orders from this zone
Allowed own-driver types Which of your own driver types can deliver in this zone. Leaving this empty blocks all own drivers from the zone entirely
Extra time buffer Additional minutes added to the expected time at the customer's location for orders in this zone — for example, to account for difficult access

Zones also expose a delivery-time deviation field, along with pricing fields such as delivery fees and minimum order amounts. These are editable on the same screen but are not used by the dispatcher — the delivery-time deviation is consumed by the ordering website, not by the assignment logic.

Stores

Edited from the store's dispatcher settings.

Setting What it controls
Own-fleet delay tolerance / Third-Party delay tolerance See Scheduling plans: how the automatic cycle works for how these two work together
Kitchen-driver max distance How far from the store a kitchen-staff driver can be sent. Set to zero to remove the restriction entirely

Stores also have opening and closing hours, per day and per shift, configured elsewhere in the product. Those are not used by the dispatcher.

Third-Party carriers — general settings

Edited from the carrier's general configuration. These apply company-wide, across every store.

Setting What it controls
Enabled Master on/off switch. While disabled, this carrier is never considered, at any store
Order type / sales channel Restricts which order types and sales channels this carrier can be offered
Integration endpoint The connection used to reach this carrier's platform. Normally set once, during onboarding
Default delivery cost Used to estimate and rank this carrier when no live pricing is available
Minimum readiness buffer How long an order must still need before it can be offered to this carrier at all
Max cash-on-delivery amount Cash-paid orders above this amount won't be offered to this carrier
Accepts credit card Whether this carrier can be offered card-paid orders
Excluded product families Product categories — for example age-restricted items — this carrier will never be offered
Max distance Farthest store-to-customer distance this carrier will be offered
Free-cancellation window Minutes after assignment during which the order can still be pulled back without penalty. See Re-checking orders already with a carrier
Description Internal label for this carrier

A "default delivery time" setting also exists at this level, but it is no longer used. It moved to the per-store settings below so it can be tuned more precisely.

Third-Party carriers — per-store settings

Edited from the carrier's settings for a specific store. These add store-specific detail on top of the general settings above, for the same carrier.

Setting What it controls
Max time to reach store If this carrier's driver doesn't arrive within this time after accepting, the order is cancelled and reassigned
Estimated time to reach store (fallback) Used when no live estimate is available for this carrier at this store
Max time to accept If this carrier doesn't accept the order within this time, it's released for reassignment
Default delivery time The delivery-time estimate used when no historical average is available for this carrier at this store
Clubbing allowed Whether this carrier's driver can carry more than one order per trip at this store
Capacity at this store A shared pool for this carrier at this store, not a per-courier limit
Operating schedule Days and shifts during which this carrier is available at this store. Outside these hours it is skipped entirely
Delivery & Dispatcher

Quick reference rules

A one-page summary of the rules that come up most often. Each links to the page that explains it in full.

Rule Behaviour
Orders already out for delivery Never revalidated, never reassigned — only used to estimate when the driver returns
Orders still waiting to leave Can be reassigned if a better driver becomes available
Reassignment checks Run before every single assignment attempt
Reassignment criteria Based only on driver priority — never on how urgent the order is
Manually assigned orders Fully locked from automatic reassignment
Internal vs. external drivers Internal can take orders from external. External can never take from internal
Attempts per cycle Exactly one with your own fleet and one with Third-Party. The zone decides the order, not the count
Priority Customers (Platinum) Not considered during regular reassignment — only inside its own optional evaluation layer
Order already with a carrier Can still be pulled back to your own fleet before the carrier collects it, if inside the free-cancellation window and your fleet has room
A carrier order is never cancelled blindly Nothing is cancelled without a confirmed replacement already lined up
Unassigned at the end of a cycle Marked Critical or Pending, and retried from scratch on the next scheduled run

Where to read more

Topic Page
Driver ranking Driver classification and priority
Reassignment rules When an order changes driver
Carrier pull-back Re-checking orders already with a carrier
The final attempt Last-Option: the final safety net
Design limits Known system boundaries
Delivery & Dispatcher

Known system boundaries

These are intentional design limits, not faults. Knowing them keeps expectations realistic and saves time when something looks wrong but isn't.

No proactive rebalancing

The dispatcher never moves a regular order out of a driver's route just to make room for a Platinum order. Platinum protection works only through the double simulation described in Priority Customers (Platinum).

Orders out for delivery are frozen

Once a driver has left the store with an order, that order is never touched again by the dispatcher. It is still used to estimate when that driver will be free, but it cannot be reassigned, revalidated or cancelled by the algorithm.

Decisions are local, not global

Each assignment decision compares the current driver against one candidate driver. The dispatcher does not attempt to find a perfect overall solution across all drivers and all orders at once.

This is why two decisions that each look right individually can, together, look less than ideal in hindsight.

Order urgency isn't a reassignment factor

Only driver priority matters when deciding whether to reassign. A very urgent regular order will not jump the queue over a less urgent one on its own. See When an order changes driver.

Last-Option can exceed the normal delay tolerance

As a last resort, an order may be placed with a slightly later estimated arrival than the normal delay tolerance would otherwise allow, rather than being left unassigned. See Last-Option: the final safety net.

A store with no change is skipped

If nothing has changed for a store since the last run, it is skipped rather than re-processed. A run that appears to have "done nothing" for a quiet store is behaving correctly — see The assignment cycle, step by step.

Delivery & Dispatcher

End-to-end overview

The full path a store's orders take in a single cycle, pulling together everything in this chapter.

One cycle, one store

  1. Fetch orders and drivers for this store. Orders already sitting with a Third-Party carrier from an earlier cycle are re-examined here — see Re-checking orders already with a carrier.
  2. Is this a Third-Party-first zone?
    • Yes → try a Third-Party carrier first. If it takes the order, that order is done.
    • No → go straight to step 3.
  3. Own solver — PG Mode or Google OR-Tools, chosen automatically unless you force one.
    • If Priority Customers (Platinum) is enabled and applicable, this step is replaced by the double simulation described in Priority Customers (Platinum). Everything before and after stays the same.
  4. Idle driver retry — free store drivers the solver didn't use.
  5. Third-Party fallback, but only for orders from a standard zone. An order from a Third-Party-first zone has already had its carrier turn and gets no second one.
  6. Post-process — categorise results and identify orders that can be grouped onto one driver.
  7. Still unassigned?
    • No → save and notify.
    • Yes → the final relaxed attempt, described in Last-Option: the final safety net. If it places the order, save and notify. If not, the order is marked Critical or Pending and the next cycle retries from scratch.
  8. Save and notify — assignments are written, drivers are pushed a notification, alarms are processed.

The two things worth remembering

Every order gets exactly two attempts per cycle — one with your own fleet, one with Third-Party — plus the Last-Option safety net at the end. The zone configuration changes the order of those two attempts, never the number.

Nothing is ever cancelled without a replacement lined up. An order already with a carrier is only pulled back once a real own-fleet assignment has been found and the cancellation with the carrier has succeeded.

Delivery & Dispatcher

Reporting a dispatcher issue

If something looks wrong — an order assigned to the "wrong" driver, delayed, or stuck unassigned — the fastest way to get it resolved is to report it with the right information the first time.

Screenshots alone, especially of unrelated screens, rarely help. Specific, matched details do.

What to include

Detail Why it matters
Request ID Identifies the exact dispatcher run involved. Shown in the execution summary on the plan's detail view in the Scheduler, and looks like req_1785152470621_6v3uobxk86e. This is the single most useful thing you can provide — more so than the store, because it points to one exact run
Order ID / ticket number Without it, the affected order can't be traced
Store Which store's run is affected
Date and approximate time Narrows down which cycle to examine
What you expected For example: "should have gone to an idle driver at the store", "should have stayed with the original driver"
What actually happened For example: "stayed unassigned for 12 minutes", "was reassigned to a different driver", "went to a carrier instead of our own fleet"
One-off or recurring? A single order and a pattern across many orders point to very different causes
Was it a Priority Customer (Platinum) order? Helps rule the optional Platinum layer in or out
Any recent configuration changes A zone, store or carrier setting changed shortly beforehand helps separate cause from coincidence

What evidence actually helps

What to avoid

Before you report

Two behaviours are frequently mistaken for faults. Checking them first can save a round trip:

The clearer and more specific the report, the faster it can be matched against the actual run that produced the behaviour you're describing.

Delivery & Dispatcher

Dispatcher FAQ

Why did an order suddenly get reassigned to a different driver?

A driver with better priority became available — for example an idle driver at the store, or an internal driver where before only an external one was free. See When an order changes driver for the exact rules.

Why is an order still unassigned after a run?

Under normal conditions every order should end up assigned: to your own fleet, to a carrier, through a fallback pass, or via the Last-Option safety net. An order still unassigned at the end of a cycle usually points to one of these:

It will be retried automatically on the very next cycle, but if it happens often it's worth investigating rather than treating as routine.

What is Last-Option, and does it mean my order gets worse service?

Last-Option is a final, same-cycle safety net for orders the normal process couldn't place. It relaxes the usual delivery-time check to avoid leaving an order completely unassigned, so it may accept a slightly later estimated arrival — but only when no better alternative exists, and only after the normal process has had its full attempt. See Last-Option: the final safety net.

Why can't I turn a plan on or off just by editing it?

Editing a plan only updates its stored configuration. It does not start or stop the automatic cycle. Always use the dedicated Activate and Pause actions. See Scheduling plans: how the automatic cycle works.

What does enabling Priority Customers (Platinum) actually change?

It adds an evaluation step that tries to protect Platinum orders from being delivered late — but only if doing so doesn't harm too many regular orders at the same time. If it isn't enabled, Platinum orders are treated exactly like any other order. See Priority Customers (Platinum).

How often does the dispatcher actually run?

Whatever run interval you set on the plan — minimum 60 seconds, maximum 300. If a run fails, the schedule doesn't break; the next run is still scheduled normally.

Can an order already with a Third-Party carrier move back to my own fleet?

Yes, but only before the carrier's driver has left the store with it, and only if two things are true: the order is still inside the carrier's free-cancellation window, and an own driver with capacity is available right then. Even so, the switch only happens if the cancellation with the carrier succeeds first. If any of that isn't met, the order simply stays with the carrier and nothing changes. See Re-checking orders already with a carrier.

A carrier looks like it has plenty of drivers, so why is it "full" for my store?

Carrier capacity is a single shared pool per store, per carrier company — not a per-courier limit. See the capacity note in Scheduling plans: how the automatic cycle works.

Why did a run appear to do nothing for one of my stores?

If nothing has changed for that store since the last run, it is deliberately skipped rather than re-processed. See The assignment cycle, step by step.

Delivery & Dispatcher

Pausing and resuming delivery

You need: Pause / resume delivery — held by admin, hub_manager, dispatcher_manager and branch_manager. Viewing the status only needs store read access.

Pausing delivery stops a store taking new delivery orders for a set time, without closing the store or touching orders already in flight.

Pausing a store

  1. Open the store's delivery controls.
  2. Choose Pause and set the duration in minutes.
  3. Confirm.

The pause is time-boxed: when the duration elapses, delivery resumes on its own. You don't have to remember to turn it back on.

If the store is already paused, pausing again doesn't stack. You'll be told it's already paused rather than silently extending it — check the current status first if you intend to extend a pause.

Resuming early

Resume ends the pause immediately, before the duration is up. Use it when the reason for the pause clears sooner than expected — a kitchen backlog that resolves, drivers coming back on shift.

Checking the current status

The delivery status view answers two questions: whether the store is paused right now, and if so what is scheduled to bring it back. Check it before pausing, so you don't mistake an existing pause for a new one.

Active pause jobs

Each pause creates a job that will resume the store when its time is up.

Emergency: cancelling all pauses

There is a chain-wide action that cancels every active delivery pause job at once.

This is an emergency control, not a routine one. It affects every store that is currently paused, including stores paused by other people for reasons you may not know about. Check the chain-wide job list first so you know exactly what you are about to resume, and tell the affected stores.

Use it when pauses were applied in bulk by mistake, or when an incident is over and you need everything back online without visiting each store.

What pausing does not do

What you can and can't see

The per-store actions are filtered by your scope: you can only pause, resume or inspect stores within it. The chain-wide job list and the emergency cancel are not store-specific, so they are limited to roles that hold delivery control without a store restriction.

Delivery & Dispatcher

Delivery zones

You need: Delivery zones — view to browse, Delivery zones — edit to change anything. Held by admin, dispatcher_manager and polygon_manager.

A zone is a delivery area with a map polygon and a set of rules deciding which drivers and carriers serve it. Zones are the single biggest lever on dispatcher behaviour — see Where each setting lives for what each rule does.

Browsing zones

The zones list shows every zone for the brand, with its store and whether it has a polygon drawn. A separate view shows zones alongside their driver availability configuration, which is where you see at a glance whether a zone is set to try carriers first.

The map view needs a configured Maps key for the brand. If the map is blank while the list shows zones, that's a configuration issue rather than missing zones.

Editing a zone's driver availability

This controls the rules the dispatcher actually uses: own-fleet versus carrier priority, the carrier ranking rule, which carriers are allowed, which own-driver types are allowed, and the extra time buffer.

The trap worth repeating: leaving allowed own-driver types empty does not mean "all types". It blocks every own driver from the zone, and orders there will only ever go to carriers. This is the most common cause of a zone whose orders all end up external.

Drawing and removing polygons

A zone's polygon defines its geographic boundary.

A zone with no polygon cannot match an address, so orders won't be routed to it. Deleting a polygon is therefore effectively switching the zone off, even though the zone itself still exists.

Moving a zone to another store

A zone — together with its polygon — can be migrated to a different store. Use this when a store relocates or when an area is reassigned between stores, rather than deleting the zone and redrawing it, which loses the boundary.

Bulk changes by file

For anything beyond a handful of zones, use the file-based tools.

Action What it does
Export zones Downloads the current zone configuration as a CSV. Always export before a bulk change — it is your rollback
Import zones Applies zone configuration from a CSV
Import polygons from KML Bulk-loads zone boundaries from a KML file, the format mapping tools export

KML import is partial by design: valid rows are imported even when others fail. You get what worked plus a report of what didn't, rather than an all-or-nothing rejection. Read the report — a partially successful import leaves the rest of your zones untouched and still needing attention.

Time-based zone switching

Zones can switch on a schedule, so an area is served differently at different times of day. These rules are loaded from a CSV.

Unlike the KML import, this import is all-or-nothing: if any row is invalid, nothing is applied. Fix the file and re-import.

Before and after a bulk change

  1. Export first. The export is the only rollback you have.
  2. Apply the import.
  3. Read the result carefully — especially for KML, where partial success is normal.
  4. Check a sample zone on the map.
  5. Confirm with a real order in that area, if you can.

Zone backups are kept and can be restored — see Backups and restoring configuration.

Delivery & Dispatcher

External carriers

You need: Third-party — view to browse, Third-party — edit to change. Held by admin, dispatcher_manager and third_party_manager. Per-store carrier settings are also reachable by hub_manager.

Carrier configuration exists at two levels, and knowing which one you're editing is most of the battle.

Level Applies to Typical settings
Brand Every store in the brand Whether a carrier is enabled at all, payment rules, product exclusions, maximum distance, free-cancellation window
Store One carrier, at one store Timing limits, capacity at that store, operating schedule, clubbing, default delivery time

Both levels are listed field by field in Where each setting lives.

Brand-level configuration

The brand view lists every carrier type available to you and its current configuration. Editing here changes that carrier everywhere.

The master Enabled switch is brand-wide. Turning a carrier off here removes it from every store immediately, whatever the per-store settings say. If you only want to stop using a carrier at one location, change that store's settings instead.

Store-level configuration

The per-store view shows the same carriers with their settings for that one store. This is where you tune the things that genuinely differ by location: how long a carrier gets to accept, how long they get to reach the store, how many concurrent orders they can hold there, and the hours they operate.

Two of these drive the behaviour described in Re-checking orders already with a carrier — Max time to accept and Max time to reach store. They look similar and compare completely different things; that page has the comparison.

Capacity is per company, not per courier

A carrier's capacity at a store is a single shared pool for that carrier company. "Ten concurrent orders at this store" means ten, however many couriers that company has nearby.

This is the usual explanation when a carrier looks busy on their own app but appears full to the dispatcher.

Bulk changes by file

For chain-wide carrier work, use the file tools rather than editing store by store.

Action What it does
Export per-store carrier configuration Downloads current per-store settings as CSV. Export before every bulk change
Import per-store carrier configuration Applies per-store settings from CSV

Backups of carrier configuration are kept and restorable — see Backups and restoring configuration.

When a carrier is never offered orders

Work through this before reporting a problem. A carrier is skipped entirely if any of these is true:

The full ordered list of those checks is in When does an alternative exist?

Delivery & Dispatcher

Store delivery settings

You need: Store config — view to browse, Store config — edit to change. Held by admin, hub_manager, dispatcher_manager and branch_manager.

Each store carries its own dispatcher settings, separate from the scheduling plan that governs when the dispatcher runs. Those two are configured in different places and are easy to confuse — the plan decides when and how the dispatcher runs, the store decides how tolerant it is for that location.

Store list

The list shows every store within your scope. A branch_manager sees their own store; a chain-wide role sees all of them. If a store you expect is missing, that is a scope question rather than a configuration one — see How scope works in practice.

Dispatcher settings for a store

Two settings matter most, and both are explained in full in Scheduling plans: how the automatic cycle works:

There is a rule here that surprises people: if a store has no in-house drivers at all, the own-fleet tolerance is automatically replaced by the third-party value. An all-contractor store is not held to a stricter standard than it can meet. You don't configure this — it just happens.

A third setting, kitchen-driver max distance, caps how far a kitchen-staff driver can be sent from the store. Setting it to zero removes the restriction entirely rather than blocking all kitchen drivers.

Promised delivery times

Each store exposes the delivery times it can promise a customer. These feed the time a customer is quoted at ordering, and the promised time the dispatcher then works against when deciding what is late — see the definitions of Critical and Pending in the Dispatcher glossary.

Products and promotions per store

A store's view also lists the products and promotions currently active there. This is a read-only cross-check: useful when an order behaves unexpectedly and you want to confirm what that store actually offers, rather than what the brand catalogue says.

What belongs elsewhere

Looking for Actually lives in
How often the dispatcher runs for this store The scheduling plan — Scheduling plans: how the automatic cycle works
Which drivers and carriers serve an area The zone — Delivery zones
Carrier timing and capacity at this store Carrier per-store settings — External carriers
Pausing deliveries temporarily Pausing and resuming delivery
Store opening hours The general store configuration. Not used by the dispatcher
Delivery & Dispatcher

Backups and restoring configuration

You need: the view or edit permission for whatever the backup contains — not a separate backup permission. A zones backup needs delivery-zone access; a carrier backup needs third-party access; an employee backup needs employee access.

Every time you export configuration, a backup is kept. You can list them, download them, restore one, or delete it.

What gets backed up

Backup type Covers Permission it follows
Zones Delivery zone configuration Delivery zones
Schedule zones Time-based zone switching rules Delivery zones
External carriers Per-store carrier configuration Third-party
Employees Employee and own-driver configuration Employees

Because each backup follows the permission of its own content, someone who can restore a zones backup cannot necessarily restore an employees one. Access is decided by what the backup contains, checked when you open it.

Browsing backups

The list can be filtered by type. Each entry shows what it covers and when it was taken. Filenames follow the pattern backup-<type>-<date>.csv, so a downloaded file stays identifiable after it leaves the console.

Downloading

Download gives you the CSV snapshot exactly as it was captured. Two good reasons to download rather than restore:

Restoring

Restoring re-applies a captured snapshot.

Read this before restoring. A restore reinstates the configuration as it was at capture time. Anything changed since — by you or anyone else — is overwritten for the entities in that snapshot. If two people have been editing zones this week, restoring last week's backup discards both sets of changes, not just the one you meant to undo.

The safe sequence:

  1. Export now, creating a fresh backup of the current state. This is your way back.
  2. Download the backup you intend to restore and read it.
  3. Restore.
  4. Verify on a real zone, store or carrier that the result is what you wanted.

Deleting

Deleting removes a backup permanently. Do it to clear out noise, not to tidy up after a change — the older backups are exactly what you need when a problem is noticed late.

Before deleting, check it isn't the last known-good snapshot from before a significant change.

Hub

The live order board: assigning, incidents, critical actions and alarms.

Hub

The Hub: what it is and who can do what

Audience: hub operators, shift managers and operations managers working the live order board. You need: Hub — orders and status at minimum. Individual actions each need their own permission, listed below.

The Hub is the live operational view of orders in flight. Where the dispatcher decides automatically, the Hub is where a person intervenes: assigning a driver by hand, changing a promised time, logging an incident, or — rarely — forcing an order closed.

What the Hub is for

The dispatcher already assigns most orders on its own, every cycle. You open the Hub when something needs a human: an order the algorithm couldn't place, a customer calling about an ETA, a driver who never picked up, a store whose alarms are firing.

If you want to understand why an order was assigned the way it was, that is the dispatcher's logic rather than the Hub's — see What the dispatcher does.

What each action needs

Access is granular on purpose. Holding the Hub view does not imply holding the critical actions.

Action Permission Who typically has it
See orders and status Hub — orders and status hub_operator and above
See an order's pickup code Hub — pickup code Kept separate from assigning, deliberately
Assign a driver Hub — assign hub_operator and above
Unassign a driver Hub — unassign hub_manager
Change the promised time Hub — modify ETA hub_manager, branch_manager
Log an incident Hub — incidents hub_manager, branch_manager
Cancel an order Hub — cancel hub_manager
Force delivery Hub — force delivery hub_manager
View driver alerts Hub — driver alerts hub_operator and above
View branch alarms Hub — branch alarms hub_operator and above
Archive alarms Hub — archive alarms hub_manager
Change alarm thresholds Alarm settings — edit alarms_config_manager

A hub_operator deliberately has the everyday actions but not force delivery, cancel or ETA changes. See Access by section for the full grid.

The pickup code is a separate permission from assigning, even though in practice the same people usually hold both. Keeping them apart means reading a pickup code never has to be bundled with the ability to move orders between drivers.

The pages in this chapter

Task Page
Find an order, understand the board The order board
Look at one order in detail Order details and pickup code
Put an order on a driver, or take it off Assigning and unassigning a driver
Change what the customer was promised Changing the promised time
Record what went wrong Logging an incident
Stop an order entirely Cancelling an order
Close an order the system couldn't close Forcing a delivery
See stores and driver alerts Stores and driver alerts
See and act on store alarms Branch alarms
Tune when alarms fire Alarm settings
Review alarms already dealt with Archived alarms

What you can and can't see

Everything in the Hub is filtered by your scope. A branch_manager sees their own store's orders; a chain-wide role sees all of them. Two colleagues looking at the same board can legitimately see different orders — see How scope works in practice.

Hub

The order board

You need: Hub — orders and status.

The order board is the working list of orders currently in play across the stores in your scope.

Filtering by store

The main filter is stores: pick one, several, or leave it open for everything within your scope.

This is the filter to reach for first. A chain-wide role looking at every store at lunchtime is reading hundreds of rows; narrowing to the two stores actually having trouble makes the board usable.

The store filter narrows within your scope — it never widens it. If a store isn't in the list at all, that's scope, not filtering. See How scope works in practice.

Identifying an order

Every order is identified by four things together, and you need all four when referring to one:

Part What it is
Store Which store the order belongs to
Ticket number The order number at that store
Source Where the order came from — web, mobile app, an aggregator, and so on
Brand Which brand, when the chain runs more than one

A ticket number on its own is not unique across stores. This is why Reporting a dispatcher issue and any support conversation asks for store plus ticket number plus source rather than just a number.

Reading the board

For each order the board shows who it is currently with, what state it is in, and the promised time it is being measured against.

Two terms matter most, and they come from the dispatcher rather than the Hub:

Both are defined in the Dispatcher glossary. An order sitting in Pending is normal between cycles; an order sitting in Critical is the board telling you to intervene.

When an order looks stuck

Before acting by hand, it is worth knowing whether the dispatcher has genuinely given up or simply hasn't run yet:

  1. The dispatcher re-evaluates each store every cycle — by default no more than 60 seconds apart, and up to 300.
  2. An order that failed to place in one cycle is retried from scratch in the next, including a fresh attempt with external carriers.
  3. Only after that does manual intervention add anything.

The common reasons an order legitimately stays unassigned are listed in the Dispatcher FAQ — genuine capacity shortage, a zone that allows no available driver type, or incomplete address data.

Manual assignment has a lasting consequence. An order assigned by a person is permanently locked out of automatic reassignment: the dispatcher will never move it again, even if a much better driver frees up seconds later. Assign by hand when you mean to override the algorithm, not to hurry it along.

From here

Hub

Order details and pickup code

You need: Hub — orders and status for the detail view; Hub — pickup code to see the pickup code, which is a separate permission.

The detail view is the single screen worth screenshotting when you report a problem — it carries the timestamps and the current assignment together.

Opening an order

An order is identified by store, ticket number and source together — see The order board. The detail view needs all of them, which is why you open it from the board rather than by typing a number.

What it tells you

You're asking The detail view answers
Who has it right now? The current driver or carrier, and since when
Is it going to be late? The promised time against the current estimate
What has already happened? Timestamps for each step, including arrival at the store where recorded
Has anything been logged against it? Any incidents recorded on the order

The pickup code

The pickup code is the code a driver or carrier uses to collect the order.

It sits behind its own permission, separate from assigning. In practice the same people usually hold both, but keeping them apart means someone can be given the ability to read a code — to a driver on the phone, say — without also being able to move orders between drivers.

Treat the pickup code like any other collection credential. Read it to the person collecting; don't paste it into a group chat or a ticket, and blank it out of screenshots before attaching them to a support request.

Using it in a support request

If you're reporting something, this screen is the evidence that helps. Include:

What doesn't help is a screenshot of the board, or of an unrelated dashboard. Full checklist in Reporting a dispatcher issue.

From here

Hub

Assigning and unassigning a driver

You need: Hub — assign to assign and to see available drivers. Unassigning is a separate permission, Hub — unassign, typically held only by hub_manager.

Seeing who is available

Open the order and ask for available drivers. The list is built for that specific order — it accounts for the order's store and its zone rules, so it is not simply "everyone on shift".

If the list is empty or shorter than you expect, the reasons are the same ones the dispatcher works from: capacity, zone restrictions on driver types, distance, carrier schedules. When does an alternative exist? lists the carrier checks in order.

Assigning your own driver versus a carrier

These are genuinely different operations, and the difference trips people up:

Own driver Third-party carrier
What you pick The specific driver The carrier company, not a courier
Who chooses the courier You The carrier does
What you can predict Exactly who is going Only that the carrier accepted it

With a carrier you are handing the order to a company. Which of their couriers turns up, and when, is theirs to decide — which is why carrier timing is governed by the limits in External carriers rather than by your choice.

Your own driver types are fixed. The carrier types available depend on what is configured and active for your brand, so the list differs between brands and can change without the Hub changing.

Assigning

  1. Open the order — see Order details and pickup code.
  2. Request available drivers.
  3. Pick an own driver, or a carrier.
  4. Confirm.

This is permanent in one specific sense. An order assigned by a person is locked out of automatic reassignment for good. The dispatcher will not move it later, even if an idle driver appears at the store moments afterwards. That is the intended behaviour — a manual assignment is treated as a deliberate override, not a hint. See When an order changes driver.

Unassigning

Unassigning takes the driver off the order and puts it back in play.

It is a separate, higher permission than assigning because it undoes someone else's action, including the dispatcher's. Use it when an assignment was made in error, or when the assigned driver has become unavailable and you want the order back in the pool.

After unassigning, the order is treated as unassigned again and the next dispatcher cycle will consider it normally.

Unassigning an order that is already with a carrier is not the same as cancelling with that carrier. If your intent is to stop the carrier, see Cancelling an order, which handles the carrier side atomically.

What you cannot do

Hub

Changing the promised time

You need: Hub — modify ETA. Held by hub_manager and branch_manager.

The promised time is what the customer was told, and what the system measures lateness against. Changing it is the right move when the original promise is no longer achievable and the customer has been told — not a way to make a late order look on time.

Choosing a new time

New times come from the store's available promised times, the same set the ordering flow offers. Pick from those rather than inventing a time: they reflect what that store can actually commit to.

The store's promised times are part of its configuration — see Store delivery settings.

You may be asked to confirm

This is the part worth knowing in advance.

When the change has consequences the system wants you to acknowledge, the first attempt does not go through. Instead you are shown the specific warnings and asked to confirm. Confirming re-submits the same change, now with your acknowledgement attached.

What you'll see What it means
The change applies immediately No side effects worth flagging
Warnings and a confirmation prompt Real consequences — read them, then confirm if you still want it
The confirmation has expired You took too long. Start again; the warnings are re-evaluated against the current state

The confirmation is deliberately not a generic "are you sure?". The warnings name what will actually happen. Read them — that is the whole point of the step, and the state may have moved since you opened the order.

Orders already with a carrier

When the order is with an external carrier, the change goes to the carrier first, and only then is it recorded on your side.

That order matters: the carrier call is the irreversible half and the one that can fail. Doing it first means a failure leaves both sides unchanged, rather than leaving your records showing a new time while the carrier's courier is still working to the old one.

If the carrier rejects the change, the promised time is not updated. That is not a bug — it is the system refusing to record a promise the carrier has not accepted.

Before you change it

  1. Has the customer been told? The promised time is a commitment, and changing it silently just moves where the disappointment lands.
  2. Is the real problem the assignment? If the order is simply unassigned, assigning it may be the fix — see Assigning and unassigning a driver.
  3. Is this a pattern? One order is an incident; a store missing its promised times all lunchtime is a configuration or capacity question. See Store delivery settings.
Hub

Logging an incident

You need: Hub — incidents to record one. Reading the incident catalogue needs only Hub — orders and status.

An incident records what went wrong on a specific order, so it can be explained later and counted across orders.

The incident catalogue

Incidents are chosen from a catalogue rather than typed free-hand. The catalogue is what makes incidents countable: "how often did this happen last month" only has an answer if everyone picked the same entry for the same situation.

Alongside the catalogue entry you add a comment. The entry says what kind of problem it was; the comment says what actually happened on this order.

Recording one

  1. Open the order — see Order details and pickup code.
  2. Choose the incident from the catalogue.
  3. Write a comment with the specifics: what happened, what was done, who was involved.
  4. Save.

Writing a comment that's worth reading

The comment is read weeks later by someone who wasn't there. What helps:

What doesn't help: "late", "problem", "see phone call".

Incidents are a record, not an action

Recording an incident does not change the order. It does not reassign, cancel, change the promised time or notify anyone automatically. If the order also needs one of those, do it separately:

Also need to… Page
Move it to another driver Assigning and unassigning a driver
Change what the customer was promised Changing the promised time
Stop it entirely Cancelling an order
Close it as delivered Forcing a delivery

Record the incident as well as taking the action, not instead of it. An order that was force-delivered without an incident explaining why is the hardest kind to reconstruct later.

When to record one

Whenever something happened that a person would need explained later: a late delivery, a missing or wrong item, a driver or carrier failure, a customer complaint tied to this order, or any use of cancel or force delivery.

Consistency matters more than volume. An incident type nobody records is indistinguishable from a problem that never happens.

Hub

Cancelling an order

You need: Hub — cancel. Typically hub_manager only — deliberately not given to hub_operator.

Cancelling stops an order entirely. It is one of the two critical Hub actions, alongside Forcing a delivery.

Before you cancel

Check Why
Is cancelling actually what's wanted? If the order is just going to be late, changing the promised time may serve the customer better — see Changing the promised time
Has the customer been told? A cancellation they learn about from a missing dinner is a different conversation from one they agreed to
Is the order already out for delivery? If the driver has left with it, cancelling here does not recall them
Do you know the reason? It is required, and it is what anyone reviewing this later will read

Cancelling

  1. Open the order.
  2. Choose cancel.
  3. Enter the cancellation reason — required, and worth writing properly.
  4. Confirm.

If the order is with a carrier

When an external carrier holds the order, the cancellation covers both sides together: the order is cancelled with the carrier and released on your side as one operation, not two.

This matters because the failure mode it prevents is a nasty one. Cancelling only your side would leave the carrier still holding a live order, with a courier on the way to collect something nobody expects them to collect.

If the carrier side fails, the cancellation does not silently half-apply. Check the order's state afterwards rather than assuming it went through, and retry rather than cancelling again from a different screen.

Write a real reason

The reason is the only explanation that survives. It is read by whoever handles the customer's follow-up, and by anyone reviewing cancellation rates for that store.

Useful: "Customer called to cancel — ordered twice by mistake, ticket 4471 kept." Not useful: "cancel", "error", "customer".

Also log an incident

Cancelling records that the order stopped, with your reason. It does not categorise the cancellation into anything countable.

If the cancellation came from something that went wrong — rather than a customer simply changing their mind — log an incident as well, so it shows up in the counts. See Logging an incident.

What cancelling does not do

Hub

Forcing a delivery

You need: Hub — force delivery. Typically hub_manager only. This is the most consequential action in the Hub — read the whole page before using it.

Force delivery closes an order as delivered when the normal flow could not close it — most often because the driver's device failed to register the delivery, or an external carrier never reported completion.

What it actually does

It records the order as delivered, with a driver and a distance that you supply rather than ones the system observed.

That is the whole point, and the whole risk: you are asserting something the system could not confirm. Everything downstream — delivery counts, driver figures, distance-based reporting — takes your word for it.

Use it only when the delivery really happened

Force delivery is for correcting a recording failure, not an operational one.

Situation Force delivery?
Customer received the order; the app never registered it ✅ Yes — that is exactly this
Carrier delivered but never reported back ✅ Yes
Order is very late and you want it off the board ❌ No — it is still in progress
Order was never delivered ❌ No — cancel it instead
You are not sure whether it was delivered ❌ No — find out first

Forcing an order that was never delivered puts a false delivery into your records permanently. There is no clean undo. When in doubt, confirm with the driver or the customer before acting.

Doing it

  1. Open the order — see Order details and pickup code.
  2. Choose force delivery.
  3. Enter who delivered it: your own driver, or the carrier. For an own driver you name the specific person; for a carrier the company is enough, since the courier is theirs.
  4. Enter the estimated distance for the delivery.
  5. Confirm.

The distance matters

The distance you enter is used as the delivery's distance. It feeds driver figures and any distance-based reporting or settlement.

Estimate it honestly from the store to the delivery address. A placeholder — zero, or a round number entered to get past the field — quietly corrupts whatever is calculated from it, and nobody will notice until the numbers are questioned months later.

Always log an incident too

A forced delivery with no incident is the hardest thing to reconstruct later: the record shows a normal delivery, with nothing explaining why a person had to close it by hand.

Log an incident describing why the force was needed — device failure, carrier silence, whatever it was. See Logging an incident.

If you are unsure

Do something reversible instead. Change the promised time, log an incident, or leave the order alone and escalate. Every other Hub action can be worked around afterwards; this one cannot.

Hub

Stores and driver alerts

You need: Hub — orders and status for the store view, Hub — driver alerts for driver alerts.

Alongside the order board, the Hub shows the state of your stores and raises alerts about drivers.

The store view

A per-store operational view of the stores within your scope: what each one currently has in play, so you can tell at a glance which store needs attention rather than reading the whole order board.

Use it as the entry point during a busy service. Find the store that looks wrong, then drill into its orders.

This is the Hub's operational view of a store. Changing how a store behaves — delay tolerances, pausing delivery — happens elsewhere; see Store delivery settings and Pausing and resuming delivery.

Driver alerts

Driver alerts flag drivers whose behaviour needs looking at rather than orders that are late.

The most common is the pickup delay alert: a driver has been at the store for too long without leaving with an order that is ready. It fires from the same at-store determination the dispatcher uses for priority — roughly 350 metres from the store. See Driver classification and priority for what "at store" means and everywhere else it is used.

Others cover drivers who appear stuck or unavailable in ways that will affect assignment if left alone.

Acting on an alert

An alert is a prompt, not an instruction. Work out which of these it is:

What you find What to do
Driver is genuinely delayed at the store An operational conversation, not a console action
Driver's device or connection has dropped Their orders may need reassigning — Assigning and unassigning a driver
Driver has finished but the system doesn't know The order may need Forcing a delivery — read that page first
The alert is firing too readily across many drivers The threshold is wrong — Alarm settings

A single alert is about one driver. The same alert firing across many drivers at once is about the threshold, or about something systemic at that store. Don't work through fifty alerts one at a time — check the threshold first.

Alerts, alarms, incidents

Three similar-sounding things that are genuinely different:

What it is Where
Driver alert The system flagging a driver's state This page
Branch alarm The system flagging a store's state Branch alarms
Incident A person recording what went wrong on an order Logging an incident

The first two are raised automatically and you respond to them. The third is created by you and is a permanent record on one order.

Hub

Branch alarms

You need: Hub — branch alarms to view. Archiving needs Hub — archive alarms, typically hub_manager.

Branch alarms flag that a store needs attention — as opposed to driver alerts, which flag a person, and incidents, which you record yourself.

What they tell you

An alarm fires when a store crosses a configured threshold: too much load, too many cancellations, too many orders missing their promised time. What counts as "too much" is configurable per alarm type — see Alarm settings.

An alarm is a signal, not a diagnosis. It tells you where to look, not what is wrong.

Working through them

  1. Look at the store, not the alarm. Open its orders and see what is actually happening.
  2. Decide whether it is an operational problem or a threshold problem. One store alarming during a genuine rush is the system working. Every store alarming every lunchtime means the threshold is wrong.
  3. Act on the underlying issue, if there is one — reassign, pause delivery, change a promised time.
  4. Archive the alarm once it has been handled.

Archiving

Archiving marks an alarm as dealt with and takes it off the active view. It doesn't delete it: archived alarms remain available for review — see Archived alarms.

Archive when the alarm has been handled or understood, not merely seen. An alarm archived without being looked at is worse than one left active, because it now looks resolved to everyone else.

Archiving is a higher permission than viewing, on purpose. Anyone on shift can see what is firing; deciding something has been dealt with is a shift-manager judgement.

When the board is full of alarms

Alarms that fire constantly stop being read. If a store or an alarm type is permanently lit:

Tuning a threshold so it fires when someone should act, and stays quiet otherwise, is worth more than working through a long list.

Hub

Alarm settings

You need: Alarm settings — view to read, Alarm settings — edit to change. The dedicated role is alarms_config_manager; admin also has it.

Alarm settings decide when an alarm fires. They apply across the whole chain, not per store.

The three families

Type Watches Example of what it catches
Order Individual orders Orders sitting too long, or past their promised time
Driver Drivers A driver at the store too long without leaving — the pickup delay alert
Branch Stores A store under too much load, or with too many cancellations

Each family holds several individual alarms. You can browse a family, open one alarm and change its thresholds or turn it off.

Chain-wide, not per store

This is the thing to internalise before changing anything: a threshold applies to every store.

Tuning an alarm because one busy city-centre store is noisy also retunes it for the quiet suburban ones — where it may now never fire at all. You are always trading a false-positive problem at one store for a false-negative problem at another.

If the real need is genuinely per store, a chain-wide threshold cannot express it. Set the threshold for the majority, and handle the outlier operationally rather than by moving the number until that one store goes quiet.

Changing a threshold

  1. Open the alarm family — order, driver or branch.
  2. Open the specific alarm.
  3. Change the threshold, or switch the alarm off.
  4. Save.

Changes affect what fires from then on. They do not retroactively clear alarms already raised — clear those by archiving them, see Branch alarms.

Choosing a number

A good threshold fires when someone should act and stays quiet otherwise. Both failure modes are real:

Too sensitive Too lax
Fires constantly Fires rarely or never
People stop reading alarms Real problems pass unnoticed
Genuine problems buried in noise Discovered from customer complaints instead

The second is more dangerous; the first is more common — and it causes the second, because an alarm board nobody reads is functionally an alarm that never fires.

Before changing a number, look at what actually fired over the last week or two. Tuning from a specific bad shift produces a threshold shaped by an outlier.

Turning an alarm off

Switching one off is legitimate when it does not apply to how you operate. It is not a fix for an alarm that fires too often — that is a threshold question, and turning it off removes the signal entirely rather than sharpening it.

Note what you turned off and why. An alarm silently disabled a year ago is indistinguishable from one that never fires.

Hub

Archived alarms

You need: Archived alarms — view. Exporting needs the metrics export permission. hub_manager holds the view; chain-wide export is typically admin.

Archiving an alarm doesn't delete it. Archived alarms are kept and can be reviewed later — the history is where you find patterns that no single shift reveals.

Where to find them

Archived alarms live with Metrics, not with the live Hub board. That split is deliberate: the Hub is for what needs acting on now, Metrics is for what happened.

What the history is for

Question How the history answers it
Is this store always like this? Compare its alarm volume against comparable stores over the same period
Is our threshold sensible? An alarm archived in seconds every time is firing too readily — see Alarm settings
Did that change help? Compare the weeks either side of a configuration change
Which alarms does nobody act on? An alarm type that is always archived immediately, with nothing else happening, is noise

Tuning thresholds from history

This is the main reason the history exists. Before changing a threshold in Alarm settings, look at what that alarm actually did over a representative period — a fortnight, not one bad shift.

Two patterns are worth acting on:

Remember thresholds are chain-wide: a change made to quieten one store changes every store.

Exporting

The history can be exported for analysis outside the console. Export is a separate, higher permission than viewing, because an export leaves the console's access controls behind entirely.

An exported file is no longer scope-filtered. Whoever opens the spreadsheet sees everything in it, regardless of what they could see in the console. Treat exports accordingly, and prefer sharing a conclusion over the raw file.

Marketing

Promotional codes, vouchers, personal promotions, subscriptions and wallet credit.

Marketing

The Marketing screen

To access the code management section, go to the MARKETING menu in the console's central panel.

Marketing - Code management

In the sidebar, you'll find all the sections available for viewing, editing, creating, or expiring codes: Promotional codes, Vouchers, Personal promotions, Loyalty subscriptions, and Wallets.

Marketing sidebar

Each section loads a table containing the data for those codes. At the top of each section, you'll find the available options:

Options available at the top of each section

Only CSV files are accepted, and they must strictly comply with the specifications.

CSV specifications and import

Selecting Show CSV specifications displays all the necessary information for that section on screen: how the first row of the CSV must be formatted, followed by a table with the required fields, a description of each field, and the allowed values.

CSV specifications

The SELECT CSV button is only enabled once all required fields (if any) have been filled in.

Once a file is selected, if it passes validation (meets all requirements), a "File successfully validated" message appears next to the file, and the Upload CSV button becomes available.

File successfully validated

Once the import begins, a message shows the status of the process, and a confirmation message appears when it finishes.

If the selected file fails validation, a "Validation Error" message appears next to the file, followed by a list of all errors found. At that point you can only select another file with those errors corrected — the upload button stays disabled until validation succeeds.

Invalid file, with a list of errors

Other available actions

Search filters

Marketing

Marketing: the five areas

Audience: marketing and customer-care staff who issue promotions, vouchers, subscriptions and wallet credit. You need: a permission per area — they are separate, and holding one grants nothing in the others.

Marketing covers five independent areas. They look similar and behave similarly, but each has its own data, its own permission, and its own rules.

Area What it holds Permission
Promotional codes Campaigns and the coupons generated from them Promotional codes — view / edit
Vouchers Single-use vouchers of a fixed amount Voucher manager — view / edit
Personal promotions Promotions attached to specific customers Customer promo manager — view / edit
Loyalty subscriptions Customer subscriptions Subscriptions manager — view / edit
Wallets Customer wallet credit and its movements Wallet manager — view / edit

Each area also has a CSV import permission of its own, separate again from view and edit. Someone who can edit wallet records cannot necessarily import wallet credit in bulk.

Finding the screens

All five live under the Marketing menu, each with its own section in the sidebar and the same row of options at the top — brand selector, export, import. The Marketing screen walks through that layout with screenshots, including the CSV specification panel each section provides.

Two things shared by all five

Before using any area, read these two pages. They explain mechanics that repeat everywhere and cause most of the confusion:

The rule that makes this safe

Across every area, bulk operations act only on records that have not been redeemed. A voucher a customer has already used, a wallet credit already spent, a coupon already applied to an order — these are never touched by a bulk update or a bulk delete.

This is what makes bulk changes recoverable in practice: the worst case is that you change records nobody has used yet.

The one place this bites is when the count comes back smaller than you expected. That usually isn't a filter problem — it's redemptions being excluded, exactly as intended.

Picking the right area

You want to… Area
Run a campaign with codes customers enter Promotional codes
Give one customer a fixed-value voucher Vouchers
Attach an offer to specific customers Personal promotions
Manage a customer's subscription Loyalty subscriptions
Add or adjust customer credit Wallets

These overlap less than they appear. A voucher is a fixed amount; a promotional code is a campaign rule; wallet credit is a balance. Choosing by what the customer receives gets it right nearly every time.

The pages in this chapter

Topic Page
The shared bulk mechanics How bulk changes work
The shared import mechanics Importing from a CSV
Campaigns, coupons, offers Promotional codes
Importing promotional codes Importing promotional codes
Fixed-value vouchers Vouchers
Customer-specific offers Personal promotions
Subscriptions Loyalty subscriptions
Finding a customer's wallet Wallets: finding a customer
Adding and adjusting credit Wallets: managing records

What you can and can't see

Everything here is scoped to the brand you are working in, and filtered further by your own scope — see How scope works in practice.

Marketing

How bulk changes work

The five Marketing areas are introduced in Marketing: the five areas.

Wallets, vouchers, personal promotions and promotional codes all support changing many records at once. They follow the same three-step shape, and learning it once covers all four.

The three steps

Step What it does Permission
1. Check Counts what would be affected. Changes nothing The area's view permission
2. Apply Starts the change as a background job The area's edit permission
3. Track Follows the job until it finishes The area's edit permission

The check step is deliberately harmless and deliberately separate. It exists so you can see the blast radius before committing to it.

Always run the check. It takes seconds and it is the only preview you get. A count that looks wrong — far larger or far smaller than expected — means your criteria are wrong, and that is much cheaper to discover now.

Step 2 runs in the background

Apply does not finish while you wait. It returns a job that runs on its own, and you follow its progress.

This matters in three ways:

Already-redeemed records are never touched

Every bulk operation acts only on records that have not been redeemed.

Area What is protected
Wallets Credit already spent
Vouchers Vouchers already used
Personal promotions Promotions already applied to an order
Promotional codes Coupons already redeemed

You cannot retroactively change or remove value a customer has already received. This is why bulk operations are recoverable in practice, and it is also the usual explanation for a count being smaller than expected.

Delete and update are separate operations

Bulk update changes fields — typically dates or amounts — on matching records. Bulk delete removes them.

Both are protected by the same non-redeemed rule, and both have their own check step. They are not variants of one action: pick the one you mean.

Promotional codes work differently — read this

Promotional codes use the same three words for a materially different operation.

In wallets, vouchers, personal promotions In promotional codes
Check counts matching records Check asks whether the campaign has any redeemed coupons
Apply updates matching records Apply deletes the whole campaign and its coupons — and only if none has been redeemed

So in promotional codes, "apply bulk changes" is a delete, gated on the campaign being entirely unused. If even one coupon has been redeemed, it will not proceed.

To retire a campaign that has been used, expire it instead — see Promotional codes.

This is the single most dangerous naming overlap in the chapter. In four areas "apply" means update; in promotional codes it means delete a campaign. Check which screen you are on before clicking it.

A safe sequence

  1. Set your criteria narrowly.
  2. Check, and read the count.
  3. If the count surprises you, stop and work out why.
  4. Apply.
  5. Track to completion.
  6. Spot-check a couple of affected records.

If a job seems stuck

Give it time proportional to the count — tens of thousands of records take a while. If progress genuinely stops advancing, don't re-run the apply: a second job on the same criteria can compound the first. Report it with the area, the criteria and roughly when you started.

Marketing

Importing from a CSV

Four of the areas described in Marketing: the five areas accept a CSV, so you can issue something to many customers at once.

Import What it creates Permission
Personal promotions A promotion per customer, from a phone list Personal promotions — import
Loyalty subscriptions A subscription per customer, from a phone list Loyalty subscriptions — import
Wallet credit Credit per customer, from a phone list Wallet codes — import
Vouchers Voucher codes Voucher codes — import

Promotional codes also import from CSV, but with progress tracking the others don't have — it gets its own page, Importing promotional codes.

Each import permission is separate from the area's view and edit permissions. Being able to create wallet records one at a time does not imply being able to load thousands from a file.

Phone lists

Three of the four identify customers by phone number. The file is a list of phones plus whatever the import needs — an amount, a set of dates.

Phone numbers are where these imports go wrong. Before importing:

Before any import

  1. Start with a handful of rows. Import five, confirm they landed as intended, then import the rest. This catches format problems for the price of five records instead of five thousand.
  2. Know what happens to an existing customer. Whether a second import adds to what they have or replaces it decides whether re-running a file is safe.
  3. Keep the file. It is the only record of exactly what you sent, and the only way to reverse it if you need to.

Imports are not transactional

An import that fails partway through does not roll back what it already did. Some customers will have received the benefit and others won't.

That is why the small test import matters, and why re-running a whole file after a partial failure is risky: the rows that already succeeded may be applied a second time.

If an import fails partway, work out where it stopped before deciding what to do — don't simply re-submit.

After importing

Spot-check two or three customers from the file and confirm they received what you intended, with the right amount and the right dates. The area's own browse screen is the place to do it: Personal promotions, Loyalty subscriptions, Wallets: finding a customer or Vouchers.

If you need to undo one

There is no "undo import". What you have instead is a bulk delete, which removes matching non-redeemed records — see How bulk changes work.

Anything customers already redeemed stays. This is the honest limit of reversing an import: you can take back what hasn't been used, not what has.

Marketing

Promotional codes

You need: Promotional codes — view to browse, Promotional codes — edit to create or change anything.

Promotional codes are organised as campaigns that generate coupons. Getting that relationship right makes the rest of the screen obvious.

Term What it is
Promotional code The rule: what the discount is, when it is valid
Campaign A promotional code plus the set of coupons generated from it
Coupon One individual code a customer actually enters

A campaign is created with its first coupon. You then add further coupons to it as needed.

Browsing

The main list supports filters and pagination. From a campaign you can open its generated coupons — the individual codes — and see or edit them one at a time.

Active offers is a separate view: the offers currently live for a given store, with the detail of any one of them. Use it to answer "what can this store actually offer right now", which is not the same question as "what campaigns exist".

Creating

To create Use
A standalone promotional code Create promotional code
A campaign, with its first coupon Create campaign
Another coupon on an existing campaign Add coupon

Create the campaign first, then add coupons to it. Creating separate codes that were meant to be one campaign leaves you unable to manage them together afterwards.

Editing

Two different edits, at two levels:

Editing the code changes the rule for the campaign. Editing a coupon changes one customer-facing code. If a customer reports a problem with one code, the coupon is usually the right level.

Expiring versus deleting

This is the decision that matters most, and the two are not interchangeable.

Expire Delete
What it does Sets the end date to today — the code stops working from now Removes the campaign and its coupons entirely
Redeemed coupons Fine — history is preserved Blocked. Will not proceed if any coupon has been redeemed
Reversible The record still exists No
Use when A live campaign should stop A campaign was created in error and never used

Expiring is almost always the right answer. It stops the campaign while keeping the record of what happened, which is what you need when a customer asks why their code stopped working.

There is also a bulk expire, which marks every coupon of a campaign as used in one go. Use it to close a campaign out completely rather than letting unredeemed coupons linger.

Deleting a campaign is the operation described under "apply bulk changes" on this screen — a naming overlap that means something different everywhere else in Marketing. Read How bulk changes work before using it.

If a customer's code doesn't work

Check in this order:

  1. Is the campaign still within its dates? Including the valid times, not just the days.
  2. Has that specific coupon already been redeemed? Open the generated coupons and look.
  3. Is the offer live for that store? Check active offers for that store — a campaign can exist without being offered everywhere.
  4. Was it bulk-expired? A campaign closed out has all its coupons marked used.
Marketing

Importing promotional codes

You need: Promotional codes — edit.

Promotional codes are the one import with full job tracking. Unlike the other CSV imports in Importing from a CSV, you can see a running import's progress, and you get told if one is already going.

One active import at a time, per person

The import tracks an active job for you. Before starting, the screen tells you whether you already have one running.

This is a guard rather than a limitation. It stops the common accident of starting an import, seeing no immediate feedback, and starting it again — which would apply the same file twice.

What you see What it means
No active import Clear to start
An active import Yours is still running. Watch it rather than starting another
An active import you don't recognise Something you started earlier and left. Check its progress before clearing it

Running one

  1. Check no import is already active for you.
  2. Upload the CSV.
  3. Follow the progress as it runs.
  4. Confirm the result before telling anyone the codes are live.

Progress

The progress figure is polled, so it lags slightly — a number that hasn't moved for a few seconds is normal. Large files take proportionally longer.

Closing the screen does not stop the import. It runs to completion on its own, and you can come back to its progress.

Clearing a stuck active job

You can clear your active import. What that means is worth being precise about:

Clearing removes the record that you have an import in progress. It does not undo rows already imported, and it isn't a cancel button. Use it when a job is genuinely finished or abandoned and is blocking you from starting a new one — not to stop a running import you've changed your mind about.

If you clear a job and start the same file again, the rows that already imported may be applied twice. Check what landed first.

Before importing

The general advice in Importing from a CSV applies here too, particularly:

After importing

Open the promotional codes list and confirm the codes exist with the dates and validity you expected — see Promotional codes. If they need to be part of a campaign, confirm that too, because a campaign relationship is hard to add afterwards.

If it goes wrong

Removing imported codes uses the campaign delete described in Promotional codes, which only proceeds when nothing has been redeemed. Once customers start using codes, they stay — expire the campaign instead.

Marketing

Vouchers

You need: Voucher manager — view to browse, Voucher manager — edit to create or change. Importing needs Voucher codes — import, which is separate again.

A voucher is a fixed amount a customer can redeem once. Simpler than a promotional code — there is no campaign, no rule, just a value and a validity period.

Browsing

The list shows available vouchers — those not yet redeemed — for the brand.

Redeemed vouchers are not in this list. That is deliberate: the screen is for vouchers still in play. If you are looking for one a customer says they used, its absence here is the answer.

Creating one

Create a voucher with its amount and validity. This is the right path for a single customer — a service recovery, a goodwill gesture, a one-off.

For many vouchers at once, import them instead — see Importing from a CSV.

Editing

You can update an existing voucher: its amount, its dates. Only vouchers that haven't been redeemed can be changed, which is the same rule that protects bulk operations.

Expiring

Expiring ends one or more vouchers immediately. Use it when a voucher was issued in error, or when a promotion is being pulled.

Expiring is the safe option: the record survives, so there is still an answer when the customer asks what happened.

Bulk changes

Vouchers support the standard bulk pattern — read How bulk changes work first.

Voucher bulk operations match on starting date, ending date, amount and validity days together. All four form the criteria; they are not filters you can partly fill in and hope for the best.

Operation Effect
Check Counts non-redeemed vouchers matching all four criteria
Bulk update Updates every matching non-redeemed voucher
Bulk delete Removes every matching non-redeemed voucher

Because the criteria are a combination, it is easy to match more than you meant. Run the check and read the count — it is the only preview.

Only non-redeemed vouchers are ever affected. A customer who already used theirs keeps the benefit, whatever you do here.

Choosing between a voucher and wallet credit

They feel similar and behave differently:

Voucher Wallet credit
Shape A fixed amount, used once A balance that can be spent down
Good for A specific gesture with a clear value Ongoing credit, refunds, loyalty balance
Expiry Per voucher Per credit record

If the customer should have "€10 off one order", that is a voucher. If they should have "€10 to spend", that is wallet credit — see Wallets: managing records.

Marketing

Personal promotions

You need: Customer promo manager — view to browse, … — edit to change. Importing needs Personal promotions — import, separate again.

A personal promotion attaches an existing offer to a specific customer. Where a promotional code is something any customer can enter, this is granted to one person.

What you can attach

The available promos view lists what can be attached for a given store. It is deliberately not the full catalogue — it shows offers that are:

If an offer you expect isn't in the list, it is usually one of those three: it is a public offer rather than a grantable one, or it has expired. That is the list doing its job, not a missing record.

Browsing existing records

Search customer promo records to see what a customer already has, or to review what was granted in a campaign of individual grants.

Granting one

  1. Find the offer under available promos for the relevant store.
  2. Create the record against the customer.
  3. Set the dates it is valid between.

For many customers at once, import a phone list instead — see Importing from a CSV.

Changing and removing

Action Applies to Note
Update dates Non-redeemed records only Extend or shorten validity
Delete Non-redeemed records only Removes the grant entirely

Both are limited to records the customer hasn't used. Once redeemed, a personal promotion is part of that customer's history and stays.

To withdraw an offer a customer has not used, shortening the dates is gentler than deleting: the record survives, so there is an answer if they ask.

Bulk changes

Personal promotions follow the standard pattern — read How bulk changes work first.

Here the criteria are a promo or offer code: you are acting on every record granting that particular offer.

Operation Effect
Check Counts records matching the promo/offer code
Bulk update Changes the start and end dates on every matching non-redeemed record
Bulk delete Removes every matching non-redeemed record

This is how you correct a grant campaign that went out with the wrong dates, without touching customers who already used theirs.

Choosing between this and a promotional code

Personal promotion Promotional code
Who can use it One named customer Anyone with the code
How they get it Granted to them They enter a code
Good for Win-back, VIP treatment, service recovery Public campaigns

If you find yourself granting the same offer to hundreds of customers individually, a campaign with coupons is probably the better tool — see Promotional codes.

Marketing

Loyalty subscriptions

You need: Subscriptions manager — view to browse, … — edit to change. Importing needs Loyalty subscriptions — import, separate again.

A subscription gives a customer an ongoing benefit for a period, rather than a single-use code or amount.

This is the smallest area in Marketing: browse, create, update, expire. There are no bulk operations here — changes are per subscription, or via an import.

Finding a subscription

Search either way round:

Searching by customer is the usual path when someone gets in touch.

Creating one

Create the subscription against the customer with its period. For many customers at once, import a phone list instead — see Importing from a CSV.

Updating

An existing subscription can be updated — typically its dates. Use this to extend a subscription, or to correct one entered wrongly.

Expiring

Expiring sets the subscription to end today. It stops the benefit from now on without removing the record of it having existed.

There is no delete here, and that is the right design: a subscription a customer has held is part of their history. Expiring is the complete answer for "this should stop".

Because expiry lands on today rather than a date you choose, it takes effect immediately. If the customer should keep the benefit until the end of a paid period, update the end date instead of expiring.

Common situations

Situation What to do
Customer says their subscription ended early Check the end date; update it if it was entered wrongly
Customer wants to cancel Expire it, or set the end date to the end of their paid period
Subscription created against the wrong customer Expire it and create the right one. There is no delete
Bulk-issuing subscriptions Import a phone list — Importing from a CSV

Choosing between a subscription and the alternatives

Subscription Personal promotion Wallet credit
Shape Ongoing benefit for a period A specific offer, granted once A spendable balance
Ends by Date Use, or date Being spent, or date

If the benefit is "free delivery for three months", that is a subscription. If it is "20% off their next order", that is a personal promotion — see Personal promotions.

Marketing

Wallets: finding a customer

You need: Wallet manager — view.

Most wallet work starts with a customer on the phone. This page is how you get from what they can tell you to what you need on screen.

Start from the phone number

Customers know their phone number. They rarely know their customer ID.

The lookup by phone resolves a phone number to the customer, which is the identifier the rest of the wallet screens use. Start here.

If the lookup finds nobody, the usual cause is a format mismatch — country prefix, spaces — rather than the customer not existing. Try the variant the brand stores before concluding they have no account. The same trap catches CSV imports, see Importing from a CSV.

Check the balance

With the customer identified, the balance answers the first question: how much credit do they have right now.

The balance is the net result of their wallet records. When it doesn't match what the customer expects, the records explain why — some may have expired, some may already be spent.

Read the records

Wallet records are the individual movements making up the balance. Searching them, filtered to that customer, shows how the balance was arrived at.

This is where "I had €20 and now I have €5" gets answered: either the credit was spent, or a record reached its end date.

Open the order behind a record

Where a record is linked to an order, you can open that order's full detail.

This closes the loop on the most common dispute — "I was charged even though I had credit". The order detail shows what was actually applied.

A working order for a customer call

  1. Phone → customer. Confirm you have the right person.
  2. Balance. What do they have now?
  3. Records. How did it get that way?
  4. Order detail, where a record points at one. What was actually applied?

By step 4 you can usually explain the discrepancy without changing anything — which is the better outcome, since adding credit to close a conversation hides the underlying cause.

When the answer is that something is wrong

If the records genuinely show a mistake, fixing it is on Wallets: managing records — creating a correcting record, adjusting one, or expiring it.

Prefer a new correcting record over editing history. It leaves the original visible alongside the correction, which is what anyone reviewing this later needs to see.

Marketing

Wallets: managing records

You need: Wallet manager — edit to create or change records. Browsing needs only the view permission. Importing credit needs Wallet codes — import, separate again.

A wallet record is one movement of credit. The customer's balance is the net of their records — so you never edit a balance directly, you add or adjust the records behind it.

Adding credit

Create a record against the customer with its amount and the dates it is valid between. This is the manual path: service recovery, a goodwill gesture, a correction.

For many customers at once, import a phone list — see Importing from a CSV.

Set an end date deliberately. Credit with an unnecessarily long life is a liability that sits on the books; credit that expires sooner than the customer expects becomes a complaint. Pick the date on purpose rather than accepting a default.

Adjusting a record

An existing record's end date and amount can be updated.

Use this to correct a genuine data-entry error. For anything a customer has already seen, prefer adding a correcting record instead: editing the original rewrites what the customer was told, and leaves nobody able to see what happened.

Expiring records

Expiring ends one or more records immediately. The credit stops being spendable from now on, and the record stays visible.

This is the right tool for credit issued in error, or for closing out a promotion. It is gentler than deletion and it preserves the explanation.

Bulk changes

Wallets follow the standard pattern — read How bulk changes work first.

The criteria are starting date, ending date, amount and, optionally, a comment.

Operation Effect
Check Counts non-redeemed records matching the criteria
Bulk update Updates every matching non-redeemed record
Bulk delete Removes every matching non-redeemed record

The comment is the most useful criterion you have. If you tag a batch with a distinctive comment when you create it, you can later act on exactly that batch and nothing else. Without it you are matching on dates and amount, which will eventually catch records from a different campaign that happen to share them.

Credit already spent is never affected, whatever you do here.

Deciding what to do

Situation Action
Customer owed compensation Create a record
Credit issued at the wrong amount Create a correcting record; don't edit the original
Credit issued to the wrong customer Expire it, then create it on the right customer
A whole batch issued with the wrong dates Bulk update, matched on the batch's comment
A batch that should never have gone out Bulk delete — removes only what nobody has spent

Before any bulk operation

  1. Run the check and read the count.
  2. If it isn't what you expected, your criteria are wrong — especially if you are matching without a comment.
  3. Apply, then track to completion.
  4. Spot-check a customer from the batch on Wallets: finding a customer.

CMS

Web content: complaints tree, resources, banners and documents.

CMS

CMS: what it covers

Audience: content editors maintaining what customers see on the ordering channels. You need: CMS — view to browse, CMS — edit to change, CMS — delete to remove. Three separate levels.

The CMS covers the content layer of the ordering experience: the images and text customers see, and the complaints structure behind customer service.

Two areas

Area What it holds
Resources Banners, logos, documents, and the presentation of promotions, products, toppings and payment methods
Complaints The tree of complaint types used when logging a customer complaint

They share the same permissions but are otherwise independent.

Three permission levels, not two

Most console areas have view and edit. The CMS has a third:

Level Lets you
View Browse resources and the complaints tree
Edit Create and change resources, and add or edit complaint nodes
Delete Remove a node from the complaints tree

Delete is deliberately separate. Removing a node from the complaints tree affects how complaints are categorised from that point on, which is harder to reverse than editing a label.

cms_editor is the role built for this area and holds all three.

Content is per source

This is the concept that makes the rest of the CMS make sense.

Resources are stored per source — web, app, kiosk, each aggregator. The same brand can show a different banner on the web than in the app, because they are different records.

So when you edit a resource you are always editing it for a source. Changing the web banner does not change the app banner.

This also means "the banner didn't change" is usually the wrong source selected rather than a failed save. Check the selector before re-uploading.

Your own scope can further limit which sources you see — see How scope works in practice.

The pages in this chapter

Topic Page
Resource types and the source selector Resources and sources
Finding incomplete content Content validation
The complaints tree The complaints tree
Editing banners, step by step CMS - Resources: Banners
Documents per language CMS - Resources: Documents
The resources screen CMS - Resources
Loading complaints from a file CMS - Complaints CSV Upload
CMS

Resources and sources

You need: CMS — view to browse, CMS — edit to change.

Resources are the content records behind what customers see. This page covers the model; CMS - Resources walks through the screen itself with screenshots.

The resource types

Type What it controls
Banners Promotional images and where they link to
Logos Brand imagery
Promotions How promotions are presented
Products How articles are presented
Toppings How ingredients and extras are presented
Payment methods Which payment options appear, and how

Editing here changes presentation, not behaviour. A promotion's rules live in Promotional codes; what the customer sees when it is offered lives here. The same split applies to products and payment methods.

Always pick the source first

Every resource belongs to a source — web, app, kiosk, an aggregator. Selecting the source is the first thing you do, not an afterthought.

If a type has no content for the chosen source, the screen says so. That is a real answer: it means nothing is configured for that combination, not that the screen failed.

What you see What it means
Content listed That type is configured for that source
"No data available" Nothing configured for that type and source
A source missing from the list Outside your scope, or not enabled for the brand

Languages

Several resource types are per language as well as per source — banners and documents in particular. A banner exists once per language, and each language needs its own image and destination.

That means a resource is not complete until every language is filled in. A missing translation shows as a gap for customers in that language only, which is exactly the kind of thing nobody notices internally.

CMS - Resources: Banners covers the per-language banner flow, and CMS - Resources: Documents the document one.

Before you finish

  1. Confirm the source you edited was the one you meant.
  2. Check every language for that resource, not just the one you were asked about.
  3. Run the validation list to catch anything left incomplete — see Content validation.
CMS

Content validation

You need: CMS — view.

The validation list shows resources that are incomplete — the gaps that would otherwise only surface as something missing on a customer's screen.

Why it exists

Resources are stored per source and, for several types, per language. That produces a lot of combinations, and a gap in any of them is invisible unless you go looking: the affected customers are the ones on that one source, in that one language.

Validation is the going-looking, done for you.

When to run it

Moment Why
After a bulk content change The fastest way to find what didn't land
Before a campaign goes live A missing banner on one source is a campaign that partly didn't run
When adding a new source or language Everything is a gap until it isn't
Routinely Content decays as products and promotions change around it

Running it before a launch is worth more than running it after. A gap found the day before is a fix; found the day after, it is an incident.

Reading it

Each entry points at a specific combination — a type, a source and where relevant a language. That is enough to go straight to the right screen and fill it.

Work by source rather than down the list. Fixing everything wrong with the web in one pass is faster than jumping between sources, because you keep the same selector.

Not everything listed is a problem

A gap is only a problem if that combination should have content. If your brand doesn't use the kiosk, kiosk resources being empty is correct.

Get to know which combinations matter for your brand; after that the list is short and every entry means something.

CMS

The complaints tree

You need: CMS — view to browse, CMS — edit to add or change, CMS — delete to remove.

The complaints tree is the structure of complaint types used when a customer complaint is logged. It is what makes complaints countable: a tree everyone uses the same way turns individual annoyances into a pattern you can act on.

Browsing

The tree is a hierarchy of nodes — broad categories at the top, specific types beneath. Browse it to see the current structure before changing anything.

Adding and editing a node

Add a node under the right parent, or edit an existing one.

Changing a label changes it everywhere, including on complaints already filed under it. That is usually what you want when correcting wording. It is not what you want when the meaning shifts — if the node should now mean something different, add a new one and stop using the old.

Deleting a node

Delete has its own permission, and for good reason. Removing a node changes how complaints can be categorised from that moment on, and existing complaints filed under it lose the structure that explained them.

Before deleting, ask:

Question If yes
Have complaints been filed under it? Prefer stopping its use over deleting it
Is it a duplicate of another node? Consolidate deliberately, and note which absorbed which
Was it created by mistake and never used? Safe to delete

Keep the tree small

A tree that grows a node per incident stops being useful: with sixty options, nobody picks consistently, and the counts mean nothing.

Two tests before adding a node:

  1. Would a different person pick this node for the same complaint? If it overlaps an existing one, it will be used inconsistently.
  2. Would you act differently on this than on its neighbour? If not, it doesn't need to be separate.

Loading many at once

The tree can be loaded from a file rather than built node by node — see CMS - Complaints CSV Upload, which covers the format and the flow in detail.

As with every import, start small and confirm the structure before loading everything.

CMS

CMS - Complaints CSV Upload

Overview

The Complaints Management CSV Upload system allows you to upload and manage complaint flow data using two CSV files - one in English and one in Arabic. This system provides validation, preview functionality, and error handling to ensure data integrity.

Code Reference Legend

Actions

Code Definition
X Go to next node
Q Question to a customer
QP Ask for proof to a customer, upload picture
S Show customer order to pick an item
CB Call back to customer
R Refund
R30 30% refund of the item in default
T Rating
TT Ticket Transfer to agent for manual evaluation
QD Dialog box
QPD Both Dialog Box and Picture upload
PHONE Provide phone number of the delivery partner in the variable field {%phone%}
R100P150 100% refund of the order value, up to 150 SAR

Status

Code Definition
CA Closed Abandoned
C Closed
O Open

Conditions

Code Definition
NOPHONE Driver phone number is not available
YESPHONE Driver phone number is available
RP Platinum Guarantee Refund Processed
RNP Refund Guarantee Refund Not Processed
GSE Gold Subscription Expired
GSNE Gold Subscription Not Expired
GTP Customer moved from Gold to Platinum
PSE Platinum Subscription Expired
PSNE Platinum Subscription Not Expired
SLABD30 Delivery SLA Breached - Platinum Guarantee of 30 mins from theoretical start production time to at customer location
NOSLAB30 Platinum delivery guarantee SLA of 30 mins not breached
SLABPU15 Pickup SLA breached - Platinum guarantee of 15 mins from theoretical start production time to actual end production time
NOSLAB15 Platinum pickup guarantee SLA of 15 mins not breached
SLABD Delivery SLA breach (SLA = 40 mins)
SLABPU Pickup SLA breach (SLA = 15 mins)
N No Condition
ITEMCHECKS Item selected from the order should be a side dish only
NOSLAB No SLA Breach in Pickup or Delivery
CHECKCUSTY Customizations are added in the Pizza
CHECKCUSTN Customizations are not added in the Pizza
ORSPT Order is Pickup or Takeaway
ORSD Order is Delivery
SLABD20 Time breach after the SLA time is between 1 min to 20 mins
SLABD2035 Time breach after the SLA time is above 20 mins and below 35 mins
SLABD3550 Time breach after the SLA time is above 35 mins and below 50 mins
SLABD50+ Time breach after the SLA time is above 50 mins
WMP Wallet balance is present in the account
WMPF Wallet balance is 0
EXEMPT If refund is given with Exempt in Action, that refund should not be counted in future customer profiling

Variables

Code English Arabic
{%wallet%} (%AMOUNT%) in your wallet (%AMOUNT%) في محفظتك.
{%wallet%} (%Loyalty Points%) rewards points (%Loyalty Points%) نقطة مكافأة.
{%wallet%} (%AMOUNT%) in your wallet & (%Loyalty Points%) rewards points (%AMOUNT%) في محفظتك و (%Loyalty Points%) نقطة مكافأة.
{%currency%} SAR ريال سعودي.
{%currency%} AED درهم إماراتي.

Loyalty Tiers

Code Definition
S Silver
G Gold
P Platinum

Customer Types

Code Definition
H Healthy
A Alert
B Abusive

Upload Process Workflow

1. File Selection

2. File Validation

The system performs comprehensive validation in the following order:

  1. Format Validation: Checks file structure and required columns
  2. Data Validation: Validates data types and required fields
  3. Flow Validation: Verifies the logical flow of complaint processes

3. Upload Execution

File Format Requirements

English CSV Structure

Required columns (case-sensitive):

Column Separator: Semicolon (;)

Arabic CSV Structure

Required columns (case-sensitive):

Column Separator: Semicolon (;)

Validation Process

Step 1: File Format Validation

The system checks:

Common Format Errors:

Step 2: Data Type Validation

The system validates:

Common Data Errors:

Step 3: Flow Validation

Advanced validation checks:

Upload Status Indicators

File Status Icons

Upload Status Messages

Error Messages and Solutions

File Selection Errors

Error Solution
"Select both English and Arabic CSV files" User must select both English and Arabic CSV files
"Both files must be validated" Click "Validate Files" after selecting both files

Format Validation Errors

Error Cause Solution
"File must contain header and at least one data row" Empty file or missing data Ensure file has header row and data rows
"Missing required column: [COLUMN_NAME]" Required column not found Add missing column to CSV header
"Row X: Column count mismatch" Inconsistent number of columns Ensure all rows have same number of columns
"Error reading CSV file" File corruption or encoding issue Re-save file as UTF-8 CSV with semicolon separator

Data Validation Errors

Error Cause Solution
"Row X: NODE_ID must be numeric" Non-numeric NODE_ID Ensure NODE_ID contains only numbers
"Row X: CUST_ID must be numeric" Non-numeric CUST_ID Ensure CUST_ID contains only numbers
"Row X: PARENT_NODE_ID must be numeric or NULL" Invalid parent reference Use numbers or exactly "NULL"
"Row X: Arabic description is required" Missing Arabic text Add Arabic description for all nodes

Server Processing Errors

Error Cause Solution
"No valid English CSV data found" Empty or invalid English file Check English file format and data
"No valid Arabic CSV data found" Empty or invalid Arabic file Check Arabic file format and data
"English CSV row X: Invalid NODE_ID" Server-side validation failure Review NODE_ID format and uniqueness
"Arabic CSV row X: Missing Description (Arabic)" Server-side validation failure Ensure all Arabic descriptions are present
"Maximum 2 files allowed" Too many files uploaded Upload exactly 2 files (English + Arabic)

Flow Validation Errors

Error Cause Solution
"The flow of both files must be validated" Flow validation not performed Click "Validate Flow" button
"The files have flow validation errors that must be corrected" Flow validation found issues Review flow validation dialog for specific errors

Troubleshooting Guide

Problem: Files won't upload

Check:

Problem: Validation fails repeatedly

Solutions:

  1. Download current data to see expected format
  2. Check file encoding (must be UTF-8)
  3. Verify column separator is semicolon (;)
  4. Ensure no hidden characters or formatting

Problem: Flow validation shows errors

Actions:

  1. Open flow validation dialog
  2. Review specific error messages
  3. Check parent-child relationships in data
  4. Verify node hierarchy integrity
  5. Correct data and re-validate

Problem: Upload fails after validation

Investigation:

  1. Check server connection
  2. Verify file size limits
  3. Review browser console for errors
  4. Contact system administrator if issues persist

Technical Notes

System Behavior

Best Practices

File Preparation

  1. Use consistent encoding: Save CSV files as UTF-8
  2. Check separators: Use semicolon (;) as column separator
  3. Validate NODE_IDs: Ensure matching NODE_IDs between English and Arabic files
  4. Review descriptions: Verify all descriptions are meaningful and complete

Error Prevention

  1. Template usage: Use existing data export as template for new uploads
  2. Data validation: Check data in spreadsheet application before export
  3. Backup strategy: Keep original files as backup before processing
  4. Test with small dataset: Validate process with subset of data first

Upload Strategy

  1. Sequential validation: Complete file validation before flow validation
  2. Review before upload: Check all validation messages before final upload
  3. Brand selection: Verify correct brand is selected before upload
  4. Timing: Perform uploads during low-traffic periods
CMS

CMS - Resources

To access the resource management section, go to the WEB CMS menu in the central panel.

WEB CMS - Resource management

Then go to the RESOURCES menu.

Resources

Once in RESOURCES, the sidebar shows all the sections available for viewing and editing resources: Banners, Payment methods, Ingredients, Logos, Products, Promotions, and Miscellaneous.

Resources sidebar

Selecting a source

Once a resource type is selected, if that resource has no data, the screen will show "No data available".

Example: Resource: Banners - Source: AI

No data available

If resources are available instead, the following options appear on screen:

Example: Resource: Banners - Source: Web

Source dropdown

Search filter and parameters

Example: Resource: Banners - Source: Web

Search filter

Example: Resource: Banners - Source: Web

Supported parameters - Banners

Example: Resource: Payment methods - Source: Web

Supported parameters - Payment methods

If no parameters are defined, the following message appears and those resources cannot be edited unless you contact the administrator: "To edit these resources, please contact your administrator".

Editing resources

Example: Resource: Banners - Source: Web

Edit button

If the file is valid, the Save button becomes enabled. If it saves without any errors during upload, a confirmation message appears.

Selected resources dialog

File saved successfully

If the file is not valid, a "Invalid format" message appears showing the incorrect parameters of the file.

File error

Preview and formats

Example: Resource: Banners - Source: Web

Preview button

Selected images - preview

Example: Resource: Promotions - Source: Web

Size format selector

CMS

CMS - Resources: Banners

To edit a banner, select the redirect type and choose a valid file.

Languages

Each banner has a corresponding banner in Catalan and English.

Image language selector

Each banner, in its respective language, must have an image and a redirect assigned to it.

Banner table by language

Destination URL

There are 3 available options for adding a banner's redirect (only one can be chosen):

Selected resources - choose redirect type

Product selection

Promotion selection

Example:

Destination URL field

CMS

CMS - Resources: Documents

To update documents, go to the WEB CMS menu and then RESOURCES.

WEB CMS - Resource management Resources

Languages

Each language has its own corresponding documents.

Document language selector

Documents table

Only one document can be uploaded at a time.

Updating a document

To update a document, select a file with a valid extension and a size under the maximum allowed. In this case, a PDF file smaller than 2 MB.

If the selected file is valid, the Save button becomes enabled.

Selected resources - upload document

Once it has saved successfully, a confirmation message appears:

File saved successfully

Reports & Metrics

Sales, products, promotions, trends, operations, alerts and per-order logs.

Reports & Metrics

Reports and Metrics: which to use

Audience: managers and analysts reading performance data, and operations staff investigating a specific order. You need: Sales reports for Reports, Metrics for Metrics. They are separate permissions.

The console has two data areas, and picking the right one saves a lot of time.

Reports Metrics
Answers "How did we do?" "What happened to this order?"
Shape Aggregated — totals, breakdowns, trends Per-order — logs, timelines
Period A business date or a date range Recent activity
Typical reader Management, analysts, area managers Support, operations, anyone investigating

If you are looking at numbers, you want Reports. If you are looking for one order's history, you want Metrics.

What's in Reports

Report Answers
Sales Revenue over the period
Product sales Which articles sold, grouped by family
Promotions How much each promotion was used
Sales by trend Monday-to-Sunday pattern, by category
Operations Live-ish operational picture: order states, staff on shift, load over the day, individual orders
Operational alerts Stores currently outside a threshold you set

What's in Metrics

View Answers
Order logs Which orders had activity, and what was done to them
Order timeline The full sequence of actions on one order
Archived alarms Alarms already dealt with

Permissions

To do this You need
Open any report Sales reports
Open order logs and timelines Metrics
Export from Metrics Metrics — export, a separate and higher permission
See archived alarms Archived alarms

report_viewer is the role built for this: reports, metrics and store visibility, nothing else. It combines well with an operational role — see Common role combinations.

Everything is scoped

Every figure is filtered to your scope before you see it. Two colleagues running the same report on the same day can legitimately get different totals, because they can see different stores or brands.

This is the single most common "the report is wrong" report, and it usually isn't. See How scope works in practice before investigating further.

The pages in this chapter

Topic Page
Filters, dates and the dashboard Filters, dates and favourites
Revenue Sales report
Articles sold Product sales report
Promotion usage Promotions report
Weekly patterns Sales by trend
The operations screen Operations report
Threshold-based store alerts Operational alerts
One order's history Order logs and timelines
Getting data out Exporting data
Reports & Metrics

Filters, dates and favourites

You need: Sales reports.

Every report is driven by the same filter set. Understanding it once covers the whole chapter.

The filters

Filter Required? Notes
Brand Yes, on most reports Reports are built per brand. With one brand it may be preselected
Stores No Empty means every store within your scope
Sources No Web, app, aggregators. Only applies where source filtering is active
Business date Yes The day the report covers
End date Only in range mode Turns one day into a period
Time window No Narrows to part of the day

The available values are loaded from your own scope, so the store list is what you can see, not everything that exists.

Day mode versus range mode

Switching modes changes what some reports mean. A 15-day chart in range mode anchors on the end date, not the start.

Business date is not calendar date

This is the one that catches people out.

A business date covers a trading day, which for late-night service runs past midnight. An order placed at 01:30 on Saturday usually belongs to Friday's business date.

So "yesterday's sales" means yesterday's business date, not the calendar day. When a total looks like it's missing the late evening, check which date the late-night orders landed on.

Two reports disagreeing by roughly one evening's trade is almost always this, not a fault.

The time window

Start and end times narrow a report to part of the day — the lunch service, the evening peak.

The window applies within each business date in your range. Setting 19:00–23:00 over a week gives you seven evenings, not one continuous stretch.

Favourites and the dashboard

The dashboard pulls its widgets in one batch, so it loads as a single view rather than piece by piece.

Use it for the numbers you check daily. For anything you need to slice, go to the report itself — the dashboard is a summary, not a filtered view.

Getting a report you can trust

  1. Set the brand first. Most reports need it, and changing it later resets other choices.
  2. Confirm the mode, day or range.
  3. Set the business date, remembering it is not the calendar date.
  4. Add stores and sources only if you mean to narrow. Empty means "everything I can see", which is usually what you want.
  5. Check the store count against what you expect. Fewer stores than expected is a scope question — see How scope works in practice.
Reports & Metrics

Sales report

You need: Sales reports.

The sales report gives revenue over the period you select, filtered to your scope.

Reading it

Set the brand, the mode and the business date — see Filters, dates and favourites — and the report covers exactly that period for the stores you can see.

In day mode it answers "how did we do yesterday". In range mode it answers "how did we do last month", and is the right shape for comparing periods.

Before comparing two periods

Comparisons go wrong for mundane reasons more often than interesting ones:

Check Why
Same store set? Adding or closing a store changes the total without changing performance
Same sources? An aggregator switched on mid-period moves volume without creating it
Comparable days? Four weekends against five is a 20% swing on its own
Same time window? A window applied to one period and not the other isn't a comparison

When the total looks wrong

  1. Business date, not calendar date. Late-night trade lands on the previous business date. This explains most "missing evening" reports — see Filters, dates and favourites.
  2. Your scope. You see your stores, not all stores. A colleague's different total may be correct for both of you — see How scope works in practice.
  3. Cancellations. A high cancellation rate suppresses revenue while order counts stay high — check Operational alerts.
Reports & Metrics

Product sales report

You need: Sales reports.

Product sales shows what actually sold, by article, grouped into families.

What it's for

The sales total tells you the revenue. This tells you what produced it — which articles moved, and which families carry the period.

Typical questions it answers:

Reading the grouping

Articles roll up into families, so you can read it at either level: the family view for the shape of the menu, the article view for individual decisions.

A family that looks flat can hide one article growing while another falls. Open the family before concluding nothing changed.

Pairing it with other reports

Question Also look at
Did discounting drive these sales? Promotions report
Is this a weekday or weekend product? Sales by trend
Did the revenue actually land? Sales report

An article that sells well only alongside heavy promotion is a different business case from one that sells at full price. The two reports together say which you have.

Scope applies here too

Figures cover the stores within your scope for the period selected. A product that looks absent may simply not be sold by the stores you can see — see How scope works in practice.

Reports & Metrics

Promotions report

You need: Sales reports.

The promotions report shows usage grouped by promotion code — how often each was applied over the period.

What it's for

It answers the question marketing actually needs: which promotions are being used, and therefore which are worth repeating.

Read alongside Sales report and Product sales report, it also answers the harder question — whether the promotion brought in business or discounted business that was coming anyway.

Reading it

Usage is grouped by code, so a campaign appears as the code customers entered. If you ran several codes for one campaign, you will see them separately; group them yourself, or run future campaigns as one campaign with multiple coupons so they stay together — see Promotional codes.

Questions worth asking of it

Pattern What it usually means
High usage, flat sales Discounting business you already had
Low usage, wide distribution The code isn't reaching people, or isn't attractive
Usage concentrated in a few stores Local awareness, or the offer only applies there
Usage stops abruptly mid-period The campaign hit its end date, or was expired — check Promotional codes

Zero usage is a finding

A promotion with no usage is worth investigating before repeating it. The usual causes are all fixable: the campaign was not live for those stores, the dates or valid times excluded the trading period, or the codes were never distributed.

The Promotional codes page lists the checks in order.

Reports & Metrics

Sales by trend

You need: Sales reports.

Sales by trend lays the period out as a Monday-to-Sunday matrix, broken down by category.

What it's for

Totals hide the shape of a week. This report shows it: which days carry the business, which are quiet, and whether that differs by category.

It is the report to use for decisions that are about the week rather than about the total — staffing, opening hours, when to run a promotion.

Reading the matrix

Rows are categories, columns are days of the week. The useful reading is across a row: a category that is flat all week behaves differently from one that spikes at the weekend.

Over a multi-week range each weekday aggregates all its occurrences, so a four-week range gives you four Mondays combined. That is what makes the pattern readable rather than noisy.

Watch the range length

An uneven range distorts the matrix. Thirty days contains five of some weekdays and four of others, so those columns are not comparable.

Use whole weeks when you want to compare days. Use any range you like when you only want each day's total.

What to do with it

Pattern Worth considering
One weekday consistently quiet A promotion aimed at that day, or reduced staffing
Weekend-heavy in one category only Menu or pricing specific to those days
A day that changed shape recently Compare against an earlier range before assuming a trend
Reports & Metrics

Operations report

You need: Sales reports.

The operations report is the widest screen in the chapter. It answers "what is happening operationally", where the other reports answer "what did we earn".

Order status and breakdown

Counters for where orders currently stand, plus a full breakdown by order type — delivery, pickup, takeaway and dine-in — each split into time buckets.

The time buckets are the useful part. A high total tells you it is busy; the buckets tell you whether orders are moving or piling up in the slow end.

Staff on shift

Who is currently active, grouped by job position, alongside the status of every store that is open.

An employee counts as active when they have clocked in for the shift and not yet clocked out. So this is a live view of who is actually on, not who was rostered.

Read it next to the order counters: heavy volume against thin staffing is the situation worth acting on, and neither number says it alone.

Requires a brand. Stores are optional, and empty means every store in your scope.

The 15-day chart

A time series of total orders in fixed 15-minute slots, for the reference date and the previous 14 business days.

The reference date is the business date in day mode, and the end date in range mode — worth knowing before you conclude the chart is showing the wrong period.

Fourteen days of history is what makes today readable. A slow hour only means something against how that hour normally looks.

Orders list, count and detail

Three views of the same underlying set:

View Use it for
Count How many orders match the filters, without loading them
List The orders themselves
Detail Line-level detail of one order

Run the count first when you are unsure how wide your filters are — it is much faster than loading a list you are about to discard.

Order detail is scoped per order, so you can only open orders for stores, brands and sources within your scope.

Store configuration changelog

The most recent configuration change per store.

This is the report that answers "did something change?" when a store's behaviour shifts. Before investigating a store that has started missing its promised times, check whether its settings moved — see Store delivery settings.

Reports & Metrics

Operational alerts

You need: Sales reports.

Three reports that return only the stores currently outside a threshold you set. Where the operations report shows everything, these show you only what needs attention.

The three

Alert Flags a store when Default threshold
Delivery load Pending deliveries per active driver exceed the threshold 2
Cancellations The share of valid orders falls below the threshold 90%
On-time On-time percentage is below the threshold and average delivery time exceeds the maximum 80% and 60 min

Each threshold is a parameter you pass when running the report, not a saved setting. Change it and re-run to widen or narrow what comes back.

The on-time alert needs both conditions

This is the one people misread. A store is only flagged when it is both below the on-time percentage and above the average-time limit.

That is deliberate. A store missing its target by a little while still delivering quickly is a different problem from one that is slow across the board — and only the second is worth interrupting someone for.

If you want the looser view, raise the maximum-minutes value rather than lowering the percentage.

These are not the Hub alarms

Easy to confuse, genuinely different:

Operational alerts Branch alarms
Where Reports Hub
Threshold Passed per run, by you Configured chain-wide
Lifecycle Recomputed each time you run it Raised, then archived
Use Reviewing a period Acting during service

Use these when reviewing; use Branch alarms when running the shift.

A workflow that works

  1. Run all three at their defaults for yesterday.
  2. For any store that appears, open the Operations report filtered to it.
  3. Check the store configuration changelog — did something change?
  4. If several stores appear together, suspect a shared cause before working through them one at a time.
  5. If the same store appears every day, the threshold is describing normal for that store. Either fix the store or accept it — a permanently-flagged store is noise.
Reports & Metrics

Order logs and timelines

You need: Metrics.

Order logs answer "what happened to this order" — the question Reports cannot answer, because Reports aggregates.

The paginated list

Orders that have recorded activity, filtered by store, brand and source within your scope. Use it to find the order you care about, then open its timeline.

The timeline

The full sequence of actions recorded against one order, in order.

An order is identified by store, ticket number and source together — a ticket number alone is not unique across stores. See The order board for why.

The timeline is what answers:

Question What to look for
Who handled this, and when? The sequence of actions and their timestamps
Was it reassigned? Assignment changes, and whether a person or the dispatcher made them
Why was it late? Where the gap actually sits — kitchen, pickup, or on the road
Did someone force or cancel it? Those actions appear here with who did them

Using it in an investigation

  1. Get the identifiers. Store, ticket number, source.
  2. Open the timeline. Read it end to end before forming a theory — the interesting event is often earlier than expected.
  3. Find the gap. Look for the long pause rather than the last event.
  4. Cross-check the dispatcher if the gap is in assignment — a Request ID from that period ties it to a specific run. See Reporting a dispatcher issue.

Metrics versus the Hub

Both show orders, for different purposes:

Metrics Hub
Time frame What already happened What is happening now
Purpose Explain Act
Can you change anything? No Yes

If the order is still live and needs intervention, work in the Hub — see The order board. If it is finished and needs explaining, work here.

Reports & Metrics

Exporting data

You need: Metrics — export. This is a separate, higher permission than Metrics, and is normally held by admin rather than by everyone who can read metrics.

Two things can be exported: order action logs and archived alarms. Both come out as data files for analysis outside the console.

Why export is a separate permission

Reading inside the console is scoped. Every screen filters to the stores, brands and sources you are allowed to see, every time you open it.

An exported file is a snapshot with that protection removed. Once it is a file on someone's laptop, it can be opened, forwarded and combined by anyone, regardless of what they could see in the console. The scope applied at export time; it does not travel with the file.

That is why export sits behind its own permission, and why it is worth thinking about before using it.

Before exporting

Ask Because
Do I need the raw rows, or an answer? A conclusion shared in a message is safer and usually more useful than a spreadsheet
Can the report answer it instead? Reports and Metrics: which to use — aggregated reports often answer the question without raw data
Who will end up with this file? Assume everyone the recipient works with
Does it need customer data? Narrow the filters before exporting, not after

Exporting

  1. Filter down to what you actually need — the export honours your filters and your scope.
  2. Export.
  3. Store it somewhere appropriate, and delete it when the analysis is done.

Narrow filters are the main control you have. An export of one store for one day is a very different object from an export of the whole chain for a month.

What you get

The export reflects exactly what you could see when you ran it. It is not live — reopening the file a week later shows the state at export time, not now.

For anything recurring, re-export rather than reusing an old file, and take the answer from the console where you can.

Employees

Staff records, hubs, contracted drivers, and bulk import/export.

Employees

Employees: what this area covers

Audience: HR and anyone who maintains staff records and their console access. You need: Employees — view to browse, Employees — edit to change.

The Employees area holds your staff records: who works where, which of them drive, and who can sign in to the console.

What it covers

Task Page
Find someone and read their record Finding an employee
Change their details or where they work Editing an employee
Add a contracted driver External employees
Move many records at once Importing and exporting employees
Give someone a console password Employees - Password

Employees, roles and drivers

Three things that attach to one person and are managed in different places:

What it is Where
The employee record Who they are, where they work Here
Their console access What they can do and see Managing roles from the console
Their driver configuration How the dispatcher treats them Here, on the record, for drivers

Creating an employee does not give them console access, and giving them a role does not give them a password. Those are three separate steps, deliberately — most employees never sign in to the console at all.

Everything is per brand

The Employees area works within the brand you are in, and is filtered further by your scope. employee_manager is the role built for it and is scoped at brand level.

A colleague seeing a different list is normal — see How scope works in practice.

Hubs

Employees are associated with hubs — the operational groupings your stores belong to. The hub list is available when editing someone, and determines which operation they are counted as part of.

Get this right before worrying about roles: a correct hub with no role is a normal employee; a role with the wrong hub is someone appearing in the wrong operation's numbers.

What this area does not do

Employees

Finding an employee

You need: Employees — view.

The employee list

The list shows staff within the brand you are in and within your scope. Search by name or identifier; if the person exists and is visible to you, they appear.

Someone missing from the list is usually scope rather than a missing record. A brand-scoped user cannot see another brand's staff even though the record exists. Check How scope works in practice before creating a duplicate.

Creating a duplicate employee because the original wasn't visible is the most expensive mistake in this area — it splits their history across two records.

The employee record

Opening someone shows their details and, if they are a driver, their driver configuration alongside.

That combination is the useful part. For a driver you can see in one place who they are, which hub they belong to, and how the dispatcher treats them — rather than reconciling two screens.

For non-drivers the driver section simply isn't there.

Hubs

The available hubs for the brand can be listed independently of any one employee. Use it to check the hub structure before assigning someone, especially if hub names are similar.

What to check on a record

Looking for Where
Are they in the right operation? Their hub
Can they deliver? The driver configuration on the record
Can they sign in? Their roles — Managing roles from the console — and their password
Why doesn't the dispatcher use them? Driver type and availability, plus Driver classification and priority
Employees

Editing an employee

You need: Employees — edit.

Editing updates an existing employee's details, their hub, and — for drivers — how the dispatcher treats them.

Changing details

Open the employee and change what needs changing. The record is the single source for who this person is, so keeping it accurate matters beyond this screen: reports group by hub, and the dispatcher reads driver configuration from here.

Moving someone between hubs

Changing an employee's hub moves them between operations.

This changes which operation they count towards from now on. Historical data is not retrospectively re-filed, so a mid-period move shows the person's work split across both hubs for that period. That is correct, and worth knowing before someone asks why a hub's numbers look odd.

Move people at a period boundary where you can.

Driver configuration

For employees who drive, the record carries the configuration the dispatcher uses — including their driver type, which decides how they rank against others.

Two things follow from that, both explained in Driver classification and priority:

So a driver who is "never getting orders" is often a type question rather than an availability one — check the zone's allowed types in Delivery zones as well.

What editing does not change

Not changed here Change it in
What they can do in the console Managing roles from the console
What data they can see Setting an employee's scope
Their password Employees - Password

Updating someone's job does not update their console access. If a person changes role in the business, all three need attention, and it is easy to do one and forget the others.

After a change that matters

For a driver, confirm the change had the effect you intended by watching whether the dispatcher starts using them as expected on the next cycle — no more than 60 to 300 seconds away. See The assignment cycle, step by step.

Employees

External employees

You need: Employees — edit.

An external employee is a contracted driver who is part of your own fleet — someone who delivers for you but is not on your payroll.

The distinction that matters

Three kinds of driver, easy to confuse:

What they are Managed
Internal driver Your own staff Here, as a normal employee
External / contracted driver Contracted, but part of your fleet Here — this page
Third-party carrier A delivery company you hand orders to Not here — External carriers

The middle one is the one this page is about. A contracted driver is still your fleet: the dispatcher assigns them individually, by name, exactly as it does your own staff. A third-party carrier is a company — you hand it the order and it picks the courier.

If you are setting up a courier platform, you are in the wrong place; go to External carriers.

Creating one

Create the external employee against the brand, then set their hub and driver configuration as you would for any driver — see Editing an employee.

How the dispatcher treats them

Contracted drivers rank below internal drivers. When both could take an order, the internal one wins, and an internal driver can take an order away from a contracted one — never the reverse. The full ranking is in Driver classification and priority.

Two consequences worth knowing:

Adding several at once

Use the CSV import rather than creating them one at a time — see Importing and exporting employees.

Employees

Importing and exporting employees

You need: Employees — view to export, Employees — edit to import.

Exporting

Export produces a CSV of the employees within your brand and scope.

Two good reasons to export, beyond bulk editing:

An exported file is no longer scope-filtered. It contains staff data, so treat it accordingly — see the same caution in Exporting data.

Importing

Import applies employee configuration from a CSV.

The sequence that avoids trouble:

  1. Export first. This gives you both the current state and the exact column format the import expects.
  2. Edit the exported file rather than building one from scratch.
  3. Test with a few rows. Confirm they landed as intended before committing the rest.
  4. Import the remainder.
  5. Spot-check two or three people on the employee list.

Imports are not transactional

A failure partway through leaves earlier rows applied and later rows not. There is no rollback, which is why the export in step 1 matters and why you find out where it stopped before re-submitting.

Re-running a whole file after a partial failure may re-apply rows that already succeeded.

Backups

Employee configuration is covered by the backup system: exports are retained, and can be downloaded or restored — see Backups and restoring configuration.

Restoring an employee backup follows the employee permission, not a separate backup one. And as with every restore, it reinstates the snapshot wholesale: anything changed since, by anyone, is overwritten for the records it covers.

What import does not touch

Roles, scope and passwords are not part of employee configuration. Importing a hundred employees gives none of them console access — see Managing roles from the console.

Employees

Employees - Password

To assign or change an employee's password, go to the EMPLOYEES menu.

Employees - Employee management

Enter your search term in the search box; if the user exists, they will appear in the table below:

Filters and search

Results table

Once you've located the user, click that row; a new window will open with all of that user's information:

Employee record

Setting or changing the password

In the password section, you can generate a password for that user (if they don't have one) or replace an existing one with a new one.

Set password - employee not yet registered

Once the password has been reset or created, a message appears at the top of the screen and that user will be able to log in to the console.

Changes updated successfully

Only users with the "Employee Manager" or "Administrator" roles can create or reset passwords.

Roles & permissions

Who can do what in the console, and what data each employee sees.

Roles & permissions

Roles and scope: the two ideas

Audience: Platform administrators who decide who can do what in the console. You need: the Assignments and Scope sections, available to admin and employee_manager.

Access in the console is built on two independent ideas. Keeping them apart is the key to the whole model.

Concept What it defines Where it's configured
Roles What an employee can do — actions and modules Assigned to the employee; one or more
Scope What data an employee can see — brands, stores, sources Configured once, per employee

An employee can hold several roles at once. The permissions from all of them are combined. The scope, by contrast, is always shared — it applies equally to everything that employee can do.

Why this separation matters

It means you never have to choose between "can operate the hub" and "can only see two stores". Those are answered separately:

Adding a second role later — reports, for example — does not widen what data they see. The scope still holds.

The three things you'll configure

You want to… Go to
Let someone do something new Managing roles from the console
Change what data they can see Setting an employee's scope
Grant or block one specific ability, just for them Individual permission exceptions

Roles decide what someone can do; their staff record is separate — see Employees: what this area covers.

Roles & permissions

Scope: what data an employee can see

Every employee has a single scope, which controls what data is visible to them everywhere in the console.

The two modes

Mode What it means
Customer Full access to all data across the entire chain
Explicit Access restricted to specific brands, stores and/or sources

The three dimensions of an explicit scope

When scope is explicit, you can combine these filters:

Dimension What it filters Example
Brands Which brands are visible Brand "X" only
Stores Which specific stores are visible Stores 1, 2 and 5
Sources Which order sources are visible Only Glovo and Uber Eats

How they combine:

Worked examples

Configuration What the employee sees
Brand = "Example Brand" All stores and sources for that brand
Stores = 1, 2, 3 All brands operating in those stores
Brand = "Example Brand" + Stores = 1, 2 Only that brand's data, in those two stores
Stores = 1 + Sources = Glovo, Uber Only Glovo and Uber data in store 1, wherever source filtering applies

A note on Sources

The source filter is a complementary dimension with limited activation. Not every module uses it — it only takes effect in sections where filtering by order origin is meaningful. Those include:

In modules where source filtering is not active, the employee sees all orders within their brand and store scope, regardless of this setting.

This makes Sources best suited to specialised roles that need a narrower view inside one particular section — not as a general-purpose restriction.

What scope does not do

Scope never grants anything. It only narrows. An employee with a store-limited scope and no reporting role still cannot open reports — scope decides what data, roles decide what actions. See Roles and scope: the two ideas.

Roles & permissions

The role catalogue

Each role covers one area of responsibility. If someone needs two areas, give them two roles — see Common role combinations.

Role For whom What it covers
admin Customer administrator Everything except managing role definitions. The highest role assigned to customer employees
hub_manager Operations manager Full hub — assign, force delivery, cancel, modify ETA, incidents, alarms — plus store configuration, pause delivery, metrics and archived alarms
hub_operator Hub shift operator Basic hub operations, without the critical actions. View stores and metrics
branch_manager Store manager Their own store: view orders, modify ETA, incidents, alarms, driver alerts, pause delivery, store configuration
branch_viewer Read-only store access Viewing store configuration only. A support role, designed to be combined with others
dispatcher_manager Logistics technician Dispatcher execution, scheduler, store configuration, pause delivery, delivery zones, third-party carriers, metrics
report_viewer Management and analysts Reports, metrics, view stores
polygon_manager Delivery zone configuration Delivery zones, view stores
cms_editor Content editor Complaints tree, resources, images
employee_manager HR and staff configuration Employees and own drivers, plus role assignments, scope and exceptions
third_party_manager External fleet configuration External carrier configuration, at brand level
alarms_config_manager Alarm threshold configuration Alarm thresholds for orders, drivers and stores, across the whole chain

Two roles you won't assign

super_admin is a PizzaGest internal technical role. It has full access and bypasses every check, and is never assigned to customer employees.

admin is the customer-side equivalent for day-to-day purposes: the same operational reach, except that individual denies still apply to it and it cannot change role definitions.

How permissions add up

Roles are built from a catalogue of atomic permissions — currently more than fifty, each covering one specific action such as "assign a driver" or "export metrics".

A role is a named subset of that catalogue. When an employee holds several roles, their permissions are combined, without duplicates. Nothing is subtracted by adding a role.

Permission counts per role change as new modules ship. Rather than memorising a number, check what a role actually grants in Access by section, or open the role in the Role catalogue screen.

Recently added modules

Chatbot configuration, External API management, the Voice agent, Promotional codes and Voucher codes are currently reachable by admin only. Whether they get a dedicated role, or are folded into existing ones, will be decided based on operational need.

If one of these needs to reach a non-admin employee before then, an individual exception is the intended route — see Individual permission exceptions.

Roles & permissions

Access by section

The full grid of what each role reaches. Legend: 👁 read-only · ✏️ read and write · — no access.

All access shown here is then filtered by the employee's scope — see Scope: what data an employee can see.

Section admin hub_manager hub_operator dispatcher_manager branch_manager report_viewer polygon_manager cms_editor employee_manager third_party_manager alarms_config_manager
Hub — orders and status ✏️ ✏️ ✏️ basic — 👁 — — — — — —
Hub — force delivery / cancel ✏️ ✏️ — — — — — — — — —
Hub — modify ETA ✏️ ✏️ — — ✏️ — — — — — —
Branch alarms ✏️ ✏️ 👁 — 👁 — — — — — —
Driver alerts ✏️ 👁 👁 — 👁 — — — — — —
Alarm threshold config ✏️ — — — — — — — — — ✏️
Archived alarms ✏️ 👁 — — — — — — — — —
Dispatcher ✏️ — — ✏️ — — — — — — —
Scheduler ✏️ — — ✏️ — — — — — — —
Store config ✏️ ✏️ 👁 ✏️ ✏️ 👁 👁 — — — —
Pause / resume delivery ✏️ ✏️ — ✏️ ✏️ — — — — — —
Third-party — brand config ✏️ — — ✏️ — — — — — ✏️ —
Third-party — store config ✏️ — — ✏️ — — — — — — —
Delivery zones ✏️ — — ✏️ — — ✏️ — — — —
Metrics ✏️ 👁 👁 👁 — 👁 — — — — —
Sales reports ✏️ — — — — 👁 — — — — —
Employees and own drivers ✏️ — — — — — — — ✏️ — —
CMS — complaints and resources ✏️ — — — — — — ✏️ — — —
Chatbot config ¹ ✏️ — — — — — — — — — —
External API management ¹ ✏️ — — — — — — — — — —
Voice agent ¹ ✏️ — — — — — — — — — —
Promotional codes ¹ ✏️ — — — — — — — — — —
Voucher codes ¹ ✏️ — — — — — — — — — —
Role and assignment management ✏️ — — — — — — — ✏️ — —

¹ Recently added modules, currently reachable by admin only. See The role catalogue.

Notes on reading this table

If a role is nearly right

Don't look for a role that matches a person exactly. Either combine two roles (Common role combinations), or keep the closest role and add a single exception (Individual permission exceptions).

Roles & permissions

Common role combinations

Because an employee can hold several roles and all of them share one scope, most real profiles are built by combining two or three roles rather than looking for a perfect single match.

Real profile Roles Scope
Operations manager who also views reports hub_manager + report_viewer Customer, or explicit by store
Operations manager who manages alarm thresholds hub_manager + alarms_config_manager Customer, or explicit by store
Operations manager who also runs the dispatcher hub_manager + dispatcher_manager Customer, or explicit by store
Shift operator who also views reports hub_operator + report_viewer Explicit — their stores
Store manager with access to reports branch_manager + report_viewer Explicit — their stores
Brand manager who doesn't operate orders employee_manager + polygon_manager + third_party_manager Explicit — brand
Delivery zone technician polygon_manager Explicit — brand
Management, data only report_viewer Customer
Full administrator admin Customer

Why hub_manager doesn't include the dispatcher

hub_manager deliberately focuses on hub operations. If your operations manager also needs the dispatcher, the scheduler or third-party carriers, assign hub_manager + dispatcher_manager.

Each role keeps its own area of responsibility, and the permissions combine automatically. This is preferred over widening hub_manager, because it keeps the two responsibilities visible and separately removable.

Rules of thumb

Combine roles, don't request new ones. Most needs are a combination that already exists. A new role definition requires a request to the development team — see Requesting a new or changed role.

Roles only ever add. Assigning a second role never reduces what the first one granted, and never widens what data is visible. Only scope controls that.

Use exceptions for the one-off case. If a profile matches an existing role except for a single ability, keep the role and add an individual grant or deny — see Individual permission exceptions.

Roles & permissions

How scope works in practice

Four behaviours explain almost every "why can this person see that?" question.

Roles are additive

An employee with hub_manager + report_viewer can operate the hub and view reports. Neither role restricts the other, and the order you assign them in makes no difference.

Scope filters data automatically

Having access to a module does not mean seeing all of its data. The system filters everything to the employee's scope.

A report_viewer whose scope is limited to the brand "Pizza Express" opens the same reports screen as everyone else, but sees only that brand's figures. Nothing is hidden or greyed out — the data simply isn't in their results.

This is worth explaining to people directly. Two colleagues comparing the same report and seeing different totals is expected behaviour, not a fault.

Scope applies equally to every role

Unlike older systems, scope is not configured per role. If an employee can see stores 1, 2 and 3, that applies to everything they do — hub, reports, metrics, store configuration, all of it.

This is a deliberate simplification. It means you can reason about one employee's visibility by looking at one setting, rather than reconciling several.

Individual exceptions override roles

You can grant or deny one specific permission to one specific employee, optionally with an expiry date.

A deny always wins, whatever their roles grant. See Individual permission exceptions.

Putting it together

When someone reports they can't do something, check in this order:

  1. Do they have a role that grants the action? → Access by section
  2. Is there a deny exception on them? → Individual permission exceptions
  3. Is the data simply outside their scope? → Setting an employee's scope

Most reports resolve at step 3, and look like a missing permission until you check.

Roles & permissions

Managing roles from the console

The console manages roles, assignments, scopes and individual exceptions through four sections.

Section What it lets you do Required permissions
Role catalogue View, create, edit and delete role definitions — their name and the permissions they include roles:read / roles:write
Assignments Assign and unassign roles to employees, activate and deactivate them employees:read / employees:write
Scope Configure what data each employee can access — brands, stores, sources employees:read / employees:write
Exceptions Create individual grants or denies on a specific permission for an employee, with an optional expiry date employees:read / employees:write

Who can reach each section

Role catalogue is restricted to super_admin — PizzaGest's own technical role. Creating or changing a role definition goes through the development team, who review the change before applying it. See Requesting a new or changed role.

Assignments, Scope and Exceptions are available to admin and employee_manager. These are the three you will use day to day: assigning existing roles, setting scope, and managing exceptions.

This split is deliberate. Changing what a role means affects every employee holding it, across the whole chain — so it is reviewed. Changing who holds a role affects one person, and is yours to do directly.

Assigning a role to an employee

  1. Open Assignments.
  2. Find the employee.
  3. Add the role or roles they need — see The role catalogue and Common role combinations.
  4. Confirm their scope separately, under Scope. A new role does not change existing scope.

An assignment can be deactivated rather than removed, which keeps the record while suspending the access.

Assigning a role does not give someone a way to sign in. Setting or resetting their password is a separate task, done from the Employees screen — see Employees - Password.

Safeguards

These protect you from the changes that are hardest to undo:

Roles & permissions

Setting an employee's scope

You need: employees:read and employees:write — held by admin and employee_manager.

Scope is set once per employee and applies to everything they do. See Scope: what data an employee can see for the model; this page is the task.

Before you start

Decide which of the two modes the person needs:

When in doubt, choose explicit and add to it. Widening a scope later is a one-field change; discovering someone has been seeing another brand's figures for months is not.

Setting an explicit scope

  1. Open Scope and find the employee.
  2. Switch the mode to Explicit.
  3. Fill only the dimensions you actually want to restrict:
    • Brands — leave empty for "all brands".
    • Stores — individual stores, store groupings, or both.
    • Sources — only if the restriction genuinely matters; see the caution below.
  4. Save, and confirm the result on a screen the employee uses, such as Reports.

Leaving a dimension empty means no restriction on that dimension — not "no access". An explicit scope with every dimension empty is equivalent to full access.

Using store groupings

Groupings are predefined sets of stores. They combine with individually selected stores rather than replacing them, so you can give someone a region plus one extra store without listing the region store by store.

Prefer a grouping over a long list of store IDs: when a store is added to the region later, the employee's scope follows automatically.

A caution on Sources

The source filter only takes effect in modules that implement it — Reports, Metrics, CMS and some Hub cases. Elsewhere the employee sees everything within their brand and store scope regardless.

This means a source restriction is not a reliable way to hide data in general. Use it to focus a specialised role, not to enforce a boundary. If the boundary matters, express it with brands or stores.

Checking your work

The fastest verification is to look at a screen that shows data volume, such as Reports or the hub order list, and confirm the employee sees what you intended — no more, no less.

Remember that scope does not grant anything. If they see nothing at all, check their roles before adjusting the scope — see How scope works in practice.

Roles & permissions

Individual permission exceptions

You need: employees:read and employees:write — held by admin and employee_manager.

An exception grants or denies one specific permission to one specific employee, on top of whatever their roles say. Use it when a person matches an existing role in every respect but one.

The two kinds

Kind Effect Typical use
Grant Adds one permission the employee's roles don't include A shift operator who also needs to cancel orders, without giving them the whole manager role
Deny Removes one permission the employee's roles do include A store manager who should not be able to pause delivery

The one rule that decides conflicts

A deny always wins. It beats every grant, from every role the employee holds, and from an explicit grant exception too. There is no ordering to reason about and no priority to configure.

This is deliberate: it means a deny is a reliable way to remove an ability, without auditing which roles might be putting it back.

super_admin is the single exception — it bypasses all checks, including denies. admin does not; individual denies apply to it normally.

Creating one

  1. Open Exceptions and find the employee.
  2. Choose the permission.
  3. Choose grant or deny.
  4. Optionally set an expiry date.
  5. Save. The record keeps who created it, for auditing.

Use the expiry date

Most exceptions are temporary in intent — cover for an absence, a seasonal push, a trial of wider access. Very few are temporary in practice, because nobody remembers to remove them.

Setting an expiry date when you create the exception turns that problem into a non-problem. If the access turns out to be permanent, the right fix is a role change, not an exception that never ends.

When not to use an exception

When two roles already cover it. If the person needs a whole area, assign the role for that area — see Common role combinations. Exceptions are for single permissions, not for assembling an area out of parts.

When several people need the same thing. Three identical exceptions are a sign the role is wrong. Request a role change instead — see Requesting a new or changed role.

To restrict data. Exceptions control actions, not visibility. To limit what someone can see, set their scope — see Setting an employee's scope.

Reviewing them

Exceptions are the part of the access model most likely to drift, because each one is invisible from the role catalogue. Review the exceptions list periodically and remove the ones whose reason has passed.

Roles & permissions

Requesting a new or changed role

Creating or editing a role definition is restricted to PizzaGest's technical team. As a customer administrator you assign existing roles, set scope and manage exceptions — but the role catalogue itself goes through a request.

This page explains why, and how to make the request land well.

Why it's reviewed

A role definition is shared. Changing what hub_manager means changes it for every employee holding it, in every store, immediately. Unlike an assignment — which affects one person and is easy to reverse — a role change has chain-wide reach, so it is reviewed before it is applied.

Try these first

Most requests turn out to be unnecessary. In order of preference:

  1. Combine existing roles. Two or three roles together cover most real profiles — see Common role combinations.
  2. Add an individual exception. If an existing role fits except for one ability, grant or deny that one permission — see Individual permission exceptions.
  3. Check it's not a scope problem. "They can't see the data" is usually scope, not permissions — see How scope works in practice.

A new role is the right answer when the same combination-plus-exception pattern keeps recurring across several people.

What to include in the request

Detail Why it matters
The job, in plain words "Regional supervisor for 12 stores" says more than a list of permissions
What they must be able to do The actions, named as they appear in the console
What they must not be able to do Often the more important half, and the part that's usually left out
The closest existing role And precisely how it falls short
How many people will hold it One person is usually an exception; several is usually a role
Whether it's permanent A seasonal need is better served by exceptions with expiry dates

What happens next

The request is analysed against the existing catalogue — partly to build the right role, and partly to check it doesn't overlap an existing one in a way that would make the model harder to reason about.

If a new role is created, it appears in the Role catalogue and you assign it like any other.

While you wait

You don't have to leave someone blocked. Assign the closest role and cover the gap with exceptions, ideally with an expiry date matching your expected timeline. When the new role arrives, assign it and remove the exceptions.

Reference

Glossary, how to report a problem, and cross-area FAQ.

Reference

Glossary

Terms used across the whole console. Dispatcher-specific vocabulary — driver states, Last-Option, TTB — is in the Dispatcher glossary.

Term Meaning
Brand A commercial identity within your company. Most screens work within one brand at a time, and data is separated by brand
Store A physical location. Called a branch in some screens
Hub An operational grouping of stores. Employees belong to a hub, and it determines which operation their work counts towards
Source Where an order came from: web, app, kiosk, or an aggregator. Content and some reports are separated by source
Scope What data an employee may see — brands, stores, sources. Set once per person and applied everywhere
Role What an employee may do. A person can hold several; permissions combine
Permission One specific ability, such as assigning a driver or exporting metrics. Roles are built from these
Exception A grant or deny of one permission for one person, overriding their roles. A deny always wins
Business date The trading day an order belongs to. Late-night orders belong to the previous business date, not the calendar date
Promised time The delivery time the customer was given, and what lateness is measured against
Own fleet Your own drivers, whether employed or contracted
Third-party carrier An external delivery company you hand orders to. They choose the courier, not you
Redeemed A promotion, voucher or credit the customer has already used. Bulk operations never touch redeemed records
Bulk change Changing many records at once, via check → apply → track
Import Loading records from a CSV. Never transactional: a partial failure leaves earlier rows applied
Backup A retained snapshot of an export, which can be downloaded or restored
Alarm Raised automatically when a store crosses a threshold. Lives in the Hub, and is archived once handled
Alert Raised automatically about a driver, or returned by a threshold report in Reports
Incident A record a person writes against one order, explaining what went wrong
Request ID Identifies one dispatcher run. The single most useful thing to include when reporting a dispatcher problem

Three that are easy to confuse

Alarm, alert, incident. The first two are raised by the system and you respond to them; the third you write yourself and it stays on the order. See Branch alarms, Stores and driver alerts and Logging an incident.

Contracted driver versus third-party carrier. A contracted driver is part of your fleet and is assigned by name. A carrier is a company — you hand it the order and it picks the courier. See External employees.

Role versus scope. Roles decide actions, scope decides data. See Roles and scope: the two ideas.

Reference

Reporting an issue

How to report a console problem so it can be resolved without three rounds of questions.

For dispatcher-specific problems there is a fuller checklist in Reporting a dispatcher issue — the Request ID it asks for is what makes those traceable.

Check these three first

A large share of reports resolve here, without anyone else being involved:

Symptom Likely cause
"I can't see the screen" Your roles — What you can see, and why
"I see fewer rows than my colleague" Your scope — How scope works in practice
"The total is missing an evening" Business date, not calendar date — Filters, dates and favourites

None of these are faults, and all three are answered in a minute.

What to include

Detail Why
Where you were The area and screen, not just "the console"
What you did The steps, in order
What you expected Often the most useful line, and the one most often missing
What happened instead Including the exact wording of any message
When Date and approximate time
Who Your identifier — it decides your roles and scope, so it determines what you should have seen
Brand If your company has more than one
One-off or recurring? A single occurrence and a pattern point to different causes

Identifying a specific order

An order needs store, ticket number and source together. A ticket number alone is not unique across stores, so a report with only a number cannot be traced.

If the dispatcher is involved, add the Request ID from the Scheduler — it points to one exact run.

Evidence that helps

What doesn't help

Before reporting a permissions problem

Say which of the two it is — you can see the screen but not the data, or you can't see the screen at all. The first is scope, the second is a role. That one sentence often resolves it immediately.

Reference

FAQ

Cross-area questions. Each chapter has its own detail; this is the index for the ones that come up everywhere.

Access

Why can't I see an area other people can? Your roles decide which areas appear. See What you can see, and why.

Why do I see fewer rows than a colleague running the same report? Your scope is narrower, and you are both seeing the correct answer for yourselves. See How scope works in practice.

I have the role but still can't do one specific thing. Permissions are granular, and a deny exception overrides a role. Check Access by section, then Individual permission exceptions.

How do I get a password? Someone with employee management rights sets it. There is no self-service reset — see Signing in.

Data and numbers

Two reports disagree by about one evening's trade. Business date is not calendar date; late-night orders belong to the previous business date. See Filters, dates and favourites.

Reports and Metrics disagree about an order. They read different stores of data. An order present in Reports but absent from Metrics generated no log events — it is not lost. See Reports and Metrics: which to use.

A bulk change affected fewer records than the check said. Records redeemed between the check and the apply are excluded, as are any already redeemed. See How bulk changes work.

Orders

Why did an order change driver by itself? A driver with better priority became available. See When an order changes driver.

Why is an order still unassigned? Usually capacity, a zone that allows no available driver type, or incomplete address data. See the Dispatcher FAQ.

I unassigned an order but the carrier still came. Unassigning does not cancel with the carrier. Cancelling does, atomically. See Assigning and unassigning a driver.

An order I assigned by hand never got reassigned. Manual assignments are permanently locked out of automatic reassignment. That is intended. See The order board.

Content and promotions

I changed a banner and nothing changed. Almost always the wrong source selected — content is stored per source, and per language for banners and documents. See Resources and sources.

A customer's promo code doesn't work. Check dates and valid times, whether that coupon is already redeemed, and whether the offer is live for that store. See Promotional codes.

A carrier looks available but shows as full. Carrier capacity is one shared pool per store per company, not per courier. See External carriers.

Imports and exports

An import failed halfway. Can I just re-run it? Not safely. Imports are not transactional, so earlier rows are already applied and re-running may apply them twice. Find where it stopped first — see Importing from a CSV.

Can I undo an import? Only for records nobody has redeemed, via a bulk delete. Anything already used stays.

Why is exporting a separate permission? Because an exported file is no longer scope-filtered. See Exporting data.

Still stuck

Reporting an issue lists what to include so it can be resolved first time.