feat(fusion_portal): ADP/express->visit wiring, visit entry tile, email consolidation (live on westin 19.0.2.10.0)
- express save captures visit_id; visit-linked submit defers SO creation (saves draft + signature) and returns to the visit for grouping. - portal dashboard 'Start a Visit' tile for sales reps. - fix duplicate-authorizer completion email; visit grouped SOs email once per SO. - define visit._assessment_sale_type (ADP grouping key) - fixes AttributeError. Verified on a westin-v19 clone (load + ADP-grouping + combination-guard smoke test, mail neutralised) then deployed to westin prod 19.0.2.10.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1486,20 +1486,18 @@ class FusionAssessment(models.Model):
|
||||
})
|
||||
|
||||
def _send_completion_notifications(self):
|
||||
"""Send email notifications when assessment is completed"""
|
||||
"""Notify the CLIENT that the assessment is complete.
|
||||
|
||||
The authorizer, sales rep and office are already emailed (with the full
|
||||
assessment report) by ``_send_assessment_completed_email`` inside
|
||||
``_create_draft_sale_order``. This method used to ALSO send the
|
||||
authorizer a second, template-only email — that duplicate is removed;
|
||||
here we only notify the client.
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
# Send to authorizer
|
||||
if self.authorizer_id and self.authorizer_id.email:
|
||||
try:
|
||||
template = self.env.ref('fusion_portal.mail_template_assessment_complete_authorizer', raise_if_not_found=False)
|
||||
if template:
|
||||
template.send_mail(self.id, force_send=True)
|
||||
_logger.info(f"Sent assessment completion email to authorizer {self.authorizer_id.email}")
|
||||
except Exception as e:
|
||||
_logger.error(f"Failed to send authorizer notification: {e}")
|
||||
|
||||
# Send to client
|
||||
|
||||
# Send to client (authorizer/rep/office already emailed by
|
||||
# _send_assessment_completed_email in _create_draft_sale_order)
|
||||
if self.client_email:
|
||||
try:
|
||||
template = self.env.ref('fusion_portal.mail_template_assessment_complete_client', raise_if_not_found=False)
|
||||
|
||||
@@ -184,6 +184,16 @@ class FusionAssessmentVisit(models.Model):
|
||||
subtype_xmlid='mail.mt_note',
|
||||
)
|
||||
assessment.write({'state': 'completed'})
|
||||
# One completion notification per SO (not per assessment) — mirrors the
|
||||
# standalone accessibility completion's office email.
|
||||
if accessibility_assessments:
|
||||
try:
|
||||
accessibility_assessments[0]._send_completion_email(sale_order)
|
||||
except Exception as e:
|
||||
_logger.warning(
|
||||
"Visit %s: completion email failed for %s: %s",
|
||||
self.name, sale_order.name, e,
|
||||
)
|
||||
_logger.info(
|
||||
"Visit %s created %s sale order %s grouping %d accessibility assessment(s)",
|
||||
self.name, sale_type, sale_order.name, len(accessibility_assessments),
|
||||
@@ -206,6 +216,15 @@ class FusionAssessmentVisit(models.Model):
|
||||
if len(walkers) > 1:
|
||||
raise UserError(_('An ADP order can include only one walker / rollator.'))
|
||||
|
||||
def _assessment_sale_type(self, adp_assessment):
|
||||
"""Funding workflow key for an ADP equipment assessment, mirroring
|
||||
fusion.assessment._create_draft_sale_order: ADP+ODSP when the client
|
||||
type is an ODSP stream, plain ADP otherwise. ADP devices that share a
|
||||
key are grouped onto one sale order."""
|
||||
if adp_assessment.client_type in ('ods', 'acs', 'owp'):
|
||||
return 'adp_odsp'
|
||||
return 'adp'
|
||||
|
||||
def action_complete_visit(self):
|
||||
"""Group the visit's accessibility assessments by funding workflow and
|
||||
create one draft SO per workflow. ADP equipment assessments keep their
|
||||
|
||||
Reference in New Issue
Block a user