Skip to content

Waiting List (Notify When Available)

Flow ID: CF-15 | Module(s): eshop, Product domain | Complexity: Low

Business Overview

The waiting list lets customers subscribe to receive email notifications when out-of-stock products return to inventory. When stock is replenished, a scheduled cron job emails all subscribers with a direct purchase link.

What customers experience:

  • On an out-of-stock product page, enter email to subscribe
  • reCAPTCHA prevents spam subscriptions
  • System confirms subscription (one per email+product pair)
  • When stock returns, customer receives email in their preferred language

Key business behaviors:

  • One subscription per email-product pair (duplicate prevention via isInWaitingList())
  • Language-scoped notifications (stored per entry, used when sending)
  • Advisable AI bookmark logged for recommendation personalization
  • Notification job groups products by customer email to reduce duplicate emails
  • Admin panel offers two views: per-entry listing and grouped-by-product view
  • Soft delete: admin deletion sets waiting_status=2 (not a hard delete)

API Reference

REST Endpoints

MethodPathAuthDescription
GET/rest/product/waiting-listBackendList entries (filterable, sortable, paginated)
POST/rest/product/waiting-listBackendCreate entry
DELETE/rest/product/waiting-list/{id}BackendDelete entry

Legacy AJAX

MethodPathDescription
POST (AJAX)/waiting_list/addSubscribe to product notification

Legacy Admin

URLDescription
/waiting_list_admin/index/{offset}Paginated list of all pending subscriptions (50/page)
/waiting_list_admin/group_products/{offset}Pending subscriptions grouped by product with counts (300/page)
/waiting_list_admin/delete_waiting_list_row/{id}Soft-delete a waiting list entry

Code Flow

Step 1: Customer Subscribes (AJAX)

File: ecommercen/eshop/controllers/Adv_waiting_list.php

  1. Guard: Reject non-AJAX requests with generic error
  2. Validate: product (natural number, required), email (valid email, required), reCAPTCHA via setCaptchaValidationRule()
  3. Product verify: getMasterRecords([$productId]) — error if product not found
  4. Duplicate check: isInWaitingList($email, $productId) — checks only pending entries (waiting_status=0)
  5. Insert: via waiting_list_model->add() — sets waiting_status=0, lang=current, creation_date=now()
  6. AI bookmark: bookmarkToAdvisableAI($productId) — deferred task for recommendation personalization
  7. Response: JSON {status: 'success'|'warning'|'danger', title, msg, db_id}

Step 2: Notification Job Sends Emails

File: ecommercen/job/libraries/AdvSendEmailForWaitingList.php

  1. Language param: Accepts optional lang option (defaults to site default language)
  2. Query eligible: getRecordsToSendEmails($lang) — joins shop_waiting_list with shop_product, product_codes, shop_product_mui, shop_vendor/shop_vendor_mui — filters: waiting_status=0, product.active=1, stock > 0 OR negative_stock=1, matching language
  3. Group by email: Collects all products per email address to send a single multi-product email
  4. Send: adv_mailer->sendEmailForWaitingList($email, ['products' => $data], $lang) per customer
  5. Mark sent: markAsSent($ids) — sets waiting_status=1, email_sent_date=now() for all processed IDs

Step 3: Admin Views

File: ecommercen/eshop/controllers/Adv_waiting_list_admin.php

  • Authorization: Requires AUTH_ROLE_ADVISABLE, AUTH_ROLE_ADMIN, or AUTH_ROLE_PRODUCTS
  • index(): Paginated list of unsent entries (50/page) — shows email, product name, creation date, status
  • group_products(): Grouped view showing product name, customer count, product codes, barcodes (300/page) — sorted by subscriber count descending
  • delete_waiting_list_row($id): Sets waiting_status=2 (soft delete), then redirects to index

Domain Layer

ComponentPath
Servicesrc/Domains/Product/WaitingList/Service.php
WriteServicesrc/Domains/Product/WaitingList/WriteService.php
Entitysrc/Domains/Product/WaitingList/Repository/Entity.php
Legacy Controllerecommercen/eshop/controllers/Adv_waiting_list.php
Admin Controllerecommercen/eshop/controllers/Adv_waiting_list_admin.php
Legacy Modelecommercen/eshop/models/Adv_waiting_list_model.php
Notification Jobecommercen/job/libraries/AdvSendEmailForWaitingList.php

Data Model

shop_waiting_list

ColumnTypeDescription
idint (PK, AI)Entry ID
emailvarchar(254)Subscriber email address
langvarchar(3)Language code at time of subscription
product_idint (FK)Product being watched
creation_datedatetimeWhen the subscription was created
waiting_statustinyint0=pending, 1=email sent, 2=deleted/dropped
email_sent_datedatetime (nullable)When the notification email was sent

Indexes: email, email+lang, product_id+waiting_status


Client Extension Points

  • Validation: Override validation() in Adv_waiting_list for custom rules
  • AI tracking: Override bookmarkToAdvisableAI() on the front controller
  • Notification job: Override AdvSendEmailForWaitingList by extending in application/modules/job/libraries/
  • Email template: Customize via adv_mailer->sendEmailForWaitingList() template
  • Feature toggle: Registry enable_waiting_list
  • Admin views: {client_views}/waiting_list/waiting_list and group_products templates