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:
gsinghpal
2026-06-02 08:50:25 -04:00
parent 7fcf38ca82
commit 9a8e1d7ab5
6 changed files with 99 additions and 17 deletions

View File

@@ -85,7 +85,19 @@
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input type="hidden" name="assessment_id" t-att-value="assessment.id if assessment else ''"/>
<input type="hidden" name="current_page" value="1"/>
<input type="hidden" name="visit_id" id="express_visit_id" t-att-value="visit_id or ''"/>
<!-- Part of an assessment visit: completing returns to the visit, which groups
this device with the rest into one funding-routed ADP order. -->
<div t-if="visit_id" class="alert alert-info d-flex align-items-start gap-2 mb-3">
<i class="fa fa-clipboard mt-1"/>
<div>
<strong>Part of an assessment visit.</strong>
Completing this device returns you to the visit — it is grouped with the
visit's other ADP devices into a single sale order when you complete the visit.
</div>
</div>
<!-- Equipment Selection Section -->
<div class="card shadow-sm">
<div class="card-body">
@@ -1246,9 +1258,10 @@
<div class="card shadow-sm">
<div class="card-body text-center">
<button type="submit" name="action" value="submit" class="btn btn-success btn-lg px-5">
<i class="fa fa-check me-2"/>Submit Assessment
<t t-if="visit_id"><i class="fa fa-clipboard me-2"/>Save to Visit</t>
<t t-else=""><i class="fa fa-check me-2"/>Submit Assessment</t>
</button>
<a href="/my/assessments" class="btn btn-outline-secondary btn-lg px-4 ms-3">
<a t-att-href="('/my/visit/%s' % visit_id) if visit_id else '/my/assessments'" class="btn btn-outline-secondary btn-lg px-4 ms-3">
Cancel
</a>
</div>

View File

@@ -50,6 +50,25 @@
<!-- Main Action Tiles - Professional Grid Layout -->
<div class="row g-3 mb-4">
<!-- 0. Start a Visit (Sales Rep) - bundle multiple assessments from one home visit -->
<t t-if="request.env.user.partner_id.is_sales_rep_portal">
<div class="col-md-6">
<a href="/my/visit/new" class="card h-100 border-0 shadow-sm text-decoration-none" style="border-radius: 12px; min-height: 100px; background: linear-gradient(135deg, #5ba848 0%, #3a8fb7 100%);">
<div class="card-body d-flex align-items-center p-4 text-white">
<div class="me-3">
<div class="icon-circle">
<i class="fa fa-clipboard"/>
</div>
</div>
<div>
<h5 class="mb-1">Start a Visit</h5>
<small>Bundle several assessments from one home visit into funding-routed orders</small>
</div>
</div>
</a>
</div>
</t>
<!-- 1. New Express Assessment (Sales Rep) - Featured tile -->
<t t-if="request.env.user.partner_id.is_sales_rep_portal">
<div class="col-md-6">