feat(tablet): mail template + notification + cleanup cron (Task 5)
Mail template renders the 4-digit code in both subject (mobile notification glance) and body (big bold display). Per Rule 25 only core res.users fields referenced; the code itself comes from ctx. fp.notification.template wrapper enables admin UI customization of the body without touching code. tablet_pin_reset_requested added to TRIGGER_EVENTS selection. Daily ir.cron purges used/expired rows > 7 days old (audit trail lives in fp.tablet.session.event, not here, so aggressive cleanup is safe). Manifest bump 19.0.34.2.0 -> 19.0.35.0.0 (triggers asset cache invalidation on -u so the new template + SCSS load cleanly). Phase 1 backend complete. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
Spec: docs/superpowers/specs/2026-05-25-tablet-pin-self-service-design.md
|
||||
|
||||
Email template + notification-template wrapper + cleanup cron for
|
||||
the tablet PIN self-service reset flow.
|
||||
|
||||
Per CLAUDE.md Rule 25 the mail.template references ONLY core
|
||||
res.users fields (object.name, object.email, object.login,
|
||||
object.company_id). The 4-digit code is passed in via context
|
||||
(ctx.code) when /fp/tablet/request_reset_code calls send_mail.
|
||||
-->
|
||||
<odoo noupdate="1">
|
||||
|
||||
<!-- ===== Mail template ============================================ -->
|
||||
<record id="fp_mail_template_tablet_pin_reset" model="mail.template">
|
||||
<field name="name">FP: Tablet PIN Reset Code</field>
|
||||
<field name="model_id" ref="base.model_res_users"/>
|
||||
<field name="subject">🔒 Your ENTECH tablet temporary PIN: {{ ctx.get('code', '----') }}</field>
|
||||
<field name="email_from">{{ (object.company_id.email or user.email) }}</field>
|
||||
<field name="email_to">{{ object.email or object.login }}</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="body_html" type="html">
|
||||
<div style="font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif; max-width: 600px; margin: 0 auto; padding: 32px 24px;">
|
||||
<div style="height: 4px; background-color: #1d4ed8; margin-bottom: 28px;"></div>
|
||||
<div style="font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #1d4ed8; font-weight: 600; margin-bottom: 8px;">
|
||||
Electroless Nickel Technologies Inc. (ENTECH)
|
||||
</div>
|
||||
<h2 style="margin: 0 0 8px 0; font-size: 22px; font-weight: bold;">Your tablet temporary PIN</h2>
|
||||
<p style="margin: 0 0 20px 0; font-size: 15px; opacity: 0.75;">
|
||||
Hi <t t-out="object.name"/>, use this 4-digit PIN to unlock the
|
||||
shop-floor tablet and set a new permanent PIN.
|
||||
</p>
|
||||
<div style="text-align: center; margin: 32px 0; padding: 24px; background: #f3f4f6; border-radius: 8px; font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 48px; font-weight: 700; letter-spacing: 0.3em; color: #1d4ed8;">
|
||||
<t t-out="ctx.get('code', '----')"/>
|
||||
</div>
|
||||
<p style="margin: 16px 0; font-size: 13px; opacity: 0.65;">
|
||||
This code expires in 72 hours. If you didn't request it, ignore
|
||||
this email — no action needed. The previous PIN (if any) stays
|
||||
valid until you successfully complete the reset on the tablet.
|
||||
</p>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- ===== fp.notification.template wrapper ========================= -->
|
||||
<record id="fp_notif_tablet_pin_reset" model="fp.notification.template">
|
||||
<field name="name">Tablet PIN Reset Code</field>
|
||||
<field name="trigger_event">tablet_pin_reset_requested</field>
|
||||
<field name="mail_template_id" ref="fp_mail_template_tablet_pin_reset"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- ===== Cleanup cron ============================================ -->
|
||||
<record id="cron_purge_expired_pin_resets" model="ir.cron">
|
||||
<field name="name">Fusion Plating: Purge expired tablet PIN reset codes</field>
|
||||
<field name="model_id" ref="model_fp_tablet_pin_reset"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._cron_purge_expired()</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user