Files
Odoo-Modules/fusion_authorizer_portal/README.md
2026-02-22 01:22:18 -05:00

722 lines
22 KiB
Markdown

# 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/<id>` | GET | user | Case detail view |
| `/my/authorizer/case/<id>/comment` | POST | user | Add comment to case |
| `/my/authorizer/case/<id>/upload` | POST | user | Upload document |
| `/my/authorizer/document/<id>/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/<id>` | 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/<id>` | GET | user | View/edit assessment |
| `/my/assessment/save` | POST | user | Save assessment data |
| `/my/assessment/<id>/signatures` | GET | user | Signature capture page |
| `/my/assessment/<id>/save_signature` | POST | user | Save signature (jsonrpc) |
| `/my/assessment/<id>/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 `<tree>` views to `<list>`.
**Solution:** Replace all `<tree>` tags with `<list>` in XML view definitions:
```xml
<!-- Old (Odoo 18 and earlier) -->
<tree>...</tree>
<!-- New (Odoo 19) -->
<list>...</list>
```
---
#### Error: `Invalid field 'category_id' in 'res.groups'`
**Cause:** Odoo 19 no longer supports `category_id` in `res.groups` XML definitions.
**Solution:** Remove the `<field name="category_id">` element from security group definitions:
```xml
<!-- Remove this line -->
<field name="category_id" ref="base.module_category_sales"/>
```
---
#### 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*