feat(certificates): per-customer document preferences (CHUNK 1/4)
Customers can now pick which shipping-time documents they actually want instead of the shop remembering it per account. Four booleans on res.partner (only shown on companies, not contacts): x_fc_send_coc (default True) Certificate of Conformance x_fc_send_thickness_report (default True) Thickness readings x_fc_send_packing_slip (default True) Packing slip PDF x_fc_send_bol (default False) Bill of Lading Surfaced in a "Plating Documents" page on the customer form. Two downstream gates: 1. fp.notification.template._collect_attachments() now reads the flags when attaching CoC / thickness / packing / BoL PDFs to the shipping confirmation email. Flags missing on the partner (e.g. legacy customers) fall back to the original defaults so nothing regresses. 2. mrp.production.button_mark_done() only auto-creates the quality documents the customer wants. A customer that unchecks both CoC and thickness gets zero certs auto-generated — shop can still create them manually if needed. Note: today a standalone thickness-only report template doesn't exist, so when a customer asks for thickness only (CoC off, thickness on) the dispatcher still attaches the CoC PDF (which carries thickness data) but with CoC creation gated off. A dedicated thickness-only template is a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,26 @@ class FpNotificationTemplate(models.Model):
|
||||
_logger.warning('Failed to render %s: %s', xmlid, exc)
|
||||
return None
|
||||
|
||||
# Resolve the customer record — partner-level flags gate certain
|
||||
# documents so customer preferences override template defaults.
|
||||
customer = None
|
||||
if sale_order:
|
||||
customer = sale_order.partner_id
|
||||
elif portal_job:
|
||||
customer = portal_job.partner_id
|
||||
elif delivery:
|
||||
customer = delivery.partner_id
|
||||
elif invoice and getattr(invoice, 'partner_id', None):
|
||||
customer = invoice.partner_id
|
||||
elif production and portal_job:
|
||||
customer = portal_job.partner_id
|
||||
|
||||
def _customer_wants(flag, default=True):
|
||||
"""Respect the per-customer flag if the field exists; else default."""
|
||||
if customer and flag in customer._fields:
|
||||
return bool(getattr(customer, flag))
|
||||
return default
|
||||
|
||||
# Both attach_quotation and attach_sale_order point at the same
|
||||
# report today — render once to avoid double attachment.
|
||||
if (self.attach_quotation or self.attach_sale_order) and sale_order:
|
||||
@@ -198,7 +218,23 @@ class FpNotificationTemplate(models.Model):
|
||||
)
|
||||
if att:
|
||||
ids.append(att)
|
||||
if self.attach_coc and portal_job:
|
||||
# CoC — gated by customer preference (x_fc_send_coc, default True)
|
||||
if self.attach_coc and portal_job and _customer_wants('x_fc_send_coc'):
|
||||
att = _render_report(
|
||||
'fusion_plating_reports.action_report_coc', portal_job,
|
||||
)
|
||||
if att:
|
||||
ids.append(att)
|
||||
# Thickness report — gated by customer preference. Today the CoC
|
||||
# template embeds thickness readings, so when a customer wants
|
||||
# thickness-only we fall back to the CoC report attachment with
|
||||
# a distinct filename. A standalone thickness-only template is
|
||||
# TBD (not part of this chunk).
|
||||
if (self.attach_thickness_report and portal_job
|
||||
and _customer_wants('x_fc_send_thickness_report')
|
||||
and not (self.attach_coc and _customer_wants('x_fc_send_coc'))):
|
||||
# Avoid double-attaching the same PDF when both are wanted —
|
||||
# the CoC already carries the thickness data.
|
||||
att = _render_report(
|
||||
'fusion_plating_reports.action_report_coc', portal_job,
|
||||
)
|
||||
@@ -216,7 +252,15 @@ class FpNotificationTemplate(models.Model):
|
||||
)
|
||||
if att:
|
||||
ids.append(att)
|
||||
if self.attach_bol and delivery:
|
||||
# Packing slip — gated by customer preference (default True)
|
||||
if self.attach_packing_list and delivery and _customer_wants('x_fc_send_packing_slip'):
|
||||
att = _render_report(
|
||||
'fusion_plating_reports.action_report_fp_packing_slip_portrait', delivery,
|
||||
)
|
||||
if att:
|
||||
ids.append(att)
|
||||
# BoL — gated by customer preference (default False)
|
||||
if self.attach_bol and delivery and _customer_wants('x_fc_send_bol', default=False):
|
||||
att = _render_report(
|
||||
'fusion_plating_reports.action_report_fp_bol_portrait', delivery,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user