# Fusion Authorizer & Sales Portal **Version:** 19.0.1.0.0 **License:** LGPL-3 **Category:** Sales/Portal **Author:** Fusion Claims ## Table of Contents 1. [Overview](#overview) 2. [Features](#features) 3. [Installation](#installation) 4. [Configuration](#configuration) 5. [Models](#models) 6. [Controllers & Routes](#controllers--routes) 7. [Security](#security) 8. [Frontend Assets](#frontend-assets) 9. [Email Templates](#email-templates) 10. [User Guide](#user-guide) 11. [API Reference](#api-reference) 12. [Troubleshooting](#troubleshooting) 13. [Changelog](#changelog) --- ## Overview The **Fusion Authorizer & Sales Portal** module extends Odoo's portal functionality to provide external access for two key user types: - **Authorizers (Occupational Therapists/OTs):** Healthcare professionals who authorize ADP (Assistive Devices Program) claims - **Sales Representatives:** Field sales staff who conduct client assessments and manage orders This module integrates with the `fusion_claims` module to provide a seamless workflow for ADP claims management, from initial client assessment through to order completion. ### Target Platform - **Odoo Enterprise v19** - Requires: `base`, `sale`, `portal`, `website`, `mail`, `fusion_claims` --- ## Features ### Authorizer Portal - View all assigned ADP cases with full details (excluding internal costs) - Real-time search by client name, reference numbers, or claim number - Upload ADP application documents with revision tracking - Add comments/notes to cases - Download submitted ADP applications - Receive email notifications for new assignments and status changes ### Sales Rep Portal - View sales cases linked to the logged-in user - Start and manage client assessments - Record detailed wheelchair specifications and measurements - Capture digital signatures for ADP pages 11 & 12 - Track assessment progress through workflow states ### Assessment System - Comprehensive client information collection - Wheelchair specifications (seat width, depth, height, cushion type, etc.) - Accessibility and mobility needs documentation - Touch-friendly digital signature capture - Automatic draft Sale Order creation upon completion - Document distribution to authorizers, sales reps, and internal records - Automated email notifications --- ## Installation ### Prerequisites 1. Odoo Enterprise v19 installed and running 2. The `fusion_claims` module installed and configured 3. Portal module enabled 4. Website module enabled 5. Mail module configured with outgoing email server ### Installation Steps 1. **Copy the module** to your Odoo addons directory: ```bash cp -r fusion_authorizer_portal /path/to/odoo/custom-addons/ ``` 2. **Update the apps list** in Odoo: - Go to Apps menu - Click "Update Apps List" - Search for "Fusion Authorizer" 3. **Install the module**: - Click Install on "Fusion Authorizer & Sales Portal" - Wait for installation to complete 4. **Restart Odoo** (recommended): ```bash docker restart odoo-app # For Docker installations # OR sudo systemctl restart odoo # For systemd installations ``` --- ## Configuration ### Granting Portal Access to Users 1. Navigate to **Contacts** in Odoo backend 2. Open the contact record for the authorizer or sales rep 3. Go to the **Portal Access** tab 4. Check the appropriate role: - `Is Authorizer` - For Occupational Therapists - `Is Sales Rep (Portal)` - For Sales Representatives 5. Click the **Grant Portal Access** button 6. An invitation email will be sent to the contact's email address ### Setting Up Authorizers on Sales Orders 1. Open a Sales Order 2. In the order details, set the **Authorizer** field (`x_fc_authorizer_id`) 3. The authorizer will receive an email notification about the assignment 4. The case will appear in their portal dashboard --- ## Models ### New Models #### `fusion.assessment` **Wheelchair Assessment Record** Captures comprehensive client assessment data including: | Field Group | Fields | |-------------|--------| | **Client Info** | `client_name`, `client_first_name`, `client_last_name`, `client_street`, `client_city`, `client_state`, `client_postal_code`, `client_country_id`, `client_phone`, `client_mobile`, `client_email`, `client_dob`, `client_health_card`, `client_reference_1`, `client_reference_2` | | **Participants** | `sales_rep_id` (res.users), `authorizer_id` (res.partner) | | **Assessment Details** | `assessment_date`, `assessment_location`, `assessment_location_notes` | | **Measurements** | `seat_width`, `seat_depth`, `seat_to_floor_height`, `back_height`, `armrest_height`, `footrest_length`, `overall_width`, `overall_length`, `overall_height`, `seat_angle`, `back_angle`, `client_weight`, `client_height` | | **Product Types** | `cushion_type`, `cushion_notes`, `backrest_type`, `backrest_notes`, `frame_type`, `frame_notes`, `wheel_type`, `wheel_notes` | | **Needs** | `mobility_notes`, `accessibility_notes`, `special_requirements`, `diagnosis` | | **Signatures** | `signature_page_11`, `signature_page_11_name`, `signature_page_11_date`, `signature_page_12`, `signature_page_12_name`, `signature_page_12_date` | | **Status** | `state` (draft, pending_signature, completed, cancelled) | | **References** | `reference` (auto-generated ASM-XXXXX), `sale_order_id`, `partner_id` | **Key Methods:** - `action_complete()` - Completes assessment, creates draft Sale Order, sends notifications - `_ensure_partner()` - Creates or links res.partner for the client - `_create_draft_sale_order()` - Generates Sale Order with specifications - `_generate_signed_documents()` - Creates document records for signatures - `_send_completion_notifications()` - Sends emails to authorizer and client --- #### `fusion.adp.document` **ADP Document Management with Revision Tracking** | Field | Type | Description | |-------|------|-------------| | `sale_order_id` | Many2one | Link to Sale Order | | `assessment_id` | Many2one | Link to Assessment | | `document_type` | Selection | full_application, page_11, page_12, pages_11_12, final_submission, other | | `file` | Binary | Document file content | | `filename` | Char | Original filename | | `file_size` | Integer | File size in bytes | | `mimetype` | Char | MIME type | | `revision` | Integer | Revision number (auto-incremented) | | `revision_note` | Text | Notes about this revision | | `is_current` | Boolean | Whether this is the current version | | `uploaded_by` | Many2one | User who uploaded | | `upload_date` | Datetime | Upload timestamp | | `source` | Selection | portal, internal, assessment | **Key Methods:** - `action_download()` - Download the document - `get_documents_for_order()` - Get all documents for a sale order - `get_revision_history()` - Get all revisions of a document type --- #### `fusion.authorizer.comment` **Portal Comments System** | Field | Type | Description | |-------|------|-------------| | `sale_order_id` | Many2one | Link to Sale Order | | `assessment_id` | Many2one | Link to Assessment | | `author_id` | Many2one | res.partner who authored | | `author_user_id` | Many2one | res.users who authored | | `comment` | Text | Comment content | | `comment_type` | Selection | general, question, update, approval | | `is_internal` | Boolean | Internal-only comment | --- ### Extended Models #### `res.partner` (Extended) | New Field | Type | Description | |-----------|------|-------------| | `is_authorizer` | Boolean | Partner is an Authorizer/OT | | `is_sales_rep_portal` | Boolean | Partner is a Sales Rep with portal access | | `authorizer_portal_user_id` | Many2one | Linked portal user account | | `assigned_case_count` | Integer | Computed count of assigned cases | | `assessment_count` | Integer | Computed count of assessments | **New Methods:** - `action_grant_portal_access()` - Creates portal user and sends invitation - `action_view_assigned_cases()` - Opens list of assigned Sale Orders - `action_view_assessments()` - Opens list of assessments --- #### `sale.order` (Extended) | New Field | Type | Description | |-----------|------|-------------| | `portal_comment_ids` | One2many | Comments from portal users | | `portal_comment_count` | Integer | Computed comment count | | `portal_document_ids` | One2many | Documents uploaded via portal | | `portal_document_count` | Integer | Computed document count | | `assessment_id` | Many2one | Source assessment that created this order | | `portal_authorizer_id` | Many2one | Authorizer reference (computed from x_fc_authorizer_id) | **New Methods:** - `_send_authorizer_assignment_notification()` - Email on authorizer assignment - `_send_status_change_notification()` - Email on status change - `get_portal_display_data()` - Safe data for portal display (excludes costs) - `get_authorizer_portal_cases()` - Search cases for authorizer portal - `get_sales_rep_portal_cases()` - Search cases for sales rep portal --- ## Controllers & Routes ### Authorizer Portal Routes | Route | Method | Auth | Description | |-------|--------|------|-------------| | `/my/authorizer` | GET | user | Authorizer dashboard | | `/my/authorizer/cases` | GET | user | List of assigned cases | | `/my/authorizer/cases/search` | POST | user | AJAX search (jsonrpc) | | `/my/authorizer/case/` | GET | user | Case detail view | | `/my/authorizer/case//comment` | POST | user | Add comment to case | | `/my/authorizer/case//upload` | POST | user | Upload document | | `/my/authorizer/document//download` | GET | user | Download document | ### Sales Rep Portal Routes | Route | Method | Auth | Description | |-------|--------|------|-------------| | `/my/sales` | GET | user | Sales rep dashboard | | `/my/sales/cases` | GET | user | List of sales cases | | `/my/sales/cases/search` | POST | user | AJAX search (jsonrpc) | | `/my/sales/case/` | GET | user | Case detail view | ### Assessment Routes | Route | Method | Auth | Description | |-------|--------|------|-------------| | `/my/assessments` | GET | user | List of assessments | | `/my/assessment/new` | GET | user | New assessment form | | `/my/assessment/` | GET | user | View/edit assessment | | `/my/assessment/save` | POST | user | Save assessment data | | `/my/assessment//signatures` | GET | user | Signature capture page | | `/my/assessment//save_signature` | POST | user | Save signature (jsonrpc) | | `/my/assessment//complete` | POST | user | Complete assessment | --- ## Security ### Security Groups | Group | XML ID | Description | |-------|--------|-------------| | Authorizer Portal | `group_authorizer_portal` | Access to authorizer portal features | | Sales Rep Portal | `group_sales_rep_portal` | Access to sales rep portal features | ### Record Rules | Model | Rule | Description | |-------|------|-------------| | `fusion.authorizer.comment` | Portal Read | Users can read non-internal comments on their cases | | `fusion.authorizer.comment` | Portal Create | Users can create comments on their cases | | `fusion.adp.document` | Portal Read | Users can read documents on their cases | | `fusion.adp.document` | Portal Create | Users can upload documents to their cases | | `fusion.assessment` | Portal Access | Users can access assessments they're linked to | | `sale.order` | Portal Authorizer | Authorizers can view their assigned orders | ### Access Rights (ir.model.access.csv) | Model | Group | Read | Write | Create | Unlink | |-------|-------|------|-------|--------|--------| | `fusion.authorizer.comment` | base.group_user | 1 | 1 | 1 | 1 | | `fusion.authorizer.comment` | base.group_portal | 1 | 0 | 1 | 0 | | `fusion.adp.document` | base.group_user | 1 | 1 | 1 | 1 | | `fusion.adp.document` | base.group_portal | 1 | 0 | 1 | 0 | | `fusion.assessment` | base.group_user | 1 | 1 | 1 | 1 | | `fusion.assessment` | base.group_portal | 1 | 1 | 1 | 0 | --- ## Frontend Assets ### CSS (`static/src/css/portal_style.css`) Custom portal styling with a dark blue and green color scheme: - **Primary Color:** Dark blue (#1e3a5f) - **Secondary Color:** Medium blue (#2c5282) - **Accent Color:** Green (#38a169) - **Background:** Light gray (#f7fafc) Styled components: - Portal cards with shadow effects - Status badges with color coding - Custom buttons with hover effects - Responsive tables - Form inputs with focus states ### JavaScript #### `portal_search.js` Real-time search functionality: - Debounced input handling (300ms delay) - AJAX calls to search endpoints - Dynamic table updates - Search result highlighting #### `assessment_form.js` Assessment form enhancements: - Unsaved changes warning - Auto-fill client name from first/last name - Number input validation - Form state tracking #### `signature_pad.js` Digital signature capture: - HTML5 Canvas-based drawing - Touch and mouse event support - Clear signature functionality - Export to base64 PNG - AJAX save to server --- ## Email Templates ### Case Assignment (`mail_template_case_assigned`) **Trigger:** Authorizer assigned to a Sale Order **Recipient:** Authorizer email **Content:** Case details, client information, link to portal ### Status Change (`mail_template_status_changed`) **Trigger:** Sale Order state changes **Recipient:** Assigned authorizer **Content:** Previous and new status, case details ### Assessment Complete - Authorizer (`mail_template_assessment_complete_authorizer`) **Trigger:** Assessment completed **Recipient:** Assigned authorizer **Content:** Assessment details, measurements, signed documents ### Assessment Complete - Client (`mail_template_assessment_complete_client`) **Trigger:** Assessment completed **Recipient:** Client email **Content:** Confirmation, next steps, measurements summary ### Document Uploaded (`mail_template_document_uploaded`) **Trigger:** Document uploaded via portal **Recipient:** Internal team **Content:** Document details, revision info, download link --- ## User Guide ### For Administrators #### Granting Portal Access 1. Go to **Contacts** > Select the contact 2. Navigate to the **Portal Access** tab 3. Enable the appropriate role: - Check `Is Authorizer` for OTs/Therapists - Check `Is Sales Rep (Portal)` for Sales Reps 4. Click **Grant Portal Access** 5. The user receives an email with login instructions #### Assigning Cases to Authorizers 1. Open a **Sale Order** 2. Set the **Authorizer** field to the appropriate contact 3. Save the order 4. The authorizer receives a notification email 5. The case appears in their portal dashboard --- ### For Authorizers #### Accessing the Portal 1. Visit `https://your-domain.com/my` 2. Log in with your portal credentials 3. Click **Authorizer Portal** in the menu #### Viewing Cases 1. From the dashboard, view recent cases and statistics 2. Click **View All Cases** or **My Cases** for the full list 3. Use the search bar to find specific cases by: - Client name - Client reference 1 or 2 - Claim number #### Adding Comments 1. Open a case detail view 2. Scroll to the Comments section 3. Enter your comment 4. Select comment type (General, Question, Update, Approval) 5. Click **Add Comment** #### Uploading Documents 1. Open a case detail view 2. Go to the Documents section 3. Click **Upload Document** 4. Select document type (Full Application, Page 11, Page 12, etc.) 5. Choose the file and add revision notes 6. Click **Upload** --- ### For Sales Representatives #### Starting a New Assessment 1. Log in to the portal 2. Click **New Assessment** 3. Fill in client information: - Name, address, contact details - Client references 4. Record wheelchair specifications: - Measurements (seat width, depth, height) - Product types (cushion, backrest, frame, wheels) 5. Document accessibility and mobility needs 6. Click **Save & Continue** #### Capturing Signatures 1. After saving assessment data, click **Proceed to Signatures** 2. **Page 11 (Authorizer):** - Have the OT sign on the canvas - Enter their printed name - Click **Save Signature** 3. **Page 12 (Client):** - Have the client sign on the canvas - Enter their printed name - Click **Save Signature** #### Completing the Assessment 1. Once both signatures are captured, click **Complete Assessment** 2. The system will: - Create a new customer record (if needed) - Generate a draft Sale Order - Attach signed documents - Send notification emails 3. The assessment moves to "Completed" status --- ## API Reference ### Assessment Model Methods ```python # Complete an assessment and create Sale Order assessment.action_complete() # Get formatted specifications for order notes specs = assessment._format_specifications_for_order() # Ensure partner exists or create new partner = assessment._ensure_partner() ``` ### Sale Order Portal Methods ```python # Get safe data for portal display (no costs) data = order.get_portal_display_data() # Search cases for authorizer cases = SaleOrder.get_authorizer_portal_cases( partner_id=123, search_query='Smith', limit=50, offset=0 ) # Search cases for sales rep cases = SaleOrder.get_sales_rep_portal_cases( user_id=456, search_query='wheelchair', limit=50, offset=0 ) ``` ### Partner Methods ```python # Grant portal access programmatically partner.action_grant_portal_access() # Check if partner is an authorizer if partner.is_authorizer: cases = partner.assigned_case_count ``` ### Document Methods ```python # Get all documents for an order docs = ADPDocument.get_documents_for_order(sale_order_id) # Get revision history history = document.get_revision_history() ``` --- ## Troubleshooting ### Common Errors #### Error: `Invalid field 'in_portal' in 'portal.wizard.user'` **Cause:** Odoo 19 changed the portal wizard API, removing the `in_portal` field. **Solution:** The `action_grant_portal_access` method has been updated to: 1. First attempt using the standard portal wizard 2. If that fails, fall back to direct user creation with portal group assignment ```python # The fallback code creates the user directly: portal_group = self.env.ref('base.group_portal') portal_user = self.env['res.users'].sudo().create({ 'name': self.name, 'login': self.email, 'email': self.email, 'partner_id': self.id, 'groups_id': [(6, 0, [portal_group.id])], }) ``` --- #### Error: `Invalid view type: 'tree'` **Cause:** Odoo 19 renamed `` views to ``. **Solution:** Replace all `` tags with `` in XML view definitions: ```xml ... ... ``` --- #### Error: `Invalid field 'category_id' in 'res.groups'` **Cause:** Odoo 19 no longer supports `category_id` in `res.groups` XML definitions. **Solution:** Remove the `` element from security group definitions: ```xml ``` --- #### Error: `DeprecationWarning: @route(type='json') is deprecated` **Cause:** Odoo 19 uses `type='jsonrpc'` instead of `type='json'`. **Solution:** Update route decorators: ```python # Old @http.route('/my/endpoint', type='json', auth='user') # New @http.route('/my/endpoint', type='jsonrpc', auth='user') ``` --- ### Portal Access Issues #### User can't see cases in portal 1. Verify the partner has `is_authorizer` or `is_sales_rep_portal` checked 2. Verify the `authorizer_portal_user_id` is set 3. For authorizers, verify the Sale Order has `x_fc_authorizer_id` set to their partner ID 4. For sales reps, verify the Sale Order has `user_id` set to their user ID #### Email notifications not sending 1. Check that the outgoing mail server is configured in Odoo 2. Verify the email templates exist and are active 3. Check the mail queue (Settings > Technical > Email > Emails) 4. Review the Odoo logs for mail errors --- ### Debug Logging Enable debug logging for this module: ```python import logging _logger = logging.getLogger('fusion_authorizer_portal') _logger.setLevel(logging.DEBUG) ``` Or in Odoo configuration: ```ini [options] log_handler = fusion_authorizer_portal:DEBUG ``` --- ## Changelog ### Version 19.0.1.0.0 (Initial Release) **New Features:** - Authorizer Portal with case management - Sales Rep Portal with assessment forms - Wheelchair Assessment model with 50+ fields - Digital signature capture (Pages 11 & 12) - Document management with revision tracking - Real-time search functionality - Email notifications for key events - Portal access management from partner form **Technical:** - Compatible with Odoo Enterprise v19 - Integrates with fusion_claims module - Mobile-responsive portal design - Touch-friendly signature pad - AJAX-powered search **Bug Fixes:** - Fixed `in_portal` field error in Odoo 19 portal wizard - Fixed `tree` to `list` view type for Odoo 19 - Fixed `category_id` error in security groups - Fixed `type='json'` deprecation warning --- ## File Structure ``` fusion_authorizer_portal/ ├── __init__.py ├── __manifest__.py ├── README.md ├── controllers/ │ ├── __init__.py │ ├── portal_main.py # Authorizer & Sales Rep portal routes │ └── portal_assessment.py # Assessment routes ├── data/ │ ├── mail_template_data.xml # Email templates & sequences │ └── portal_menu_data.xml # Portal menu items ├── models/ │ ├── __init__.py │ ├── adp_document.py # Document management model │ ├── assessment.py # Assessment model │ ├── authorizer_comment.py # Comments model │ ├── res_partner.py # Partner extensions │ └── sale_order.py # Sale Order extensions ├── security/ │ ├── ir.model.access.csv # Access rights │ └── portal_security.xml # Groups & record rules ├── static/ │ └── src/ │ ├── css/ │ │ └── portal_style.css # Portal styling │ └── js/ │ ├── assessment_form.js # Form enhancements │ ├── portal_search.js # Real-time search │ └── signature_pad.js # Signature capture └── views/ ├── assessment_views.xml # Assessment backend views ├── portal_templates.xml # Portal QWeb templates ├── res_partner_views.xml # Partner form extensions └── sale_order_views.xml # Sale Order extensions ``` --- ## Support For support or feature requests, contact: - **Email:** support@fusionclaims.com - **Website:** https://fusionclaims.com --- *Last Updated: January 2026*