187 lines
6.9 KiB
Python
187 lines
6.9 KiB
Python
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class TranslationConfig(models.Model):
|
|
_name = 'otk.translation.config'
|
|
_description = 'Translation Configuration'
|
|
_rec_name = 'model_id'
|
|
|
|
model_id = fields.Many2one(
|
|
'ir.model',
|
|
string="Model",
|
|
required=True,
|
|
ondelete='cascade',
|
|
domain="[('transient', '=', False)]",
|
|
)
|
|
active = fields.Boolean(default=True)
|
|
has_translatable_fields = fields.Boolean(
|
|
compute='_compute_has_translatable_fields',
|
|
store=True,
|
|
)
|
|
translatable_field_ids = fields.Many2many(
|
|
'ir.model.fields',
|
|
string="Translatable Fields",
|
|
compute='_compute_has_translatable_fields',
|
|
store=True,
|
|
)
|
|
server_action_id = fields.Many2one(
|
|
'ir.actions.server',
|
|
string="Server Action",
|
|
readonly=True,
|
|
ondelete='set null',
|
|
)
|
|
|
|
@api.constrains('model_id')
|
|
def _check_unique_model_id(self):
|
|
for record in self:
|
|
if record.model_id:
|
|
if self.search([('model_id', '=', record.model_id.id), ('id', '!=', record.id)]):
|
|
raise ValidationError(_("A configuration already exists for this model."))
|
|
|
|
@api.depends('model_id')
|
|
def _compute_has_translatable_fields(self):
|
|
for record in self:
|
|
if record.model_id:
|
|
translatable_fields = self.env['ir.model.fields'].search([
|
|
('model_id', '=', record.model_id.id),
|
|
('translate', 'in', ['standard', 'html_translate', 'xml_translate']),
|
|
('related', '=', False),
|
|
('store', '=', True),
|
|
])
|
|
record.translatable_field_ids = translatable_fields
|
|
record.has_translatable_fields = bool(translatable_fields)
|
|
else:
|
|
record.translatable_field_ids = False
|
|
record.has_translatable_fields = False
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
records = super().create(vals_list)
|
|
records._create_server_actions()
|
|
return records
|
|
|
|
def write(self, vals):
|
|
model_changed = 'model_id' in vals
|
|
result = super().write(vals)
|
|
if 'active' in vals or model_changed:
|
|
self._update_server_actions(model_changed=model_changed)
|
|
return result
|
|
|
|
def unlink(self):
|
|
self.server_action_id.unlink()
|
|
return super().unlink()
|
|
|
|
def _create_server_actions(self):
|
|
"""Create server actions for each configuration."""
|
|
for record in self:
|
|
if not record.server_action_id and record.model_id:
|
|
record._create_single_server_action()
|
|
|
|
def _create_single_server_action(self):
|
|
"""Create a single server action for this configuration."""
|
|
self.ensure_one()
|
|
if not self.model_id:
|
|
return
|
|
|
|
action_name = _('Bulk translate')
|
|
server_action = self.env['ir.actions.server'].sudo().create({
|
|
'name': action_name,
|
|
'model_id': self.model_id.id,
|
|
'binding_model_id': self.model_id.id,
|
|
'binding_view_types': 'list',
|
|
'state': 'code',
|
|
'code': "action = env['otk.translation.config'].action_bulk_translate_generic()",
|
|
})
|
|
|
|
# Create external ID for the server action
|
|
action_xml_id = 'bulk_translate_config_action_for_' + self.model_id.model.replace('.', '_')
|
|
existing_data = self.env['ir.model.data'].sudo().search([
|
|
('module', '=', 'otoolkit_auto_translate_fields'),
|
|
('name', '=', action_xml_id),
|
|
])
|
|
if existing_data:
|
|
existing_data.unlink()
|
|
|
|
self.env['ir.model.data'].sudo().create({
|
|
'name': action_xml_id,
|
|
'model': 'ir.actions.server',
|
|
'module': 'otoolkit_auto_translate_fields',
|
|
'res_id': server_action.id,
|
|
'noupdate': True,
|
|
})
|
|
|
|
self.server_action_id = server_action
|
|
|
|
def _update_server_actions(self, model_changed=False):
|
|
"""Update server actions when configuration changes."""
|
|
for record in self:
|
|
# If model changed, delete old action and create new one
|
|
if model_changed and record.server_action_id:
|
|
record.server_action_id.unlink()
|
|
record.server_action_id = False
|
|
|
|
if record.active and not record.server_action_id:
|
|
record._create_single_server_action()
|
|
elif not record.active and record.server_action_id:
|
|
record.server_action_id.unlink()
|
|
record.server_action_id = False
|
|
|
|
@api.model
|
|
def action_bulk_translate_generic(self):
|
|
"""Generic action to open bulk translate wizard - called from server actions."""
|
|
active_model = self.env.context.get('active_model')
|
|
if not active_model:
|
|
return {'type': 'ir.actions.act_window_close'}
|
|
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Bulk translate'),
|
|
'res_model': 'otk.translation.bulk.translate',
|
|
'view_mode': 'form',
|
|
'view_id': self.env.ref('otoolkit_auto_translate_fields.view_bulk_translate_wizard_form').id,
|
|
'target': 'new',
|
|
}
|
|
|
|
def action_enable_all_translatable_models(self):
|
|
"""Enable bulk translation for all models that have translatable fields."""
|
|
# Find all models with translatable fields
|
|
translatable_models = self.env['ir.model.fields'].search([
|
|
('translate', 'in', ['standard', 'html_translate', 'xml_translate']),
|
|
('related', '=', False),
|
|
('store', '=', True),
|
|
]).mapped('model_id')
|
|
|
|
# Filter out transient models and already configured models
|
|
existing_model_ids = self.search([]).mapped('model_id.id')
|
|
models_to_add = translatable_models.filtered(
|
|
lambda m: m.id not in existing_model_ids and not m.transient
|
|
)
|
|
|
|
# Create configurations
|
|
vals_list = [{'model_id': model.id} for model in models_to_add]
|
|
created = self.create(vals_list)
|
|
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': _('Bulk Translation Enabled'),
|
|
'message': _('%d models have been configured for bulk translation.') % len(created),
|
|
'type': 'success',
|
|
'sticky': False,
|
|
}
|
|
}
|
|
|
|
def action_view_translatable_fields(self):
|
|
"""View the translatable fields for this model."""
|
|
self.ensure_one()
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': _('Translatable Fields'),
|
|
'res_model': 'ir.model.fields',
|
|
'view_mode': 'list,form',
|
|
'domain': [('id', 'in', self.translatable_field_ids.ids)],
|
|
'target': 'current',
|
|
}
|