chore(plating): de-dash shipped code + intake-neutral customer emails

Replace em-dashes and en-dashes with hyphens across 789 shipped source
files (py/xml/js/scss) so the delivered module reads as human-written;
em-dashes had become a recognizable AI-generated tell. Internal .md dev
notes are excluded. The WO-sticker mojibake strippers keep their dash
search targets (now written — / –). No logic changes: comments
and display strings only; validated with py_compile + lxml parse.

Rewrite the 7 customer notification emails to be intake-neutral
(ship-in / drop-off / pickup) and repair-aware, and fix the Shipped
email documents line (packing slip vs bill of lading; certificate only
when issued). Subjects use a hyphen separator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-06-05 00:16:19 -04:00
parent c9eb61ee0c
commit 8c76a16366
789 changed files with 4692 additions and 4692 deletions

View File

@@ -82,7 +82,7 @@ class FpContractReview(models.Model):
qty = fields.Integer(string='Qty')
due_date = fields.Date(string='Due')
# ---- Section 2.0 Planning / Production Review (Planning Review) ------
# ---- Section 2.0 - Planning / Production Review (Planning Review) ------
s20_acceptable_lead_time = fields.Boolean(string='Acceptable Lead Time')
s20_capacity_to_process = fields.Boolean(string='Capacity to Process')
@@ -121,7 +121,7 @@ class FpContractReview(models.Model):
copy=False,
)
# ---- Section 3.0 Quality Review (QA Review) --------------------------
# ---- Section 3.0 - Quality Review (QA Review) --------------------------
s30_source_control_docs = fields.Boolean(string="Source Control Documents (Customer Spec's)")
s30_quality_clauses_supplied = fields.Boolean(string='Quality Clause(s) supplied')
@@ -137,19 +137,19 @@ class FpContractReview(models.Model):
s30_accepted = fields.Boolean(string='Accepted (Section 3.0)')
s30_evaluate_risk = fields.Boolean(string='Evaluate Risk (Section 3.0)')
s30_risk_consequence = fields.Selection(
[('1', '1 Minimal'),
('2', '2 Moderate'),
('3', '3 Mod. / Applicable'),
('4', '4 Major / Changes'),
('5', '5 Unacceptable')],
[('1', '1 - Minimal'),
('2', '2 - Moderate'),
('3', '3 - Mod. / Applicable'),
('4', '4 - Major / Changes'),
('5', '5 - Unacceptable')],
string='Consequence',
)
s30_risk_likelihood = fields.Selection(
[('1', '1 Not Likely'),
('2', '2 Low Likelihood'),
('3', '3 Likely'),
('4', '4 Highly Likely'),
('5', '5 Near Certainty')],
[('1', '1 - Not Likely'),
('2', '2 - Low Likelihood'),
('3', '3 - Likely'),
('4', '4 - Highly Likely'),
('5', '5 - Near Certainty')],
string='Likelihood',
)
s30_risk_band = fields.Selection(
@@ -193,14 +193,14 @@ class FpContractReview(models.Model):
tracking=True,
)
# ---- "Failed QA Awaiting Client Info" workflow ------------------------
# ---- "Failed QA - Awaiting Client Info" workflow ------------------------
# When a QA Signer (Brett or whoever the company has rostered) finds a
# client requirement that fails during the QA Review, they mark the
# review failed. The state moves to `awaiting_info`, an activity is
# scheduled for every QA Signer to follow up, and a smart button on
# the form gives them a one-click email composer to ping the client.
# When the client replies, the QA Signer captures notes in
# `special_instructions` and marks complete the notes print on the
# `special_instructions` and marks complete - the notes print on the
# final QA-005 PDF for the audit trail.
qa_failure_reason = fields.Html(
string='QA Failure Reason',
@@ -232,7 +232,7 @@ class FpContractReview(models.Model):
)
client_email_count = fields.Integer(
compute='_compute_client_email_count',
help='Smart-button counter number of emails posted to chatter '
help='Smart-button counter - number of emails posted to chatter '
'against this review. Always non-zero after the first send.',
)
@@ -257,7 +257,7 @@ class FpContractReview(models.Model):
def _compute_name(self):
for rec in self:
if rec.part_id:
rec.name = _('QA-005 %(pn)s Rev %(rev)s') % {
rec.name = _('QA-005 - %(pn)s Rev %(rev)s') % {
'pn': rec.part_id.part_number or _('(no part#)'),
'rev': rec.part_id.revision or _('(no rev)'),
}
@@ -313,7 +313,7 @@ class FpContractReview(models.Model):
return True
# Checklist fields per section, for the "Check All" / "Clear All"
# bulk-toggle buttons. Only the checklist boxes are flipped
# bulk-toggle buttons. Only the checklist boxes are flipped -
# outcome fields (Accepted, Evaluate Risk, Risk Level / Matrix,
# Mitigation Plan Required) remain under the user's explicit
# decision so they don't get accidentally ticked.
@@ -347,7 +347,7 @@ class FpContractReview(models.Model):
self.ensure_one()
if self[locked_field]:
raise UserError(_(
'Section is already signed checklist is locked.'
'Section is already signed - checklist is locked.'
))
self.write({f: value for f in fields_tuple})
return True
@@ -405,7 +405,7 @@ class FpContractReview(models.Model):
'fusion_plating_quality.action_report_contract_review'
).report_action(self)
# ---- "Failed QA Awaiting Client Info" workflow ------------------------
# ---- "Failed QA - Awaiting Client Info" workflow ------------------------
def action_mark_qa_failed(self):
"""QA Signer marks the review failed because a client requirement
is missing or unclear. Captures the reason, flips state to
@@ -418,13 +418,13 @@ class FpContractReview(models.Model):
'Only a review at the QA Review (or Planning Review) stage '
'can be flagged as failed. Current state: %s.'
) % dict(self._fields['state'].selection).get(self.state, self.state))
# Reuse the section-30 signer roster the same group of people
# Reuse the section-30 signer roster - the same group of people
# who can sign QA can flag a QA failure.
self._check_signer(30)
if not self.qa_failure_reason or not self.qa_failure_reason.strip():
raise UserError(_(
'Capture the QA Failure Reason before flagging the '
'review failed the reason pre-fills the client email '
'review failed - the reason pre-fills the client email '
'and is required for the audit trail.'
))
self.write({'state': 'awaiting_info'})
@@ -449,7 +449,7 @@ class FpContractReview(models.Model):
for user in signers:
self.activity_schedule(
activity_type_id=activity_type.id if activity_type else False,
summary=_('Follow up on QA-005 client info required'),
summary=_('Follow up on QA-005 - client info required'),
note=self.qa_failure_reason or '',
user_id=user.id,
date_deadline=fields.Date.context_today(self) +
@@ -458,14 +458,14 @@ class FpContractReview(models.Model):
return True
def action_open_client_email_wizard(self):
"""Smart-button target opens the email composer wizard pre-filled
"""Smart-button target - opens the email composer wizard pre-filled
with the customer's contact email + a body templated from the
QA failure reason. The wizard handles the actual mail.mail send
and stamps `info_requested_date` on this review."""
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': _('Email Client Request Info'),
'name': _('Email Client - Request Info'),
'res_model': 'fp.contract.review.client.email.wizard',
'view_mode': 'form',
'target': 'new',
@@ -479,12 +479,12 @@ class FpContractReview(models.Model):
}
def action_view_client_emails(self):
"""Drill-down behind the smart button counter shows the chatter
"""Drill-down behind the smart button counter - shows the chatter
messages of type=email for this review."""
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': _('Client Emails %s') % self.name,
'name': _('Client Emails - %s') % self.name,
'res_model': 'mail.message',
'view_mode': 'list,form',
'domain': [
@@ -520,7 +520,7 @@ class FpContractReview(models.Model):
# everyone's inbox once the case is closed.
self.activity_feedback(
['mail.mail_activity_data_todo'],
feedback=_('Client info received review closed.'),
feedback=_('Client info received - review closed.'),
)
self.message_post(body=Markup(_(
'<b>QA Review completed</b> by %(user)s after receiving '