fp.certificate.contact_partner_id (single 'Customer Contact') becomes contact_partner_ids (Many2many) — same shape as the partner's Default CoC Contacts, as requested. - Auto-populate: at job creation (fp.job cert resolution) + lazy-fill at issue, contact_partner_ids = the customer's x_fc_default_coc_contact_ids (ALL). - Send: action_send_to_customer pre-fills the composer with exactly the cert's contact_partner_ids, so the CoC goes to all the defined clients (fallback: company). - Primary: the FIRST contact prints on the CoC + is gated for email; report uses contact_partner_ids[:1]. - Gate: requires >=1 Customer Contact + the primary has an email. - View: many2many_tags. - Migration 19.0.10.3.0: copies each cert's old single contact into the new M2m, drops the orphaned column. Deployed + verified on entech: migration copied 16 certs, old column dropped, field is M2m, send pre-fills the cert contacts, CoC report renders. entech-only part_line_ids preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1
|
|
"""Migrate the cert's single Customer Contact (Many2one) to a Many2many.
|
|
|
|
fp.certificate.contact_partner_id (single Many2one column) was renamed to
|
|
contact_partner_ids (Many2many -> res.partner, rel
|
|
fp_certificate_contact_partner_rel) so a cert can carry every contact who
|
|
receives the CoC. Odoo creates the new rel table during the schema-update
|
|
phase but leaves the old column orphaned. Copy each cert's single contact
|
|
into the new M2m (becomes the primary / printed addressee), then drop the
|
|
dead column. Guarded + idempotent.
|
|
"""
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def migrate(cr, version):
|
|
cr.execute("""
|
|
SELECT 1 FROM information_schema.columns
|
|
WHERE table_name = 'fp_certificate'
|
|
AND column_name = 'contact_partner_id'
|
|
""")
|
|
if not cr.fetchone():
|
|
return
|
|
cr.execute("""
|
|
SELECT 1 FROM information_schema.tables
|
|
WHERE table_name = 'fp_certificate_contact_partner_rel'
|
|
""")
|
|
if not cr.fetchone():
|
|
_logger.warning(
|
|
'fp_certificate_contact_partner_rel missing — skipping cert '
|
|
'customer-contact migration (rel table not created yet).')
|
|
return
|
|
cr.execute("""
|
|
INSERT INTO fp_certificate_contact_partner_rel (cert_id, partner_id)
|
|
SELECT c.id, c.contact_partner_id
|
|
FROM fp_certificate c
|
|
WHERE c.contact_partner_id IS NOT NULL
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM fp_certificate_contact_partner_rel r
|
|
WHERE r.cert_id = c.id
|
|
AND r.partner_id = c.contact_partner_id)
|
|
""")
|
|
moved = cr.rowcount
|
|
cr.execute(
|
|
"ALTER TABLE fp_certificate DROP COLUMN IF EXISTS contact_partner_id")
|
|
_logger.info(
|
|
'Cert customer-contact migration: copied %s single contact_partner_id '
|
|
'value(s) into the new contact_partner_ids M2m, dropped old column.',
|
|
moved)
|