|
@ -30,6 +30,8 @@ class EmployeeDynamicFields(models.TransientModel): |
|
|
_description = 'Dynamic Fields' |
|
|
_description = 'Dynamic Fields' |
|
|
_inherit = 'ir.model.fields' |
|
|
_inherit = 'ir.model.fields' |
|
|
|
|
|
|
|
|
|
|
|
form_view_id = fields.Many2one('ir.ui.view', string="Form View ID") |
|
|
|
|
|
|
|
|
@api.model |
|
|
@api.model |
|
|
def get_possible_field_types(self): |
|
|
def get_possible_field_types(self): |
|
|
"""Return all available field types other than 'one2many' and 'reference' fields.""" |
|
|
"""Return all available field types other than 'one2many' and 'reference' fields.""" |
|
@ -43,16 +45,17 @@ class EmployeeDynamicFields(models.TransientModel): |
|
|
view_id = self.env.ref('hr.view_employee_form') |
|
|
view_id = self.env.ref('hr.view_employee_form') |
|
|
view_arch = str(view_id.arch_base) |
|
|
view_arch = str(view_id.arch_base) |
|
|
doc = xee.fromstring(view_arch) |
|
|
doc = xee.fromstring(view_arch) |
|
|
print("doc===", doc) |
|
|
|
|
|
field_list = [] |
|
|
field_list = [] |
|
|
for tag in doc.findall('.//field'): |
|
|
for tag in doc.findall('.//field'): |
|
|
print("tag==", tag) |
|
|
|
|
|
field_list.append(tag.attrib['name']) |
|
|
field_list.append(tag.attrib['name']) |
|
|
model_id = self.env['ir.model'].sudo().search([('model', '=', 'hr.employee')]) |
|
|
model_id = self.env['ir.model'].sudo().search( |
|
|
return [('model_id', '=', model_id.id), ('state', '=', 'base'), ('name', 'in', field_list)] |
|
|
[('model', '=', 'hr.employee')]) |
|
|
|
|
|
return [('model_id', '=', model_id.id), ('state', '=', 'base'), |
|
|
|
|
|
('name', 'in', field_list)] |
|
|
|
|
|
|
|
|
def _set_default(self): |
|
|
def _set_default(self): |
|
|
model_id = self.env['ir.model'].sudo().search([('model', '=', 'hr.employee')]) |
|
|
model_id = self.env['ir.model'].sudo().search( |
|
|
|
|
|
[('model', '=', 'hr.employee')]) |
|
|
return [('id', '=', model_id.id)] |
|
|
return [('id', '=', model_id.id)] |
|
|
|
|
|
|
|
|
def create_fields(self): |
|
|
def create_fields(self): |
|
@ -76,41 +79,51 @@ class EmployeeDynamicFields(models.TransientModel): |
|
|
'<field name="%s" position="%s">' |
|
|
'<field name="%s" position="%s">' |
|
|
'<field name="%s"/>' |
|
|
'<field name="%s"/>' |
|
|
'</field>' |
|
|
'</field>' |
|
|
'</data>') % (self.position_field.name, self.position, self.name) |
|
|
'</data>') % ( |
|
|
|
|
|
self.position_field.name, self.position, self.name) |
|
|
if self.widget: |
|
|
if self.widget: |
|
|
arch_base = _('<?xml version="1.0"?>' |
|
|
arch_base = _('<?xml version="1.0"?>' |
|
|
'<data>' |
|
|
'<data>' |
|
|
'<field name="%s" position="%s">' |
|
|
'<field name="%s" position="%s">' |
|
|
'<field name="%s" widget="%s"/>' |
|
|
'<field name="%s" widget="%s"/>' |
|
|
'</field>' |
|
|
'</field>' |
|
|
'</data>') % (self.position_field.name, self.position, self.name, self.widget.name) |
|
|
'</data>') % ( |
|
|
|
|
|
self.position_field.name, self.position, self.name, |
|
|
|
|
|
self.widget.name) |
|
|
|
|
|
|
|
|
self.env['ir.ui.view'].sudo().create({'name': 'employee.dynamic.fields', |
|
|
self.form_view_id = self.env['ir.ui.view'].sudo().create( |
|
|
'type': 'form', |
|
|
{'name': 'employee.dynamic.fields', |
|
|
'model': 'hr.employee', |
|
|
'type': 'form', |
|
|
'mode': 'extension', |
|
|
'model': 'hr.employee', |
|
|
'inherit_id': inherit_id.id, |
|
|
'mode': 'extension', |
|
|
'arch_base': arch_base, |
|
|
'inherit_id': inherit_id.id, |
|
|
'active': True}) |
|
|
'arch_base': arch_base, |
|
|
|
|
|
'active': True}) |
|
|
return { |
|
|
return { |
|
|
'type': 'ir.actions.client', |
|
|
'type': 'ir.actions.client', |
|
|
'tag': 'reload', |
|
|
'tag': 'reload', |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
position_field = fields.Many2one('ir.model.fields', string='Field Name', |
|
|
position_field = fields.Many2one('ir.model.fields', string='Field Name', |
|
|
domain=set_domain, required=True) |
|
|
domain=set_domain, required=True, |
|
|
|
|
|
ondelete='cascade') |
|
|
position = fields.Selection([('before', 'Before'), |
|
|
position = fields.Selection([('before', 'Before'), |
|
|
('after', 'After')], string='Position', required=True) |
|
|
('after', 'After')], string='Position', |
|
|
model_id = fields.Many2one('ir.model', string='Model', required=True, index=True, ondelete='cascade', |
|
|
required=True) |
|
|
help="The model this field belongs to", domain=_set_default) |
|
|
model_id = fields.Many2one('ir.model', string='Model', required=True, |
|
|
|
|
|
index=True, ondelete='cascade', |
|
|
|
|
|
help="The model this field belongs to", |
|
|
|
|
|
domain=_set_default) |
|
|
ref_model_id = fields.Many2one('ir.model', string='Model', index=True) |
|
|
ref_model_id = fields.Many2one('ir.model', string='Model', index=True) |
|
|
# In odoo 13 the field 'selection' is deprecated, so adding a new field to get the selection values. |
|
|
# In odoo 13 the field 'selection' is deprecated, so adding a new field to get the selection values. |
|
|
selection_field = fields.Char(string="Selection Options") |
|
|
selection_field = fields.Char(string="Selection Options") |
|
|
rel_field = fields.Many2one('ir.model.fields', string='Related Field') |
|
|
rel_field = fields.Many2one('ir.model.fields', string='Related Field') |
|
|
field_type = fields.Selection(selection='get_possible_field_types', string='Field Type', required=True) |
|
|
field_type = fields.Selection(selection='get_possible_field_types', |
|
|
|
|
|
string='Field Type', required=True) |
|
|
ttype = fields.Selection(string="Field Type", related='field_type') |
|
|
ttype = fields.Selection(string="Field Type", related='field_type') |
|
|
widget = fields.Many2one('employee.field.widgets', string='Widget') |
|
|
widget = fields.Many2one('employee.field.widgets', string='Widget') |
|
|
groups = fields.Many2many('res.groups', 'employee_dynamic_fields_group_rel', 'field_id', 'group_id') |
|
|
groups = fields.Many2many('res.groups', 'employee_dynamic_fields_group_rel', |
|
|
|
|
|
'field_id', 'group_id') |
|
|
extra_features = fields.Boolean(string="Show Extra Properties") |
|
|
extra_features = fields.Boolean(string="Show Extra Properties") |
|
|
|
|
|
|
|
|
@api.depends('field_type') |
|
|
@api.depends('field_type') |
|
@ -120,7 +133,8 @@ class EmployeeDynamicFields(models.TransientModel): |
|
|
if self.field_type == 'binary': |
|
|
if self.field_type == 'binary': |
|
|
return {'domain': {'widget': [('name', '=', 'image')]}} |
|
|
return {'domain': {'widget': [('name', '=', 'image')]}} |
|
|
elif self.field_type == 'many2many': |
|
|
elif self.field_type == 'many2many': |
|
|
return {'domain': {'widget': [('name', 'in', ['many2many_tags', 'binary'])]}} |
|
|
return {'domain': { |
|
|
|
|
|
'widget': [('name', 'in', ['many2many_tags', 'binary'])]}} |
|
|
elif self.field_type == 'selection': |
|
|
elif self.field_type == 'selection': |
|
|
return {'domain': { |
|
|
return {'domain': { |
|
|
'widget': [('name', 'in', ['radio', 'priority'])]}} |
|
|
'widget': [('name', 'in', ['radio', 'priority'])]}} |
|
@ -132,6 +146,14 @@ class EmployeeDynamicFields(models.TransientModel): |
|
|
return {'domain': {'widget': [('id', '=', False)]}} |
|
|
return {'domain': {'widget': [('id', '=', False)]}} |
|
|
return {'domain': {'widget': [('id', '=', False)]}} |
|
|
return {'domain': {'widget': [('id', '=', False)]}} |
|
|
|
|
|
|
|
|
|
|
|
def unlink(self): |
|
|
|
|
|
if self.form_view_id: |
|
|
|
|
|
self.form_view_id.active = False |
|
|
|
|
|
for field in self: |
|
|
|
|
|
query = """delete FROM ir_model_fields WHERE name = %s""" |
|
|
|
|
|
self.env.cr.execute(query, [field.name]) |
|
|
|
|
|
return super(EmployeeDynamicFields, self).unlink() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Employee(models.Model): |
|
|
class Employee(models.Model): |
|
|
_description = 'Employee' |
|
|
_description = 'Employee' |
|
|