Send targeted image banners and scheduled email reminders to clients and staff based on invoices, projects, tasks, proposals and estimates. Banners appear inside the Perfex admin and client portal. Emails fire automatically via cron based on date conditions. Reminder Groups control exactly who receives what and when. Full logs for both banners and emails are included.
before_cron_run fires regularly before relying on email delivery.
What you get
- Banner Manager — upload image banners with date ranges, links, close button control
- Reminder Groups — define who receives a banner or email and under which conditions
- Email Templates — HTML email editor with full Perfex merge field support
- Cron-based email delivery — fires once per day at a configurable hour
- Duplicate send prevention — each recipient gets each template only once per day
- Mail Logs — full send history with status, recipient, subject and error messages
- Banner Logs — view and close events per banner per user
- Dashboard — KPI tiles, views/closes chart, top banners, email activity
- CPB GrapeJS widget — drag banners into Client Portal Builder pages
- Staff permission system — restrict access by role
- Fully bilingual — DE / EN included
Setup
- Install and activate — menu item appears immediately under Smart Reminder
- Create a Reminder Group — defines recipients, date conditions and related object type
- Create a Banner — upload image, set dates, assign to a group
- Create an Email Template — write subject and HTML body, assign group, set date range
- Confirm Perfex cron is active — emails fire via
before_cron_runhook - Configure cron hour under Smart Reminder → Mail Manager
- View activity in Dashboard, Mail Logs and Banner Logs
Banners are image-based notifications shown inside Perfex admin (staff) or the client portal (clients). Each banner has its own date range, optional link, optional close button, and is assigned to a Reminder Group that controls who sees it.
Banner fields
- Title — internal name for admin use
- Image — uploaded file (jpg, jpeg, png, gif)
- Start date / End date — banner only shows within this range
- Banner link — optional URL the banner links to on click
- Close button — show or hide the dismiss button
- Group — Reminder Group that controls who sees this banner
- Status — active or inactive
How banners are shown
- Staff banners: injected into admin dashboard via
before_start_render_dashboard_contenthook - Client banners: injected into client portal via
app_customers_footerhook - JS (
smart_reminder.js) fetches eligible banners for the current user via AJAX - Banner history table tracks views and closes per user — prevents re-showing already-closed banners
- Multiple banners can be assigned to one group — displayed as a slideshow
Reminder Groups are the targeting engine. A group defines which staff members and which clients are eligible, what related object (invoice, project, task, proposal, estimate) must match, and what date conditions apply. Both banners and email templates are assigned to a group.
Staff targeting options
- All members
- By staff role
- Specific staff members
- Passive (excluded from this group)
Client targeting options
- All clients
- By client group
- Specific clients
- Passive (excluded from this group)
Date conditions
Supported date fields and operators
- Date field — invoice due date, project deadline, task due date, proposal expiry, estimate expiry
- Operators — equal, less than, greater than, plus N days, minus N days
- Preset offsets — 1, 3, 7, 15, 30, 45, 60 days before or after
- Date range — from / to bounds for when the condition is evaluated
Object types supported in groups
Supported relations
- Invoice — filter by status
- Project — filter by status
- Task — filter by status and priority
- Proposal — filter by status
- Estimate — filter by status
Group evaluation
- Groups are evaluated at cron time (email) or at JS load time (banners)
- Each group returns a list of eligible staff + their related object IDs, and clients + their related object IDs
- Email templates consume this list to build per-recipient sends
- Banner JS consumes the group ID to filter which banners are shown
Email templates define the subject and HTML body of reminder emails. They are assigned to a Reminder Group and have a start/end date range. The cron fires once daily and processes all active templates whose date range includes today.
Template fields
- Name — internal label
- Subject — email subject line (supports merge fields)
- Content — HTML email body (supports all Perfex merge fields)
- Group — Reminder Group that determines recipients
- Start date / End date — template only runs within this range
- Status — active or inactive
Supported merge fields
- Invoice merge fields — number, amount, due date, link
- Client merge fields — company, contact email, name
- Staff merge fields — name, email
- Project merge fields
- Task merge fields
- Proposal merge fields
- Estimate merge fields
Cron delivery logic
sr_email_cron() — step by step
- Fires on
before_cron_runhook - Checks configured cron hour — exits early if current hour is before the threshold
- Cleans stale entries from
sr_mail_logsandsr_template_run_logs(past dates) - Loads all active templates where today falls within start_date and end_date
- Skips templates that already have a run log entry for today
- For each template, calls the assigned group to resolve eligible staff and clients
- Checks
sr_mail_logsper recipient per template — skips already-sent combinations - Sends email, logs result to
sr_mail_logsandsr_send_mail_logs - After all recipients: inserts run log entry so template is not re-processed today
- Uses
$CI->email->send_queue()at the end — respects Perfex email queue settings
When the Client Portal Builder (CPB) is installed, Smart Reminder registers a custom GrapeJS block. Drag the block into any CPB page to embed banners or banner groups directly inside the client portal layout.
GrapeJS block traits
- Specific Banner — select a single active banner by name
- From Group — show banners from a Reminder Group dynamically
- Close Button — show or hide dismiss button in the embedded view
- Auto-Advance — slideshow mode for groups with multiple banners
- Interval (ms) — slideshow transition speed
- Image Fit — CSS object-fit behaviour (cover / contain / fill)
- Border Radius (px) — rounded corners on the banner image
How the CPB block renders
sr_cpb_editor_block()fires onapp_admin_footer— only on CPB editor pages- Passes available banners and groups as JSON to the GrapeJS block (
sr_cpb_block.js) sr_cpb_render.jsis loaded in the client portal footer (app_customers_footer)- Render script fetches banner content via
sr_public/get_banners_for_blockroute and injects it into the block placeholder - Route registered in
my_routes.phpwith marker// [SR_ROUTES]
Registered hooks
admin_init→sr_register_permissions()— registers staff capability for access controladmin_init→sr_init_menu()— builds sidebar menu (Dashboard, Banner Manager, Mail Manager, Groups, logs)before_start_render_dashboard_content→sr_banner_placeholder()— injects<div id="sr_staff_banner_div">into admin dashboardapp_admin_footer→sr_include_assets()— loadssmart_reminder.js+ CSS in adminapp_customers_footer→sr_include_assets()— loads assets in client portalapp_customers_footer→sr_cpb_render_script()— loads CPB block render JS in portalbefore_cron_run→sr_email_cron()— daily email dispatch engineapp_admin_footer→sr_cpb_editor_block()— injects GrapeJS block definition on CPB editor pages only
Admin controller routes
admin/smart_reminder/dashboard— KPI dashboard with charts and logsadmin/smart_reminder/manage— Banner Manager list and create/editadmin/smart_reminder/manage/logs— Banner Logs (views and closes)admin/smart_reminder/template— Email Template list and create/editadmin/smart_reminder/template/logs— Mail Logs (send history)admin/smart_reminder/group— Reminder Groups list and create/editadmin/smart_reminder/banner/{id}— individual banner CRUD actions
Public route (injected into my_routes.php)
sr_public/get_banners_for_block→smart_reminder/SrPublic/get_banners_for_block- Used by CPB render script to fetch banner content for embedded blocks
- Marker:
// [SR_ROUTES]— safe to re-run activation, will not duplicate
Staff permission
- Capability key:
smart_reminder - Check:
staff_can('smart_reminder', 'smart_reminder') - Menu and all admin routes are hidden from staff without this capability
{db_prefix}sr_banners
idINT AUTO_INCREMENT PRIMARY KEYbanner_nameVARCHAR(150) — internal titlebanner_fileVARCHAR(350) — uploaded image pathstatusTINYINT(4) DEFAULT 1start_date / end_dateDATE — active date rangecreated_byINT — staff IDcreated_dateDATETIMEgroup_idINT — assigned Reminder Groupbanner_linkVARCHAR(255) — click-through URLclose_buttonTINYINT(4) DEFAULT 1
{db_prefix}sr_banner_groups
idINT AUTO_INCREMENT PRIMARY KEYnameVARCHAR(255)statusTINYINT(4) DEFAULT 1client_typeVARCHAR(25) — all / group / specific / passivestaff_typeVARCHAR(25) — all / role / specific / passiveclient_optionsVARCHAR(500) — serialised targeting configstaff_optionsVARCHAR(500) — serialised targeting configgroup_orderINT DEFAULT 99
{db_prefix}sr_banner_history
idINT AUTO_INCREMENT PRIMARY KEYbanner_idINTstaff_idINT DEFAULT 0client_idINT DEFAULT 0statusVARCHAR(100) — viewed / closeddateDATETIME
{db_prefix}sr_templates
idINT AUTO_INCREMENT PRIMARY KEYname / subjectVARCHAR(255)group_idINT — assigned Reminder Groupcreated_byINT — staff IDcreated_dateDATETIMEcontentTEXT — HTML email bodystatusTINYINT(4) DEFAULT 1start_date / end_dateDATE — active range for cron processing
{db_prefix}sr_mail_logs — daily dedup table
- Tracks which template was sent to which recipient today
- Checked before each send — prevents duplicate sends on the same day
- Cleaned automatically by cron at the start of each run (past dates deleted)
- Columns: id, invoice_id, client_id, staff_id, template_id, date, rel_type
{db_prefix}sr_send_mail_logs — full send history
- Permanent record of every send attempt (success and failure)
- Columns: id, invoice_id, client_id, staff_id, template_id, date, template_subject, to_email, to_text, status, error_message, rel_type
{db_prefix}sr_template_run_logs — daily template guard
- One entry per template per day — prevents a template being processed twice in one day
- Cleaned automatically by cron at the start of each run (past dates deleted)
- Columns: id, template_id, date
Perfex options table entries
sr_cron_hour— integer hour (0–23) at which email cron processing starts, default 8
Server requirements
- Perfex CRM 3.0 or higher
- PHP 8.0 or higher
- MySQL 5.7+ / MariaDB 10.3+
application/config/my_routes.phpwritable (chmod 664)- Perfex cron active and running daily (for email delivery)
- Client Portal Builder installed (optional — for CPB block feature only)
If something does not work
- Emails not sending? → Confirm Perfex cron is active and
before_cron_runfires - Emails sending too late? → Adjust cron hour in Mail Manager settings
- Banners not showing? → Check group targeting — staff/client may not match group conditions
- CPB block not in editor? → Confirm CPB is installed and active
- Routes 404? → Check
my_routes.phppermissions — deactivate and reactivate to re-inject - Still stuck? → Email support with your domain and module version