# CMS

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

# 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](/books/console-yF7/page/how-scope-works-in-practice).

## The pages in this chapter

| Topic | Page |
|---|---|
| Resource types and the source selector | [Resources and sources](/books/console-yF7/page/resources-and-sources) |
| Finding incomplete content | [Content validation](/books/console-yF7/page/content-validation) |
| The complaints tree | [The complaints tree](/books/console-yF7/page/the-complaints-tree) |
| Editing banners, step by step | [CMS - Resources: Banners](/books/console-yF7/page/cms-resources-banners) |
| Documents per language | [CMS - Resources: Documents](/books/console-yF7/page/cms-resources-documents) |
| The resources screen | [CMS - Resources](/books/console-yF7/page/cms-resources) |
| Loading complaints from a file | [CMS - Complaints CSV Upload](/books/console-yF7/page/cms-complaints-csv-upload) |

# 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](/books/console-yF7/page/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](/books/console-yF7/page/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](/books/console-yF7/page/cms-resources-banners) covers the per-language banner flow, and [CMS - Resources: Documents](/books/console-yF7/page/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](/books/console-yF7/page/content-validation).

# 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.

## Related pages

- [Resources and sources](/books/console-yF7/page/resources-and-sources) — the model behind the combinations
- [CMS - Resources](/books/console-yF7/page/cms-resources) — the screen, with screenshots

# 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](/books/console-yF7/page/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.

## Related pages

- [CMS - Complaints CSV Upload](/books/console-yF7/page/cms-complaints-csv-upload) — bulk loading, in detail
- [CMS: what it covers](/books/console-yF7/page/cms-what-it-covers) — permissions and the two CMS areas
- [Logging an incident](/books/console-yF7/page/logging-an-incident) — the Hub's per-order record, which is a different thing

# 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

- **English CSV**: Upload the main complaint flow structure with all node data
- **Arabic CSV**: Upload the Arabic translations for node descriptions
- **File Format**: Only `.csv` files are accepted
- **Requirement**: Both files must be selected before proceeding

### 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

- Files are uploaded to test database tables
- Existing data for the selected brand complaints is replaced with new data
- Transaction-based upload ensures data consistency

## File Format Requirements

### English CSV Structure

Required columns (case-sensitive):

- `NODE_ID` - Numeric identifier (required, unique)
- `CUST_ID` - Customer ID (numeric, required)
- `PARENT_NODE_ID` - Parent node reference (numeric or NULL)
- `DESCRIPTION` - Node description in English (required, non-empty)
- `SHORT_NAME` - Short display name (required)
- `CUSTOMER_TYPE` - Customer type classification
- `LOYALTY_TIER` - Loyalty level indicator
- `ACTION` - Action type for this node
- `CONDITION` - Conditional logic (if applicable)
- `LAST_NODE` - End node indicator
- `STATUS` - Node status

**Column Separator**: Semicolon (`;`)

### Arabic CSV Structure

Required columns (case-sensitive):

- `NODE_ID` - Must match English CSV NODE_ID (numeric, required)
- `CUST_ID` - Must match English CSV CUST_ID (numeric, required)
- `PARENT_NODE_ID` - Parent node reference (numeric or NULL)
- `Description (Arabic)` - Arabic translation (required, non-empty)
- `SHORT_NAME` - Short name in Arabic

**Column Separator**: Semicolon (`;`)

## Validation Process

### Step 1: File Format Validation

The system checks:

- ✅ File contains headers and at least one data row
- ✅ All required columns are present
- ✅ Column count matches across all rows
- ✅ File encoding is UTF-8 compatible

**Common Format Errors:**

- Missing required columns
- Incorrect column separator (must be `;`)
- Empty files or header-only files
- Mismatched column count between rows

### Step 2: Data Type Validation

The system validates:

- ✅ `NODE_ID` is numeric
- ✅ `CUST_ID` is numeric
- ✅ `PARENT_NODE_ID` is numeric or NULL
- ✅ Required text fields are not empty
- ✅ Arabic descriptions contain valid text

**Common Data Errors:**

- Non-numeric values in ID fields
- Empty description fields
- Invalid character encoding
- Missing required field values

### Step 3: Flow Validation

Advanced validation checks:

- ✅ Node hierarchy integrity
- ✅ Parent-child relationships
- ✅ Circular reference detection
- ✅ End node validation
- ✅ Action type consistency
- ✅ Variable pattern validation

## Upload Status Indicators

### File Status Icons

- 🔄 **Validating**: File validation in progress
- ✅ **Validated**: File passed all validation checks
- ⏳ **Waiting**: File queued for validation
- ⚠️ **Warning**: File selected but not validated
- ❌ **Error**: Validation failed

### Upload Status Messages

- 📤 **"Uploading"**: Files are being processed on server
- ✅ **"Files uploaded successfully"**: Upload completed without errors
- ❌ **"Upload failed"**: Server error during upload process

## 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:**
- Both files selected
- Both files validated successfully
- Flow validation completed without errors
- Correct brand selected

### 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

