Appearance
Delivery Delay Notifications
Flow ID: SY-15 | Module(s): job, eshop | Complexity: Medium Last Updated: 2026-04-04
Business Overview
When orders experience shipping delays, the platform proactively notifies customers via email before they contact support. The system identifies orders that have been pending shipment for too long (2+ or 3+ days depending on configuration) and sends an apology/information email. This builds customer trust by acknowledging delays transparently.
Two operating modes:
- Standard delay (
withWarningDelay=false): Targets orders 2+ days old without a delivery warning flag - Extended delay (
withWarningDelay=true): Targets orders 3+ days old that have the delivery warning flag set
The delivery_warning flag on orders allows merchants to manually flag orders expected to have longer processing times, giving those orders an extra day before the automated notification fires.
Architecture
AdvSendEmailForDeliveryDelay (JobCommand)
|
+--> order_model::sendMailForDelayOrderToCustomers($withWarningDelay)
|
+--> Query eligible orders:
| shop_order JOIN shop_customer
| status NOT IN (CANCELED, PENDING)
| store_id IS NULL
| delivery_warning = $withWarningDelay
| delivery_warning_msg_status = false
| invoised_date_time IS NULL
| canceled_date IS NULL
| entry_datetime >= 2019-01-01
| entry_datetime <= (now - 2 days) or (now - 3 days)
|
+--> For each order:
adv_mailer::sendCustomerInformDelay($order)
|
+--> order_model::setDeliveryWarningMsgStatus(1, $orderSerial)
+--> send email via orderInformDelay templateJob Classes
| Class | File | Purpose |
|---|---|---|
AdvSendEmailForDeliveryDelay | ecommercen/job/libraries/AdvSendEmailForDeliveryDelay.php | Base job implementation |
SendEmailForDeliveryDelay | application/modules/job/libraries/SendEmailForDeliveryDelay.php | Client-overridable subclass |
Supporting Classes
| Class | File | Role |
|---|---|---|
Adv_order_model | ecommercen/eshop/models/Adv_order_model.php | Order query and status update logic |
Adv_mailer | application/models/Adv_mailer.php | Email dispatch with delay template |
Code Flow
1. Job Initialization
The job is lightweight -- no constructor, just inline model loading in executeCommand():
executeCommand:
parse withWarningDelay option (bool, defaults to false)
load eshop/order_model
load adv_mailer
call order_model->sendMailForDelayOrderToCustomers($withWarningDelay)2. Calculate Cutoff Date
In sendMailForDelayOrderToCustomers():
date = now - 2 days
if withWarningDelay:
date = now - 3 days (additional -1 day)
toDate = date formatted as Y-m-d3. Query Eligible Orders
The method builds a query with these conditions:
| Condition | Purpose |
|---|---|
status NOT IN ('CANCELED', 'PENDING') | Only process active, accepted orders |
store_id IS NULL | Exclude store-pickup orders (those have different logistics) |
delivery_warning = $withWarningDelay | Match the delay tier (standard vs. flagged) |
delivery_warning_msg_status = false | Only orders not yet notified |
invoised_date_time IS NULL | Exclude already-invoiced orders (they shipped) |
canceled_date IS NULL | Exclude canceled orders |
entry_datetime >= '2019-01-01' | Safety floor to exclude very old legacy data |
entry_datetime <= $toDate | Only orders older than the threshold |
Results are ordered by entry_datetime ASC (oldest first) and include customer email and language from shop_customer.
4. Send Notifications
For each eligible order, calls adv_mailer->sendCustomerInformDelay($order):
- Validates that the order has
order_serialandmailproperties - Marks processed first: calls
order_model->setDeliveryWarningMsgStatus(1, $orderSerial)before sending -- this prevents reprocessing even if the email fails - Sends email using:
- Template:
orderInformDelay - Data: the full order object
- Subject:
EMAIL_SUBJECTS.CUSTOMER_INFORM_DELAY(supports%sfor order serial) - SMTP profile:
EMAIL_SHOP_MAILER
- Template:
Data Model
Primary Table: shop_order
| Column | Type | Role |
|---|---|---|
id | int | PK |
order_serial | varchar | Human-readable order number |
status | varchar | Order status |
entry_datetime | datetime | When the order was placed |
delivery_warning | boolean | Manually flagged for expected delay (gives extra day) |
delivery_warning_msg_status | boolean | Whether delay notification has been sent |
store_id | int/null | NULL = courier delivery; non-null = store pickup |
invoised_date_time | datetime/null | When invoiced (NULL = not yet shipped) |
canceled_date | datetime/null | When canceled (NULL = not canceled) |
customer_id | int | FK to shop_customer |
Related Tables
| Table | Relationship | Purpose |
|---|---|---|
shop_customer | customer_id -> id | Customer email (mail) and language (lang) |
Configuration
Job Scheduling (application/config/jobs.php)
Two entries are typically configured -- one for each delay tier:
php
// Standard delay (2+ days):
// ['command' => 'SendEmailForDeliveryDelay', 'schedule' => '0 10 * * *', 'graceTime' => 300, 'retryTimes' => 3],
// Extended delay (3+ days, for flagged orders):
// ['command' => 'SendEmailForDeliveryDelay', 'schedule' => '0 10 * * *', 'graceTime' => 300, 'retryTimes' => 3, 'options' => ['withWarningDelay' => true]],Commented out by default (client opt-in).
Job Options
| Option | Type | Required | Description |
|---|---|---|---|
withWarningDelay | bool | No | When true, targets orders 3+ days old with delivery_warning=true. Defaults to false (2+ days, no warning flag) |
Registry Settings
| Group | Key | Purpose |
|---|---|---|
EMAIL_SUBJECTS | CUSTOMER_INFORM_DELAY | Email subject template (supports %s for order serial) |
EMAIL_SHOP_MAILER | (group) | SMTP configuration for outbound shop emails |
Email Templates
| Template key | Description |
|---|---|
orderInformDelay | Apology/information email about the shipping delay |
Client Extension Points
Override the job class: Create
SendEmailForDeliveryDelayinapplication/modules/job/libraries/extendingAdvSendEmailForDeliveryDelay. OverrideexecuteCommand()to change delay thresholds or add custom filtering.Override the order model: Override
sendMailForDelayOrderToCustomers()inOrder_modelto change the query criteria (e.g., exclude specific payment methods, adjust the date threshold, add status filters).Override the mailer: Extend
Adv_mailerinapplication/models/to customizesendCustomerInformDelay()behavior (e.g., add admin CC, change template).Override email template: Place a custom
orderInformDelayview file inapplication/views/to change the email content.Dual-tier scheduling: Configure both standard and extended delay jobs with different schedules for granular control.
Business Rules
| Rule | Description |
|---|---|
| Two delay tiers | Standard (2+ days) and extended (3+ days with delivery_warning flag) |
| One notification per order | delivery_warning_msg_status flag prevents duplicate notifications |
| Courier orders only | store_id IS NULL excludes store-pickup orders from delay notifications |
| Active orders only | Excludes CANCELED and PENDING statuses, as well as already-invoiced and canceled orders |
| Mark-before-send | The status flag is set before the email is sent, preventing reprocessing on partial failures |
| Legacy data floor | Orders before 2019-01-01 are excluded via a hardcoded date floor |
| Per-client opt-in | Both job variants are commented out by default |
Related Flows
- SY-01 Cron Job Framework -- job scheduling and execution
- SY-24 Email Dispatch System --
Adv_mailerinternals, SMTP routing, and template rendering used to send delivery delay notifications - SY-02 Order Status Emails -- related order notification jobs
- AD-03 Order Management -- admin interface where
delivery_warningflag is set