Skip to main content

Overview

The promotions system (Promos) allows vendors to create special offers, featured deals, and promotional campaigns. Promotions function similarly to products but with additional visual prominence and marketing features.

Promotion Structure

Promo Fields

FieldTypeDescription
id_promointUnique promotion identifier
texto_promovarchar(255)Promotion name/title
descripciontextDetailed promotion description
thumbnailstextMain promotion image
urlvarchar(255)SEO-friendly URL slug
clavesvarchar(255)Keywords/tags for search
publicarintPublication status (0=hidden, 1=published)
preciodoublePromotional price
cantidadintTotal quantity available
cantidad_existenteintCurrent stock level
prod_vendidosintTotal units sold
locale_id_localintStore/vendor association
usuario_id_usuariointUser who created the promo
fechacre_promotimestampCreation date

Model Relationships

Promo Model Associations:

beLongsTo:
  - User (creator)
  - Locale (store)

hasAndBelongsToMany:
  - Archivo (files/images)
  - Category (categories)

hasMany:
  - Newsgalleries (news associations)

Creating Promotions

1

Access Promotion Manager

Navigate to Promos > Add from the admin panel
2

Enter Promotion Details

Fill in the promotional information:Required Fields:
  • Promotion name (texto_promo)
  • Description (detailed offer details)
  • Keywords (claves) for search optimization
  • Associated store (auto-filled for vendors)
Optional Fields:
  • Price (special promotional price)
  • Warranty terms
3

Upload Promotional Image

Select an eye-catching promotion imageSupported Formats: JPG, JPEG, PNG, GIF, MP3, SWF, FLVImage Processing:
  • Original stored in /files/promos/otras/
  • Thumbnail (450x280) in /files/promos/thumbnails/
  • Slider version (779x280) in /files/promos/slider/
4

Set Stock Quantities

Define promotional inventory:
  • Initial quantity (cantidad)
  • System sets cantidad_existente = cantidad
  • System initializes prod_vendidos = 0
5

Publish

Save the promotion to make it available

Image Sizes & Processing

Location: /files/promos/thumbnails/Purpose: Grid views, listings, category pagesProcessing:
$image = new SimpleImage();
$image->load($original_file_path);
if($image->getWidth() > 450){
    $image->resizeToWidth(450);
}
if($image->getHeight() > 280){
    $image->resizeToHeight(280);
}
$image->save($thumbnail_path);

URL Generation

Promotions automatically generate SEO-friendly URLs: Formula: texto_promo + claves (slugified) Example:
  • Promo Name: “Descuento Especial Verano”
  • Keywords: “muebles oferta”
  • Generated URL: descuento-especial-verano-muebles-oferta
URLs are unique and automatically incremented if duplicates exist (e.g., url_1, url_2).

Promotion Listings

Vendor View

Endpoint: /promos/index Vendors see only their own promotions:
$user = $this->Session->read('Auth.User.locale_id_local');
if(!empty($user)){
    $conditions = array('Promo.locale_id_local' => $user);
}
Features:
  • 10 promotions per page
  • Ordered by creation date (newest first)
  • Quick actions: Edit, Delete, Activate/Deactivate

Administrator View

Administrators see all promotions across all stores with no filtering.

Editing Promotions

Editing promotional stock quantities resets cantidad_existente and prod_vendidos to 0. Be cautious when modifying active promotions.
Edit Workflow:
  1. Navigate to Promos > Index
  2. Select promotion to edit
  3. Modify fields as needed:
    • Promotion details
    • Description and keywords
    • Price and terms
    • Stock quantities
  4. Upload new image (optional)
  5. Save changes
Image Replacement:
  • New images are processed in all three sizes
  • Old images remain on disk but are not referenced
  • Consider manual cleanup of unused images

Stock Management

Inventory Tracking

Promotions use the same stock tracking as products:

Available Stock

cantidad_existente - Current units available for sale

Units Sold

prod_vendidos - Total units sold through this promotion

Stock Updates on Sale

When a customer purchases a promotion:
// Check availability
$promocion = $this->Promo->find('all', array(
    'conditions' => array(
        'id_promo' => $promo_id,
        'cantidad_existente >' => 0
    )
));

// Update stock
$new_existente = $current_existente - $quantity_sold;
$new_vendidos = $current_vendidos + $quantity_sold;

$this->Promo->updateAll(
    array(
        'Promo.cantidad_existente' => $new_existente,
        'Promo.prod_vendidos' => $new_vendidos
    ),
    array('Promo.id_promo' => $promo_id)
);

Publication Control

Visibility Management

Activate Promotion

Route: /promos/activa/{id}Sets publicar = 1 to display promotion to customers

Deactivate Promotion

Route: /promos/desactiva/{id}Sets publicar = 0 to hide promotion from public view
Common Use Cases:
  • Schedule promotions (activate when campaign starts)
  • Pause promotions during stock outages
  • Test promotions before public launch
  • End campaigns without deleting history

Deleting Promotions

