Initial commit
This commit is contained in:
126
fusion_claims/models/fusion_central_config.py
Normal file
126
fusion_claims/models/fusion_central_config.py
Normal file
@@ -0,0 +1,126 @@
|
||||
# -*- 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, api, _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FusionCentralConfig(models.TransientModel):
|
||||
_name = 'fusion_claims.config'
|
||||
_description = 'Fusion Central Configuration Manager'
|
||||
|
||||
# =========================================================================
|
||||
# ACTION METHODS
|
||||
# =========================================================================
|
||||
|
||||
def action_detect_existing_fields(self):
|
||||
"""Detect existing custom x_* fields and map them."""
|
||||
ICP = self.env['ir.config_parameter'].sudo()
|
||||
IrModelFields = self.env['ir.model.fields'].sudo()
|
||||
detected = []
|
||||
detected_details = []
|
||||
|
||||
# Search for all custom fields on relevant models
|
||||
models_to_search = ['sale.order', 'sale.order.line', 'account.move', 'account.move.line', 'product.template']
|
||||
|
||||
# Find all custom x_* fields
|
||||
all_custom_fields = IrModelFields.search([
|
||||
('model', 'in', models_to_search),
|
||||
('name', '=like', 'x_%'),
|
||||
('state', '=', 'manual'),
|
||||
])
|
||||
|
||||
_logger.debug("Found %d custom fields across models", len(all_custom_fields))
|
||||
|
||||
# Field patterns to detect (model, keywords, param_key, display_name)
|
||||
# Keywords are checked if they appear anywhere in the field name
|
||||
# NOTE: param_key must match the config_parameter in res_config_settings.py
|
||||
field_mappings = [
|
||||
# Sale Order header fields
|
||||
('sale.order', ['sale_type', 'saletype', 'type_of_sale'], 'fusion_claims.field_sale_type', 'Sale Type'),
|
||||
('sale.order', ['client_type', 'clienttype', 'customer_type'], 'fusion_claims.field_so_client_type', 'SO Client Type'),
|
||||
('sale.order', ['authorizer', 'authorized', 'approver'], 'fusion_claims.field_so_authorizer', 'SO Authorizer'),
|
||||
('sale.order', ['claim_number', 'claimnumber', 'claim_no', 'claim_num'], 'fusion_claims.field_so_claim_number', 'SO Claim Number'),
|
||||
('sale.order', ['client_ref_1', 'clientref1', 'reference_1'], 'fusion_claims.field_so_client_ref_1', 'SO Client Ref 1'),
|
||||
('sale.order', ['client_ref_2', 'clientref2', 'reference_2'], 'fusion_claims.field_so_client_ref_2', 'SO Client Ref 2'),
|
||||
('sale.order', ['delivery_date', 'deliverydate', 'adp_delivery'], 'fusion_claims.field_so_delivery_date', 'SO Delivery Date'),
|
||||
('sale.order', ['service_start', 'servicestart'], 'fusion_claims.field_so_service_start', 'SO Service Start'),
|
||||
('sale.order', ['service_end', 'serviceend'], 'fusion_claims.field_so_service_end', 'SO Service End'),
|
||||
('sale.order', ['adp_status', 'adpstatus'], 'fusion_claims.field_so_adp_status', 'SO ADP Status'),
|
||||
# Sale Order line fields
|
||||
('sale.order.line', ['serial', 'sn', 's_n'], 'fusion_claims.field_sol_serial', 'SO Line Serial'),
|
||||
('sale.order.line', ['placement', 'device_placement'], 'fusion_claims.field_sol_placement', 'SO Line Placement'),
|
||||
# Invoice header fields
|
||||
('account.move', ['invoice_type', 'invoicetype', 'inv_type', 'type_of_invoice'], 'fusion_claims.field_invoice_type', 'Invoice Type'),
|
||||
('account.move', ['client_type', 'clienttype', 'customer_type'], 'fusion_claims.field_inv_client_type', 'Invoice Client Type'),
|
||||
('account.move', ['authorizer', 'authorized', 'approver'], 'fusion_claims.field_inv_authorizer', 'Invoice Authorizer'),
|
||||
('account.move', ['claim_number', 'claimnumber', 'claim_no'], 'fusion_claims.field_inv_claim_number', 'Invoice Claim Number'),
|
||||
('account.move', ['client_ref_1', 'clientref1', 'reference_1'], 'fusion_claims.field_inv_client_ref_1', 'Invoice Client Ref 1'),
|
||||
('account.move', ['client_ref_2', 'clientref2', 'reference_2'], 'fusion_claims.field_inv_client_ref_2', 'Invoice Client Ref 2'),
|
||||
('account.move', ['delivery_date', 'deliverydate', 'adp_delivery'], 'fusion_claims.field_inv_delivery_date', 'Invoice Delivery Date'),
|
||||
('account.move', ['service_start', 'servicestart'], 'fusion_claims.field_inv_service_start', 'Invoice Service Start'),
|
||||
('account.move', ['service_end', 'serviceend'], 'fusion_claims.field_inv_service_end', 'Invoice Service End'),
|
||||
# Invoice line fields
|
||||
('account.move.line', ['serial', 'sn', 's_n'], 'fusion_claims.field_aml_serial', 'Invoice Line Serial'),
|
||||
('account.move.line', ['placement', 'device_placement'], 'fusion_claims.field_aml_placement', 'Invoice Line Placement'),
|
||||
# Product fields
|
||||
('product.template', ['adp_device', 'adp_code', 'adp_sku', 'device_code', 'sku'], 'fusion_claims.field_product_code', 'Product ADP Code'),
|
||||
]
|
||||
|
||||
for model, keywords, param_key, display_name in field_mappings:
|
||||
# Find fields on this model that contain any of the keywords
|
||||
model_fields = all_custom_fields.filtered(lambda f: f.model == model)
|
||||
|
||||
model_fields_sorted = sorted(model_fields, key=lambda f: f.name)
|
||||
|
||||
matched_field = None
|
||||
for field in model_fields_sorted:
|
||||
field_name_lower = field.name.lower()
|
||||
for keyword in keywords:
|
||||
if keyword in field_name_lower:
|
||||
# Skip our own x_fc_* fields - we want to find other custom fields
|
||||
if field.name.startswith('x_fc_'):
|
||||
continue
|
||||
matched_field = field
|
||||
break
|
||||
if matched_field:
|
||||
break
|
||||
|
||||
if matched_field:
|
||||
ICP.set_param(param_key, matched_field.name)
|
||||
detected.append(matched_field.name)
|
||||
detected_details.append(f"• {display_name}: {matched_field.name} ({model})")
|
||||
_logger.debug("Mapped %s -> %s on %s", param_key, matched_field.name, model)
|
||||
|
||||
# Also list any unmapped custom fields for reference
|
||||
unmapped = []
|
||||
for field in all_custom_fields:
|
||||
if field.name not in detected:
|
||||
unmapped.append(f"{field.model}.{field.name}")
|
||||
|
||||
if detected_details:
|
||||
message = _("Detected and mapped %d fields:\n%s") % (len(detected), "\n".join(detected_details))
|
||||
if unmapped:
|
||||
message += _("\n\nOther custom fields found (not mapped):\n• ") + "\n• ".join(unmapped[:10])
|
||||
if len(unmapped) > 10:
|
||||
message += f"\n... and {len(unmapped) - 10} more"
|
||||
message += _("\n\n⚠️ IMPORTANT: Save settings and reload page to see changes.")
|
||||
else:
|
||||
message = _("No matching fields found.\n\nCustom fields found:\n• ") + "\n• ".join(unmapped[:15]) if unmapped else _("No custom fields found on relevant models.")
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _("Field Detection Complete"),
|
||||
'message': message,
|
||||
'type': 'success' if detected else 'warning',
|
||||
'sticky': True,
|
||||
}
|
||||
}
|
||||
|
||||
# (Migration and field protection methods removed)
|
||||
Reference in New Issue
Block a user