Files
Odoo-Modules/fusion_inventory/models/res_config_settings.py
gsinghpal e9cf75ee48 changes
2026-03-14 12:04:20 -04:00

113 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
from odoo import models, fields, api
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
fi_case_conversion = fields.Selection([
('none', 'No Conversion'),
('upper', 'UPPERCASE'),
('sentence', 'Sentence case'),
('capitalized', 'Capitalized Case'),
('lower', 'lowercase'),
], string='Product Name Case',
config_parameter='fusion_inventory.case_conversion',
default='none',
help='Globally convert all product names to the selected case. '
'Overrides individual product settings and applies to new products.')
fi_auto_update_cost = fields.Boolean(
string='Auto-Update Cost from Vendor Bills',
config_parameter='fusion_inventory.auto_update_cost',
default=True,
help='Automatically update product cost when a vendor bill is confirmed. '
'Uses the latest bill line price (skips zero-price lines).')
fi_default_margin = fields.Float(
string='Default Margin (%)',
config_parameter='fusion_inventory.default_margin',
default=0,
help='Default margin percentage applied to new products.')
fi_booking_hold_hours = fields.Integer(
string='Booking Hold Duration (hours)',
config_parameter='fusion_inventory.booking_hold_hours',
default=24,
help='How many hours a product booking holds before auto-expiring.')
fi_openai_api_key = fields.Char(
string='OpenAI API Key',
config_parameter='fusion_inventory.openai_api_key',
help='API key for OpenAI features (discrepancy analysis, notes parsing). '
'Falls back to Fusion Digitize key if empty.')
@api.model
def get_fi_openai_key(self):
"""Return the effective OpenAI API key, falling back to Fusion Digitize."""
key = self.env['ir.config_parameter'].sudo().get_param(
'fusion_inventory.openai_api_key', ''
)
if not key:
key = self.env['ir.config_parameter'].sudo().get_param(
'fusion_digitize.openai_api_key', ''
)
return key or ''
def action_sync_all_costs_from_bills(self):
"""Pull every product's cost from its latest posted vendor bill line."""
products = self.env['product.template'].sudo().search([])
products._sync_cost_from_latest_bill()
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Cost Sync Complete',
'message': f'Checked {len(products)} products against vendor bill history.',
'type': 'success',
'sticky': False,
},
}
def action_apply_case_conversion_all(self):
"""Apply the global case conversion to all existing products."""
mode = self.fi_case_conversion
if not mode or mode == 'none':
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'No Conversion Selected',
'message': 'Select a case conversion option first.',
'type': 'warning',
'sticky': False,
},
}
products = self.env['product.template'].search([])
count = 0
for product in products:
converted = self.env['product.template']._apply_case_conversion(
product.name, mode
)
if converted and converted != product.name:
product.with_context(_fi_converting_case=True).write({
'name': converted,
'x_fi_case_conversion': mode,
})
count += 1
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Case Conversion Applied',
'message': f'{count} product names converted to {mode}.',
'type': 'success',
'sticky': False,
},
}