Delete Process:
  1. Navigate to promotion listing
  2. Click delete button for target promotion
  3. System removes promotion record
  4. Redirects to listing with confirmation message
Endpoint: /promos/delete/{id}

Sales Integration

Purchasing Promotions

Promotions are sold through the sales system: Purchase Flow:
  1. Customer views promotion details
  2. Clicks to purchase
  3. System validates:
    • Promotion exists and is published
    • Stock available (cantidad_existente > 0)
    • No duplicate pending orders
  4. Creates sale record with promocion_id_promo
  5. Updates promotion stock
  6. Processes payment
Key Endpoints:
  • /ventas/consulta_promocion - Check availability
  • /ventas/add_promo - Add to cart
  • /ventas/finalizar_compra - Complete purchase

Response Codes

CodeMeaning
0Database error
1Success
2Out of stock
4Duplicate order

Store Assignment

Endpoint: /promos/verlocal Provides AJAX autocomplete for store selection:
// Request
{ "term": "magdaleno" }

// Response
[
  {
    "id": 1,
    "value": "El Punto Artesanal de Magdaleno"
  }
]
Query:
$locales = $this->Locale->find('all', array(
    'fields' => array('Locale.nombre_empresa', 'Locale.id_local'),
    'conditions' => array(
        'Locale.nombre_empresa LIKE' => '%' . $term . '%',
        'Locale.status =' => 1
    )
));

Categories & Classification

Promotions can be organized using categories:

Category Association

Join Table: categories_galleries Relationship: Many-to-Many (HABTM) Benefits:
  • Browse promotions by category
  • Filter promotional campaigns
  • Organize seasonal offers
  • Group related promotions

Image Management

Multiple Images

Promotions support multiple images through file attachments: Join Table: archivos_galleries Supported Types:
  • Images: JPG, JPEG, PNG, GIF
  • Audio: MP3
  • Flash: SWF, FLV

Deleting Images

Endpoint: /promos/deleteimg/{promo_id}/{file_id} Removes specific image from promotion’s gallery.
Image deletion uses direct SQL and cannot be rolled back. Verify before deletion.

Validation Rules

  • Rule: Not empty
  • Message: “No debes dejar vacio el campo”
  • Used in URL generation
  • Rule: Not empty
  • Message: “No debes dejar vacio el campo”
  • Should explain promotional terms
  • Rule: Not empty
  • Message: “No debes dejar vacio el campo”
  • Used for SEO and search
  • Rule: Not empty
  • Message: ”* Requerido”
  • Must reference active store

MeioUpload Configuration

Promotion images use the MeioUpload behavior:
'MeioUpload' => array(
    'thumbnails' => array(
        'dir' => 'files{DS}promos/otras',
        'create_directory' => true,
        'thumbnailQuality' => 50,
        'useImageMagick' => true,
        'allowed_mime' => array(
            'image/gif',
            'image/jpeg',
            'image/pjpeg',
            'image/png',
            'audio/mpeg',
            'application/x-shockwave-flash',
            'video/x-flv'
        ),
        'allowed_ext' => array(
            '.jpg', '.JPG',
            '.jpeg', '.JPEG',
            '.png', '.PNG',
            '.gif', '.GIF',
            '.mp3', '.swf', '.flv'
        )
    )
)

Best Practices

  • Use high-quality, attention-grabbing images
  • Optimize for slider dimensions (779x280)
  • Include promotional text in image
  • Maintain consistent branding
  • State promotional terms clearly
  • Include start and end dates
  • Specify any restrictions or conditions
  • Highlight savings or benefits
  • Set realistic stock levels
  • Monitor inventory during campaigns
  • Deactivate when out of stock
  • Restock or end promotion promptly
  • Use descriptive promotion names
  • Include relevant keywords
  • Create unique URLs for each campaign
  • Add to appropriate categories

Promotional Campaigns

Campaign Types

Seasonal Sales

Holiday specials, seasonal clearance, back-to-school offers

Flash Sales

Limited-time offers with urgent messaging and countdown timers

Bundle Deals

Multiple items packaged together at discounted price

New Product Launch

Introductory pricing for new inventory items

Clearance

Deep discounts on discontinued or excess inventory

Loyalty Rewards

Special offers for repeat customers or members

Inventory Management

Regular product listings

Sales Tracking

Promotional sales reporting

Galleries

Image management system

Technical Notes

URL Slug Generation

Implemented in beforeSave() model method:
$currentUrl = Inflector::slug(strtolower($this->data['Promo']['texto_promo']));
$claves = Inflector::slug(strtolower($this->data['Promo']['claves']));
$url = $currentUrl . $claves;

// Check for duplicates and append _1, _2, etc.

Display Field

var $displayField = 'thumbnails';
The thumbnail filename is used when displaying promotion names in dropdowns and references.

Timestamp

`fechacre_promo` timestamp DEFAULT CURRENT_TIMESTAMP
Automatically records creation date for reporting and sorting.

Build docs developers (and LLMs) love