- fusion_claims: separated field service logic, updated controllers/views - fusion_tasks: updated task views and map integration - fusion_authorizer_portal: added page 11 signing, schedule booking, migrations - fusion_shipping: new standalone shipping module (Canada Post, FedEx, DHL, Purolator) - fusion_ltc_management: new standalone LTC management module
644 lines
27 KiB
Python
644 lines
27 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2024-2025 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
# Part of the Fusion Claim Assistant product family.
|
|
|
|
import logging
|
|
|
|
from odoo import models, fields, api
|
|
from odoo.exceptions import ValidationError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ResConfigSettings(models.TransientModel):
|
|
_inherit = 'res.config.settings'
|
|
|
|
# =========================================================================
|
|
# COMPANY SETTINGS (Related to res.company)
|
|
# =========================================================================
|
|
|
|
fc_store_address_1 = fields.Char(
|
|
related='company_id.x_fc_store_address_1',
|
|
readonly=False,
|
|
string='Store Address Line 1',
|
|
)
|
|
fc_store_address_2 = fields.Char(
|
|
related='company_id.x_fc_store_address_2',
|
|
readonly=False,
|
|
string='Store Address Line 2',
|
|
)
|
|
fc_company_tagline = fields.Char(
|
|
related='company_id.x_fc_company_tagline',
|
|
readonly=False,
|
|
string='Company Tagline',
|
|
)
|
|
fc_etransfer_email = fields.Char(
|
|
related='company_id.x_fc_etransfer_email',
|
|
readonly=False,
|
|
string='E-Transfer Email',
|
|
)
|
|
fc_cheque_payable_to = fields.Char(
|
|
related='company_id.x_fc_cheque_payable_to',
|
|
readonly=False,
|
|
string='Cheque Payable To',
|
|
)
|
|
fc_payment_terms_html = fields.Html(
|
|
related='company_id.x_fc_payment_terms_html',
|
|
readonly=False,
|
|
string='Payment Terms',
|
|
)
|
|
fc_include_refund_page = fields.Boolean(
|
|
related='company_id.x_fc_include_refund_page',
|
|
readonly=False,
|
|
string='Include Refund Policy Page',
|
|
)
|
|
fc_refund_policy_html = fields.Html(
|
|
related='company_id.x_fc_refund_policy_html',
|
|
readonly=False,
|
|
string='Refund Policy',
|
|
)
|
|
|
|
# =========================================================================
|
|
# ADP BILLING SETTINGS
|
|
# =========================================================================
|
|
|
|
fc_vendor_code = fields.Char(
|
|
string='ADP Vendor Code',
|
|
config_parameter='fusion_claims.vendor_code',
|
|
help='Your ADP vendor/location code for claim submissions',
|
|
)
|
|
|
|
# =========================================================================
|
|
# FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_sale_type = fields.Char(
|
|
string='Sale Type Field',
|
|
config_parameter='fusion_claims.field_sale_type',
|
|
help='Field name for sale type on sale.order',
|
|
)
|
|
fc_field_so_client_type = fields.Char(
|
|
string='SO Client Type Field',
|
|
config_parameter='fusion_claims.field_so_client_type',
|
|
help='Field name for client type on sale.order',
|
|
)
|
|
fc_field_so_authorizer = fields.Char(
|
|
string='SO Authorizer Field',
|
|
config_parameter='fusion_claims.field_so_authorizer',
|
|
help='Field name for authorizer on sale.order',
|
|
)
|
|
fc_field_invoice_type = fields.Char(
|
|
string='Invoice Type Field',
|
|
config_parameter='fusion_claims.field_invoice_type',
|
|
help='Field name for invoice type on account.move',
|
|
)
|
|
fc_field_inv_client_type = fields.Char(
|
|
string='Invoice Client Type Field',
|
|
config_parameter='fusion_claims.field_inv_client_type',
|
|
help='Field name for client type on account.move',
|
|
)
|
|
fc_field_inv_authorizer = fields.Char(
|
|
string='Invoice Authorizer Field',
|
|
config_parameter='fusion_claims.field_inv_authorizer',
|
|
help='Field name for authorizer on account.move',
|
|
)
|
|
fc_field_product_code = fields.Char(
|
|
string='Product ADP Code Field',
|
|
config_parameter='fusion_claims.field_product_code',
|
|
help='Field name for ADP device code on product.template',
|
|
)
|
|
fc_field_sol_serial = fields.Char(
|
|
string='SO Line Serial Field',
|
|
config_parameter='fusion_claims.field_sol_serial',
|
|
help='Field name for serial number on sale.order.line',
|
|
)
|
|
fc_field_aml_serial = fields.Char(
|
|
string='Invoice Line Serial Field',
|
|
config_parameter='fusion_claims.field_aml_serial',
|
|
help='Field name for serial number on account.move.line',
|
|
)
|
|
|
|
# =========================================================================
|
|
# ADDITIONAL SALE ORDER FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_so_claim_number = fields.Char(
|
|
string='SO Claim Number Field',
|
|
config_parameter='fusion_claims.field_so_claim_number',
|
|
help='Field name for claim number on sale.order',
|
|
)
|
|
fc_field_so_client_ref_1 = fields.Char(
|
|
string='SO Client Ref 1 Field',
|
|
config_parameter='fusion_claims.field_so_client_ref_1',
|
|
help='Field name for client reference 1 on sale.order',
|
|
)
|
|
fc_field_so_client_ref_2 = fields.Char(
|
|
string='SO Client Ref 2 Field',
|
|
config_parameter='fusion_claims.field_so_client_ref_2',
|
|
help='Field name for client reference 2 on sale.order',
|
|
)
|
|
fc_field_so_delivery_date = fields.Char(
|
|
string='SO Delivery Date Field',
|
|
config_parameter='fusion_claims.field_so_delivery_date',
|
|
help='Field name for ADP delivery date on sale.order',
|
|
)
|
|
fc_field_so_adp_status = fields.Char(
|
|
string='SO ADP Status Field',
|
|
config_parameter='fusion_claims.field_so_adp_status',
|
|
help='Field name for ADP status on sale.order',
|
|
)
|
|
fc_field_so_service_start = fields.Char(
|
|
string='SO Service Start Date Field',
|
|
config_parameter='fusion_claims.field_so_service_start',
|
|
help='Field name for service start date on sale.order',
|
|
)
|
|
fc_field_so_service_end = fields.Char(
|
|
string='SO Service End Date Field',
|
|
config_parameter='fusion_claims.field_so_service_end',
|
|
help='Field name for service end date on sale.order',
|
|
)
|
|
|
|
# =========================================================================
|
|
# ADDITIONAL INVOICE FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_inv_claim_number = fields.Char(
|
|
string='Invoice Claim Number Field',
|
|
config_parameter='fusion_claims.field_inv_claim_number',
|
|
help='Field name for claim number on account.move',
|
|
)
|
|
fc_field_inv_client_ref_1 = fields.Char(
|
|
string='Invoice Client Ref 1 Field',
|
|
config_parameter='fusion_claims.field_inv_client_ref_1',
|
|
help='Field name for client reference 1 on account.move',
|
|
)
|
|
fc_field_inv_client_ref_2 = fields.Char(
|
|
string='Invoice Client Ref 2 Field',
|
|
config_parameter='fusion_claims.field_inv_client_ref_2',
|
|
help='Field name for client reference 2 on account.move',
|
|
)
|
|
fc_field_inv_delivery_date = fields.Char(
|
|
string='Invoice Delivery Date Field',
|
|
config_parameter='fusion_claims.field_inv_delivery_date',
|
|
help='Field name for ADP delivery date on account.move',
|
|
)
|
|
fc_field_inv_service_start = fields.Char(
|
|
string='Invoice Service Start Date Field',
|
|
config_parameter='fusion_claims.field_inv_service_start',
|
|
help='Field name for service start date on account.move',
|
|
)
|
|
fc_field_inv_service_end = fields.Char(
|
|
string='Invoice Service End Date Field',
|
|
config_parameter='fusion_claims.field_inv_service_end',
|
|
help='Field name for service end date on account.move',
|
|
)
|
|
|
|
# =========================================================================
|
|
# SALE ORDER LINE FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_sol_placement = fields.Char(
|
|
string='SO Line Placement Field',
|
|
config_parameter='fusion_claims.field_sol_placement',
|
|
help='Field name for device placement on sale.order.line',
|
|
)
|
|
|
|
# =========================================================================
|
|
# INVOICE LINE FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_aml_placement = fields.Char(
|
|
string='Invoice Line Placement Field',
|
|
config_parameter='fusion_claims.field_aml_placement',
|
|
help='Field name for device placement on account.move.line',
|
|
)
|
|
|
|
# =========================================================================
|
|
# PRODUCT FIELD MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_product_adp_price = fields.Char(
|
|
string='Product ADP Price Field',
|
|
config_parameter='fusion_claims.field_product_adp_price',
|
|
help='Field name for ADP price on product.template',
|
|
)
|
|
|
|
# =========================================================================
|
|
# HEADER-LEVEL SERIAL NUMBER MAPPINGS
|
|
# =========================================================================
|
|
|
|
fc_field_so_primary_serial = fields.Char(
|
|
string='SO Primary Serial Field',
|
|
config_parameter='fusion_claims.field_so_primary_serial',
|
|
help='Field name for primary serial number on sale.order (header level)',
|
|
)
|
|
fc_field_inv_primary_serial = fields.Char(
|
|
string='Invoice Primary Serial Field',
|
|
config_parameter='fusion_claims.field_inv_primary_serial',
|
|
help='Field name for primary serial number on account.move (header level)',
|
|
)
|
|
|
|
# =========================================================================
|
|
# ADP POSTING SCHEDULE SETTINGS
|
|
# =========================================================================
|
|
|
|
fc_adp_posting_base_date = fields.Char(
|
|
string='ADP Posting Base Date',
|
|
config_parameter='fusion_claims.adp_posting_base_date',
|
|
help='Reference date for calculating bi-weekly posting schedule (a known posting day). Format: YYYY-MM-DD',
|
|
)
|
|
fc_adp_posting_frequency_days = fields.Integer(
|
|
string='Posting Frequency (Days)',
|
|
config_parameter='fusion_claims.adp_posting_frequency_days',
|
|
help='Number of days between ADP posting cycles (typically 14 days)',
|
|
)
|
|
fc_adp_billing_reminder_user_id = fields.Many2one(
|
|
'res.users',
|
|
string='Billing Deadline Reminder Person',
|
|
# NOTE: stored manually via get_values/set_values (not config_parameter)
|
|
# because Many2one + config_parameter causes double-write conflicts
|
|
help='Person to remind on Monday to complete ADP billing by Wednesday 6 PM',
|
|
)
|
|
fc_adp_correction_reminder_user_ids = fields.Many2many(
|
|
'res.users',
|
|
'fc_config_correction_reminder_users_rel',
|
|
'config_id',
|
|
'user_id',
|
|
string='Correction Alert Recipients',
|
|
help='People to notify when an ADP invoice needs correction/resubmission',
|
|
)
|
|
|
|
# =========================================================================
|
|
# EMAIL NOTIFICATION SETTINGS
|
|
# =========================================================================
|
|
|
|
fc_enable_email_notifications = fields.Boolean(
|
|
string='Enable Automated Email Notifications',
|
|
config_parameter='fusion_claims.enable_email_notifications',
|
|
help='Enable/disable automated email notifications for ADP workflow events',
|
|
)
|
|
fc_office_notification_ids = fields.Many2many(
|
|
related='company_id.x_fc_office_notification_ids',
|
|
readonly=False,
|
|
string='Office Notification Recipients',
|
|
)
|
|
fc_application_reminder_days = fields.Integer(
|
|
string='First Reminder Days',
|
|
config_parameter='fusion_claims.application_reminder_days',
|
|
help='Number of days after assessment completion to send first application reminder to therapist',
|
|
)
|
|
fc_application_reminder_2_days = fields.Integer(
|
|
string='Second Reminder Days (After First)',
|
|
config_parameter='fusion_claims.application_reminder_2_days',
|
|
help='Number of days after first reminder to send second application reminder to therapist',
|
|
)
|
|
|
|
# =========================================================================
|
|
# WORKFLOW LOCK SETTINGS
|
|
# =========================================================================
|
|
|
|
fc_allow_sale_type_override = fields.Boolean(
|
|
string='Allow Sale Type Override',
|
|
config_parameter='fusion_claims.allow_sale_type_override',
|
|
help='If enabled, allows changing Sale Type even after application is submitted (for cases where additional benefits are discovered)',
|
|
)
|
|
|
|
fc_allow_document_lock_override = fields.Boolean(
|
|
string='Allow Document Lock Override',
|
|
config_parameter='fusion_claims.allow_document_lock_override',
|
|
help='When enabled, users in the "Document Lock Override" group can edit locked documents on old cases. '
|
|
'Disable this once all legacy cases have been processed to enforce strict workflow.',
|
|
)
|
|
|
|
fc_designated_vendor_signer = fields.Many2one(
|
|
'res.users',
|
|
string='Designated Vendor Signer',
|
|
help='The user who signs Page 12 on behalf of the company',
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# AI CLIENT INTELLIGENCE
|
|
# ------------------------------------------------------------------
|
|
fc_ai_api_key = fields.Char(
|
|
string='AI API Key',
|
|
config_parameter='fusion_claims.ai_api_key',
|
|
help='OpenAI API key for Client Intelligence chat',
|
|
)
|
|
fc_ai_model = fields.Selection([
|
|
('gpt-4o-mini', 'GPT-4o Mini (Fast, Lower Cost)'),
|
|
('gpt-4o', 'GPT-4o (Best Quality)'),
|
|
('gpt-4.1-mini', 'GPT-4.1 Mini'),
|
|
('gpt-4.1', 'GPT-4.1'),
|
|
], string='AI Model',
|
|
config_parameter='fusion_claims.ai_model',
|
|
)
|
|
fc_auto_parse_xml = fields.Boolean(
|
|
string='Auto-Parse XML Files',
|
|
config_parameter='fusion_claims.auto_parse_xml',
|
|
help='Automatically parse ADP XML files when uploaded and create/update client profiles',
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# TWILIO SMS SETTINGS
|
|
# ------------------------------------------------------------------
|
|
fc_twilio_enabled = fields.Boolean(
|
|
string='Enable Twilio SMS',
|
|
config_parameter='fusion_claims.twilio_enabled',
|
|
help='Enable SMS notifications via Twilio for assessment bookings and key status updates',
|
|
)
|
|
fc_twilio_account_sid = fields.Char(
|
|
string='Twilio Account SID',
|
|
config_parameter='fusion_claims.twilio_account_sid',
|
|
groups='fusion_claims.group_fusion_claims_manager',
|
|
)
|
|
fc_twilio_auth_token = fields.Char(
|
|
string='Twilio Auth Token',
|
|
config_parameter='fusion_claims.twilio_auth_token',
|
|
groups='fusion_claims.group_fusion_claims_manager',
|
|
)
|
|
fc_twilio_phone_number = fields.Char(
|
|
string='Twilio Phone Number',
|
|
config_parameter='fusion_claims.twilio_phone_number',
|
|
help='Your Twilio phone number for sending SMS (e.g. +1234567890)',
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# MARCH OF DIMES SETTINGS
|
|
# ------------------------------------------------------------------
|
|
fc_mod_default_email = fields.Char(
|
|
string='MOD Default Email',
|
|
config_parameter='fusion_claims.mod_default_email',
|
|
help='Default email for sending quotations and documents to March of Dimes (e.g. hvmp@marchofdimes.ca)',
|
|
)
|
|
fc_mod_vendor_code = fields.Char(
|
|
string='March of Dimes Vendor Code',
|
|
config_parameter='fusion_claims.mod_vendor_code',
|
|
help='Your vendor code assigned by March of Dimes (e.g. TRD0001234)',
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# MOD FOLLOW-UP SETTINGS
|
|
# ------------------------------------------------------------------
|
|
fc_mod_followup_interval_days = fields.Integer(
|
|
string='Follow-up Interval (Days)',
|
|
config_parameter='fusion_claims.mod_followup_interval_days',
|
|
help='Number of days between follow-up reminders for MOD cases awaiting funding (default: 14)',
|
|
)
|
|
fc_mod_followup_escalation_days = fields.Integer(
|
|
string='Escalation Delay (Days)',
|
|
config_parameter='fusion_claims.mod_followup_escalation_days',
|
|
help='Days after a follow-up activity is due before auto-sending email to client (default: 3)',
|
|
)
|
|
|
|
# ------------------------------------------------------------------
|
|
# ODSP CONFIGURATION
|
|
# ------------------------------------------------------------------
|
|
fc_sa_mobility_email = fields.Char(
|
|
string='SA Mobility Email',
|
|
config_parameter='fusion_claims.sa_mobility_email',
|
|
help='Email address for SA Mobility submissions (default: samobility@ontario.ca)',
|
|
)
|
|
fc_sa_mobility_phone = fields.Char(
|
|
string='SA Mobility Phone',
|
|
config_parameter='fusion_claims.sa_mobility_phone',
|
|
help='SA Mobility phone number (default: 1-888-222-5099)',
|
|
)
|
|
fc_odsp_default_office_id = fields.Many2one(
|
|
'res.partner',
|
|
string='Default ODSP Office',
|
|
domain="[('x_fc_contact_type', '=', 'odsp_office')]",
|
|
help='Default ODSP office contact for new ODSP cases',
|
|
)
|
|
|
|
# =========================================================================
|
|
# PORTAL BRANDING
|
|
# =========================================================================
|
|
|
|
fc_portal_gradient_preset = fields.Selection([
|
|
('green_teal', 'Green to Teal (Default)'),
|
|
('blue_purple', 'Blue to Purple'),
|
|
('orange_red', 'Sunset Orange'),
|
|
('dark_slate', 'Dark Slate'),
|
|
('custom', 'Custom'),
|
|
],
|
|
string='Portal Gradient Theme',
|
|
config_parameter='fusion_claims.portal_gradient_preset',
|
|
default='green_teal',
|
|
)
|
|
fc_portal_gradient_start = fields.Char(
|
|
string='Gradient Start Color',
|
|
config_parameter='fusion_claims.portal_gradient_start',
|
|
default='#5ba848',
|
|
)
|
|
fc_portal_gradient_mid = fields.Char(
|
|
string='Gradient Mid Color',
|
|
config_parameter='fusion_claims.portal_gradient_mid',
|
|
default='#3a8fb7',
|
|
)
|
|
fc_portal_gradient_end = fields.Char(
|
|
string='Gradient End Color',
|
|
config_parameter='fusion_claims.portal_gradient_end',
|
|
default='#2e7aad',
|
|
)
|
|
fc_portal_gradient_preview = fields.Html(
|
|
string='Gradient Preview',
|
|
compute='_compute_portal_gradient_preview',
|
|
sanitize=False,
|
|
)
|
|
|
|
@api.onchange('fc_portal_gradient_preset')
|
|
def _onchange_portal_gradient_preset(self):
|
|
preset = self.fc_portal_gradient_preset
|
|
if preset and preset != 'custom' and preset in self.GRADIENT_PRESETS:
|
|
start, mid, end = self.GRADIENT_PRESETS[preset]
|
|
self.fc_portal_gradient_start = start
|
|
self.fc_portal_gradient_mid = mid
|
|
self.fc_portal_gradient_end = end
|
|
|
|
@api.depends(
|
|
'fc_portal_gradient_preset',
|
|
'fc_portal_gradient_start',
|
|
'fc_portal_gradient_mid',
|
|
'fc_portal_gradient_end',
|
|
)
|
|
def _compute_portal_gradient_preview(self):
|
|
for rec in self:
|
|
start = rec.fc_portal_gradient_start or '#5ba848'
|
|
mid = rec.fc_portal_gradient_mid or '#3a8fb7'
|
|
end = rec.fc_portal_gradient_end or '#2e7aad'
|
|
gradient = 'linear-gradient(135deg, %s 0%%, %s 60%%, %s 100%%)' % (start, mid, end)
|
|
rec.fc_portal_gradient_preview = (
|
|
'<div style="background: %s; border-radius: 12px; padding: 24px; min-height: 80px;">'
|
|
'<div style="display: flex; align-items: center; color: #fff;">'
|
|
'<div style="flex: 1;">'
|
|
'<h5 style="color: #fff; margin-bottom: 4px;">'
|
|
'<i class="fa fa-hand-peace-o" style="margin-right: 8px;"></i>'
|
|
'Welcome back, Preview User!</h5>'
|
|
'<small style="color: rgba(255,255,255,0.9);">'
|
|
'This is how your portal dashboard header will look.</small>'
|
|
'</div>'
|
|
'<div style="text-align: right;">'
|
|
'<div style="background: rgba(255,255,255,0.2); border-radius: 8px; padding: 8px 12px;">'
|
|
'<small style="display: block; color: rgba(255,255,255,0.8);">Preview</small>'
|
|
'<strong style="color: #fff;">Live</strong>'
|
|
'</div></div></div></div>'
|
|
) % gradient
|
|
|
|
@api.model
|
|
def get_values(self):
|
|
res = super().get_values()
|
|
ICP = self.env['ir.config_parameter'].sudo()
|
|
|
|
# Get billing reminder user
|
|
billing_user_id = ICP.get_param('fusion_claims.adp_billing_reminder_user_id', False)
|
|
if billing_user_id:
|
|
try:
|
|
res['fc_adp_billing_reminder_user_id'] = int(billing_user_id)
|
|
except (ValueError, TypeError):
|
|
res['fc_adp_billing_reminder_user_id'] = False
|
|
|
|
# Get correction reminder users (stored as comma-separated IDs)
|
|
correction_user_ids = ICP.get_param('fusion_claims.adp_correction_reminder_user_ids', '')
|
|
if correction_user_ids:
|
|
try:
|
|
user_ids = [int(x.strip()) for x in correction_user_ids.split(',') if x.strip()]
|
|
res['fc_adp_correction_reminder_user_ids'] = [(6, 0, user_ids)]
|
|
except (ValueError, TypeError):
|
|
res['fc_adp_correction_reminder_user_ids'] = [(6, 0, [])]
|
|
|
|
# Get designated vendor signer
|
|
vendor_signer_id = ICP.get_param('fusion_claims.designated_vendor_signer', False)
|
|
if vendor_signer_id:
|
|
try:
|
|
res['fc_designated_vendor_signer'] = int(vendor_signer_id)
|
|
except (ValueError, TypeError):
|
|
res['fc_designated_vendor_signer'] = False
|
|
|
|
# Get default ODSP office
|
|
odsp_office_id = ICP.get_param('fusion_claims.odsp_default_office_id', False)
|
|
if odsp_office_id:
|
|
try:
|
|
res['fc_odsp_default_office_id'] = int(odsp_office_id)
|
|
except (ValueError, TypeError):
|
|
res['fc_odsp_default_office_id'] = False
|
|
|
|
return res
|
|
|
|
def set_values(self):
|
|
ICP = self.env['ir.config_parameter'].sudo()
|
|
|
|
# --- Protect sensitive config_parameter fields from accidental blanking ---
|
|
# These are keys where a blank/default value should NOT overwrite
|
|
# an existing non-empty value (e.g. API keys, user-customized settings).
|
|
_protected_keys = [
|
|
'fusion_claims.ai_api_key',
|
|
'fusion_claims.vendor_code',
|
|
'fusion_claims.ai_model',
|
|
'fusion_claims.adp_posting_base_date',
|
|
'fusion_claims.application_reminder_days',
|
|
'fusion_claims.application_reminder_2_days',
|
|
]
|
|
# Snapshot existing values BEFORE super().set_values() runs
|
|
_existing = {}
|
|
for key in _protected_keys:
|
|
val = ICP.get_param(key, '')
|
|
if val:
|
|
_existing[key] = val
|
|
|
|
super().set_values()
|
|
|
|
# Restore any protected values that were blanked by the save
|
|
for key, old_val in _existing.items():
|
|
new_val = ICP.get_param(key, '')
|
|
if not new_val and old_val:
|
|
ICP.set_param(key, old_val)
|
|
_logger.warning(
|
|
"Settings protection: restored %s (was blanked during save)", key
|
|
)
|
|
|
|
# Store billing reminder user (Many2one - manual handling)
|
|
if self.fc_adp_billing_reminder_user_id:
|
|
ICP.set_param('fusion_claims.adp_billing_reminder_user_id',
|
|
str(self.fc_adp_billing_reminder_user_id.id))
|
|
# Only clear if explicitly set to empty AND there was no existing value
|
|
elif not ICP.get_param('fusion_claims.adp_billing_reminder_user_id', ''):
|
|
ICP.set_param('fusion_claims.adp_billing_reminder_user_id', '')
|
|
|
|
# Store correction reminder users as comma-separated IDs
|
|
if self.fc_adp_correction_reminder_user_ids:
|
|
user_ids = ','.join(str(u.id) for u in self.fc_adp_correction_reminder_user_ids)
|
|
ICP.set_param('fusion_claims.adp_correction_reminder_user_ids', user_ids)
|
|
# Only clear if explicitly empty AND no existing value
|
|
elif not ICP.get_param('fusion_claims.adp_correction_reminder_user_ids', ''):
|
|
ICP.set_param('fusion_claims.adp_correction_reminder_user_ids', '')
|
|
|
|
# Office notification recipients are stored via related field on res.company
|
|
# No need to store in ir.config_parameter
|
|
|
|
# Store designated vendor signer (Many2one - manual handling)
|
|
if self.fc_designated_vendor_signer:
|
|
ICP.set_param('fusion_claims.designated_vendor_signer',
|
|
str(self.fc_designated_vendor_signer.id))
|
|
elif not ICP.get_param('fusion_claims.designated_vendor_signer', ''):
|
|
ICP.set_param('fusion_claims.designated_vendor_signer', '')
|
|
|
|
# Store default ODSP office (Many2one - manual handling)
|
|
if self.fc_odsp_default_office_id:
|
|
ICP.set_param('fusion_claims.odsp_default_office_id',
|
|
str(self.fc_odsp_default_office_id.id))
|
|
elif not ICP.get_param('fusion_claims.odsp_default_office_id', ''):
|
|
ICP.set_param('fusion_claims.odsp_default_office_id', '')
|
|
|
|
# Apply gradient preset colors to ICP so the portal reads them
|
|
preset = self.fc_portal_gradient_preset
|
|
if preset and preset != 'custom' and preset in self.GRADIENT_PRESETS:
|
|
start, mid, end = self.GRADIENT_PRESETS[preset]
|
|
ICP.set_param('fusion_claims.portal_gradient_start', start)
|
|
ICP.set_param('fusion_claims.portal_gradient_mid', mid)
|
|
ICP.set_param('fusion_claims.portal_gradient_end', end)
|
|
|
|
# =========================================================================
|
|
# ACTION METHODS
|
|
# =========================================================================
|
|
|
|
def action_open_field_mapping_wizard(self):
|
|
"""Open the field mapping configuration wizard."""
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': 'Field Mapping Configuration',
|
|
'res_model': 'fusion_claims.field_mapping_config',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': {},
|
|
}
|
|
|
|
# -- Portal Gradient Presets -----------------------------------------------
|
|
|
|
GRADIENT_PRESETS = {
|
|
'green_teal': ('#5ba848', '#3a8fb7', '#2e7aad'),
|
|
'blue_purple': ('#4a90d9', '#7b68ee', '#6a5acd'),
|
|
'orange_red': ('#f7971e', '#e44d26', '#c0392b'),
|
|
'dark_slate': ('#2c3e50', '#4a6274', '#34495e'),
|
|
}
|
|
|
|
def _apply_gradient_preset(self, preset_key):
|
|
start, mid, end = self.GRADIENT_PRESETS[preset_key]
|
|
self.fc_portal_gradient_preset = preset_key
|
|
self.fc_portal_gradient_start = start
|
|
self.fc_portal_gradient_mid = mid
|
|
self.fc_portal_gradient_end = end
|
|
|
|
def action_set_gradient_green_teal(self):
|
|
self._apply_gradient_preset('green_teal')
|
|
|
|
def action_set_gradient_blue_purple(self):
|
|
self._apply_gradient_preset('blue_purple')
|
|
|
|
def action_set_gradient_orange_red(self):
|
|
self._apply_gradient_preset('orange_red')
|
|
|
|
def action_set_gradient_dark_slate(self):
|
|
self._apply_gradient_preset('dark_slate')
|
|
|