Files
Odoo-Modules/fusion_plating/fusion_plating_notifications/models/fp_delivery.py
gsinghpal 0342535b9f feat(notifications): Sub 6 — contact profiles + communication routing
Five new boolean flags on res.partner applied to CHILD contacts:
x_fc_receives_certs, _qc, _quotes_so, _invoices, and _is_global_contact.
Single resolver helper res.partner._fp_resolve_notification_recipients
(stream, delivery_location=None) walks location contacts first then
company contacts, returning emails for contacts that opted into the
stream (or flagged themselves global). Falls back to partner.email
when no contact opts in so existing customers keep their exact
pre-Sub-6 routing.

fp.notification.template._dispatch now maps each trigger event to a
stream (so_confirmed→quotes_so, invoice_posted→invoices, shipped→
certs, etc.) and overrides the mail_template's email_to with the
resolved list. fp.delivery passes its delivery_address_id so the
shipped/CoC email routes through location-scoped contacts when they
exist.

Partner form gets a new "Communication Routing" tab on child contact
forms with the 5 flags (hides the per-stream checkboxes when
Global Contact is on, since it overrides them).

fusion_plating_certificates → 19.0.4.0.0 (adds the flag fields)
fusion_plating_notifications → 19.0.5.0.0 (+depends certificates)

Smoke on entech: 11/11 assertions pass including per-stream routing,
delivery-location scoping, zero-flag fallback, email-less skip,
unknown-stream + global behaviour, and case-insensitive dedup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:01:15 -04:00

35 lines
1.2 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
# Part of the Fusion Plating product family.
from odoo import models
class FpDelivery(models.Model):
_inherit = 'fusion.plating.delivery'
def action_mark_delivered(self):
res = super().action_mark_delivered()
Dispatch = self.env['fp.notification.template']
for rec in self:
if not rec.partner_id:
continue
so = False
if rec.job_ref:
# Delivery's job_ref is the MO name; find the SO via MO origin.
mo = self.env['mrp.production'].search(
[('name', '=', rec.job_ref)], limit=1,
)
if mo and mo.origin:
so = self.env['sale.order'].search(
[('name', '=', mo.origin)], limit=1,
)
# Sub 6 — pass the delivery address so location-scoped
# contacts receive the 'shipped' notification.
Dispatch._dispatch(
'shipped', rec, rec.partner_id, sale_order=so,
delivery_location=rec.delivery_address_id or False,
)
return res