- **Environment**: CSV uploads always to test environment
- **Data replacement**: Existing complaints data is completely replaced when uploading a CSV in the test environment
- **Transaction safety**: Failed uploads don't corrupt existing data
- **File processing**: Files processed sequentially during validation
- **Memory limits**: Large files may cause browser performance issues

## 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 - Resources

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

![WEB CMS - Resource management](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/ErrVquUS0CLuw5DJ-manual-consola-cms-recursos-p1-0.png)

Then go to the **RESOURCES** menu.

![Resources](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/RTLr32akQXdDXoEa-manual-consola-cms-recursos-p1-1.png)

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](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/pGUKmOc9BiwtQS66-manual-consola-cms-recursos-p1-2.png)

## 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](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/m2NoVgJe038BhfiW-manual-consola-cms-recursos-p2-0.png)

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

- **Source dropdown**: to select which source to display (Web, App, Kiosk, Store, JustEat, UberEats, Stuart, Tablet, etc.).

*Example: Resource: Banners - Source: Web*

![Source dropdown](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/jPd5RmKpD6rg9Lf7-manual-consola-cms-recursos-p2-1.png)

## Search filter and parameters

- **Search filter**: to search within the displayed table.

*Example: Resource: Banners - Source: Web*

![Search filter](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/6Vdcac9ewvJRs2Td-manual-consola-cms-recursos-p3-0.png)

- **Supported parameters** for the selected resource, depending on the chosen source.

*Example: Resource: Banners - Source: Web*

![Supported parameters - Banners](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/d1aMqkCRAqe0ewG9-manual-consola-cms-recursos-p3-1.png)

*Example: Resource: Payment methods - Source: Web*

![Supported parameters - Payment methods](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/o9jQB00JeYcHVPWy-manual-consola-cms-recursos-p3-2.png)

> 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

- **Edit button**: to edit the resources selected in the table.

*Example: Resource: Banners - Source: Web*

![Edit button](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/wHkgpUqSVJejRLmT-manual-consola-cms-recursos-p4-1.png)

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](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/z57CYN2v2Wfxa6K1-manual-consola-cms-recursos-p4-3.png)

![File saved successfully](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/Jmz8t76q3JMphMP4-manual-consola-cms-recursos-p4-4.png)

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

![File error](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/ks54pSeonBIjkMJM-manual-consola-cms-recursos-p4-5.png)

## Preview and formats

- **Preview button**: to view a preview of the images selected in the table.

*Example: Resource: Banners - Source: Web*

![Preview button](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/NViWB4TPG7ldbFA8-manual-consola-cms-recursos-p5-1.png)

![Selected images - preview](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/KI5t9RL2GuAJItXV-manual-consola-cms-recursos-p5-2.png)

- **Size buttons (000px x 000px)** (only visible when multiple sizes are defined): selecting one shows the table for that format.

*Example: Resource: Promotions - Source: Web*

![Size format selector](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/tmWNADXo0esCagza-manual-consola-cms-recursos-p5-4.png)

# 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](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/NQUh5rmoFf66Y5SL-manual-consola-cms-recursos-banners-p1-0.png)

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

![Banner table by language](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/7RcNGLLJOZWZ2M3M-manual-consola-cms-recursos-banners-p1-2.png)

## Destination URL

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

![Selected resources - choose redirect type](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/9iWHU4lgMK7Jfyhv-manual-consola-cms-recursos-banners-p2-0.png)

- **PRODUCT** → select from the list the product the banner should redirect to.

![Product selection](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/bzcDcKNT8W7uwzSq-manual-consola-cms-recursos-banners-p2-1.png)

- **PROMOTION** → select from the list the promotion the banner should redirect to.

![Promotion selection](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/HCsz9CL8fhtYGSQ7-manual-consola-cms-recursos-banners-p3-0.png)

- **URL** → enter the complete, correct URL of the page you want to redirect the customer to, as long as it isn't a specific offer or product.

*Example:*
- Redirect to the "promocion-sala" landing page
- URL: `https://www.pizzeriascarlos.es/promocion-sala/`

![Destination URL field](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/MCfV3zg63Bg73DqC-manual-consola-cms-recursos-banners-p3-1.png)

# CMS - Resources: Documents

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

![WEB CMS - Resource management](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/TKPxHV9cerBG4O2U-manual-consola-cms-recursos-documentos-p1-0.png)
![Resources](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/CJ6pFzD41idOuukY-manual-consola-cms-recursos-documentos-p1-1.png)

## Languages

Each language has its own corresponding documents.

![Document language selector](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/yJJEQ8s4a1kvj3UF-manual-consola-cms-recursos-documentos-p1-3.png)

![Documents table](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/Kx9K8yg6TGNtBbv6-manual-consola-cms-recursos-documentos-p1-4.png)

> **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](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/FZUkT9pwMmnPRFio-manual-consola-cms-recursos-documentos-p2-1.png)

Once it has saved successfully, a confirmation message appears:

![File saved successfully](https://pav-bookstack-docs-uploads.s3.eu-west-par.io.cloud.ovh.net/uploads/images/gallery/2026-09/fovrqdfZOsKpdhmc-manual-consola-cms-recursos-documentos-p2-2.png)