Browse Source

Jun 13: [FIX] Bug Fixed 'all_in_one_dynamic_custom_fields'

pull/320/head
RisvanaCybro 11 months ago
parent
commit
dc6ed16201
  1. 6
      all_in_one_dynamic_custom_fields/README.rst
  2. 6
      all_in_one_dynamic_custom_fields/__init__.py
  3. 17
      all_in_one_dynamic_custom_fields/__manifest__.py
  4. 16
      all_in_one_dynamic_custom_fields/data/widget_data.xml
  5. 5
      all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md
  6. 8
      all_in_one_dynamic_custom_fields/models/__init__.py
  7. 19
      all_in_one_dynamic_custom_fields/models/dynamic_field_widgets.py
  8. 241
      all_in_one_dynamic_custom_fields/models/dynamic_fields.py
  9. 10
      all_in_one_dynamic_custom_fields/models/ir_model_fields.py
  10. 3
      all_in_one_dynamic_custom_fields/security/ir.model.access.csv
  11. 8
      all_in_one_dynamic_custom_fields/security/security.xml
  12. BIN
      all_in_one_dynamic_custom_fields/static/description/assets/screenshots/0.png
  13. BIN
      all_in_one_dynamic_custom_fields/static/description/assets/screenshots/1.png
  14. BIN
      all_in_one_dynamic_custom_fields/static/description/assets/screenshots/2.png
  15. BIN
      all_in_one_dynamic_custom_fields/static/description/assets/screenshots/3.png
  16. BIN
      all_in_one_dynamic_custom_fields/static/description/assets/screenshots/4.png
  17. 10
      all_in_one_dynamic_custom_fields/static/description/index.html
  18. 108
      all_in_one_dynamic_custom_fields/views/dynamic_fields.xml
  19. 116
      all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml

6
all_in_one_dynamic_custom_fields/README.rst

@ -1,11 +1,11 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
All in One Custom Dynamic Fields
================================
All in One Custom Dynamic Fields
The features of module facilitates the addition of fields to any view within a model,
allowing users to specify attributes and properties at their preferred location.
Installation
============

6
all_in_one_dynamic_custom_fields/__init__.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,5 +19,5 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
from . import models

17
all_in_one_dynamic_custom_fields/__manifest__.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,26 +19,27 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
{
'name': 'All in One Dynamic Fields',
'version': '16.0.1.1.3',
'summary': 'Create Custom Fields As Per Your Need Without Any Coding.',
'description': 'All in One Dynamic Fields, All in One Custom Fields, Dynamic Fields, Custom Fields, Create Fields Dynamically',
'version': '16.0.1.2.4',
'category': 'Extra Tools',
'summary': 'Create Custom Fields As Per Your Need Without Any Coding.',
'description': 'All in One Dynamic Fields, All in One Custom Fields, '
'Dynamic Fields, Custom Fields, Create Fields Dynamically',
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "https://www.cybrosys.com",
'license': 'AGPL-3',
'depends': ['base'],
'data': [
'data/widget_data.xml',
'security/security.xml',
'security/ir.model.access.csv',
'views/dynamic_fields.xml',
'views/dynamic_fields_views.xml',
],
'images': ['static/description/banner.png'],
'license': 'AGPL-3',
'installable': True,
'auto_install': False,
'application': False,

16
all_in_one_dynamic_custom_fields/data/widget_data.xml

@ -2,37 +2,37 @@
<odoo>
<data noupdate="1">
<!-- Widget 'image' for 'binary' field -->
<record id="image_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_image" model="dynamic.field.widgets">
<field name="name">image</field>
<field name="description">Image</field>
</record>
<!-- Widget 'many2many_tags' for 'many2many' field -->
<record id="many2many_tag_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_many2many_tags" model="dynamic.field.widgets">
<field name="name">many2many_tags</field>
<field name="description">Many2many Tags</field>
</record>
<!-- Widget 'binary' for 'many2many' field -->
<record id="many2many_binary_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_binary" model="dynamic.field.widgets">
<field name="name">binary</field>
<field name="description">Binary</field>
</record>
<!-- Widget 'radio' for 'selection' field -->
<record id="radio_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_radio" model="dynamic.field.widgets">
<field name="name">radio</field>
<field name="description">Radio</field>
</record>
<!-- Widget 'priority' for 'selection' field -->
<record id="priority_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_priority" model="dynamic.field.widgets">
<field name="name">priority</field>
<field name="description">Priority</field>
</record>
<!-- Widget 'monetory' for 'float' field -->
<record id="monetory_widget" model="dynamic.field.widgets">
<!-- Widget 'monetary' for 'float' field -->
<record id="dynamic_field_widgets_monetary" model="dynamic.field.widgets">
<field name="name">monetary</field>
<field name="description">Monetary</field>
</record>
<!-- Widget 'selection' for 'Many2one' field -->
<record id="selection_widget" model="dynamic.field.widgets">
<record id="dynamic_field_widgets_selection" model="dynamic.field.widgets">
<field name="name">selection</field>
<field name="description">Selection</field>
</record>

5
all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md

@ -4,3 +4,8 @@
#### Version 16.0.1.1.3
##### ADD
- Initial commit for All in One Custom Dynamic Fields
#### 12.06.2024
#### Version 16.0.1.2.4
##### UPDATE
- The latest module update includes enhancements to the list view configuration. You can now add the newly created field to the selected list view at the desired position, with the option to enable or disable its visibility by default.

8
all_in_one_dynamic_custom_fields/models/__init__.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2024-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
from . import ir_model_fields
from . import field_widgets
from . import dynamic_field_widgets
from . import dynamic_fields

19
all_in_one_dynamic_custom_fields/models/field_widgets.py → all_in_one_dynamic_custom_fields/models/dynamic_field_widgets.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2024-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,19 +19,20 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
from odoo import models, fields
class FieldWidgets(models.Model):
"""We can't filter a selection field dynamically
so when we select a field its widgets also need to change according to the selected
field type, we can't do it by a 'selection' field, need a 'Many2one' field.
class DynamicFieldWidgets(models.Model):
"""We can't filter a selection field dynamically so when we select a
field its widgets also need to change according to the selected field
type, we can't do it by a 'selection' field, need a 'Many2one' field.
"""
_name = 'dynamic.field.widgets'
_rec_name = 'description'
_description = 'Field Widgets'
name = fields.Char(string="Name")
description = fields.Char(string="Description")
name = fields.Char(string="Name", help='Name of the record')
description = fields.Char(string="Description", help='Description given to '
'the record')

241
all_in_one_dynamic_custom_fields/models/dynamic_fields.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2024-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,12 +19,15 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
from xlrd.xlsx import ET
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class DynamicFields(models.Model):
"""Class DynamicFields to create fields dynamically to any model"""
_name = 'dynamic.fields'
_rec_name = 'field_description'
_description = 'Custom Dynamic Fields'
@ -39,49 +42,127 @@ class DynamicFields(models.Model):
field_list.remove(('reference', 'reference'))
return field_list
position_field = fields.Many2one('ir.model.fields', string='Field Name',
required=True,
ondelete='cascade')
position_field_id = fields.Many2one('ir.model.fields',
string='Field Name',
help='Position Field Name',
required=True,
ondelete='cascade')
position = fields.Selection([('before', 'Before'),
('after', 'After')], string='Position',
help='position of the newly created field',
required=True)
model_id = fields.Many2one('ir.model', string='Model', required=True,
model_id = fields.Many2one('ir.model', string='Model',
required=True,
index=True, ondelete='cascade',
help="The model this field belongs to")
ref_model_id = fields.Many2one('ir.model', string='Model', index=True)
selection_field = fields.Char(string="Selection Options")
rel_field = fields.Many2one('ir.model.fields', string='Related Field')
ref_model_id = fields.Many2one('ir.model', string='Model',
index=True, help='Reference model of the '
'relational field')
selection_field = fields.Char(string="Selection Options",
help='Selection options for field')
rel_field_id = fields.Many2one('ir.model.fields',
string='Related Field', help='Related field')
field_type = fields.Selection(selection='get_possible_field_types',
string='Field Type', required=True)
ttype = fields.Selection(string="Field Type", related='field_type')
widget = fields.Many2one('dynamic.field.widgets', string='Widget')
groups = fields.Many2many('res.groups', 'employee_dynamic_fields_group_rel',
'field_id', 'group_id')
extra_features = fields.Boolean(string="Show Extra Properties")
string='Field Type',
help='Field type of newly created field',
required=True)
ttype = fields.Selection(string="Field Type", related='field_type',
help='Field type')
widget_id = fields.Many2one('dynamic.field.widgets',
string='Widget',
help='Widget of the newly selected field')
groups = fields.Many2many('res.groups',
'employee_dynamic_fields_group_rel',
'field_id', 'group_id',
string='Groups', help='Groups')
is_extra_features = fields.Boolean(string="Show Extra Properties",
help='Show Extra Properties of newly '
'field')
created_from_id = fields.Many2one('ir.ui.view',
help='Created form view id for the field',
string='Dynamic created form view')
status = fields.Selection([
('draft', 'Draft'),
('form', 'Field Created'),
('tree', 'Added in Tree View'),
], string='Status', index=True, readonly=True, tracking=True,
copy=False, default='draft',
required=True, help='Record Status')
help='Record Status')
form_view_id = fields.Many2one('ir.ui.view', string="Form View ID",
form_view_id = fields.Many2one('ir.ui.view',
string="Form View ID",
help='Form View ID',
required=True)
form_view_inherit_id = fields.Char(string="Form View Inherit Id",
help="Form View Inherit Id",
related='form_view_id.xml_id')
add_field_in_tree = fields.Boolean(string="Add Field to the Tree View",
default=False)
tree_view_id = fields.Many2one('ir.ui.view', string="Tree View ID")
is_add_field_in_tree = fields.Boolean(string="Add Field to the Tree View",
help="Add newly created Field to "
"the Tree View")
tree_view_id = fields.Many2one('ir.ui.view',
string="Tree View ID", help='Tree View ID')
tree_view_inherit_id = fields.Char(string="Tree View Inherit Id",
help='Tree View Inherit Id',
readonly=True,
related='tree_view_id.xml_id')
tree_field_position = fields.Selection([('before', 'Before'),
('after', 'After')],
string='Position',
help='Tree field position to the '
'selected tree field')
tree_field_ids = fields.Many2many('ir.model.fields',
string='Tree View Fields',
compute='_compute_tree_field_ids',
help='Domain field for tree view fields')
tree_view_field_id = fields.Many2one('ir.model.fields',
string='Tree View Field',
domain="[('id', 'in', "
"tree_field_ids)]",
help='Select a tree view field for '
'position of newly created '
'field in the tree view')
is_tree_view_toggle = fields.Boolean(string='Visible in tree view',
help='Enable to toggle view the newly '
'created view in selected tree '
'view')
created_tree_view_id = fields.Many2one('ir.ui.view',
help='Dynamic Created tree view id',
string='Dynamic Tree view id')
@api.depends('tree_view_id')
def _compute_tree_field_ids(self):
"""Compute function to find the tree view fields of selected tree view
in field tree_view_id"""
for rec in self:
if rec.tree_view_id:
field_list = []
if rec.tree_view_id.xml_id:
tree_fields = ET.fromstring(self.env.ref(
rec.tree_view_id.xml_id).arch).findall(".//field")
for field in tree_fields:
field_list.append(field.get('name'))
inherit_id = rec.tree_view_id.inherit_id \
if rec.tree_view_id.inherit_id else False
while inherit_id:
if inherit_id.xml_id:
tree_fields = ET.fromstring(self.env.ref(
inherit_id.xml_id).arch).findall(".//field")
for field in tree_fields:
field_list.append(field.get('name'))
inherit_id = inherit_id.inherit_id \
if inherit_id.inherit_id else False
self.tree_field_ids = self.env['ir.model.fields'].search(
[('model_id', '=', self.model_id.id),
('name', 'in', field_list)])
else:
rec.tree_field_ids = False
def create_dynamic_fields(self):
def action_create_dynamic_fields(self):
"""Function create Dynamic field"""
self.write({'status': 'form'})
if self.field_type == 'monetary' and not self.env[
'ir.model.fields'].sudo().search([
('model', '=', self.model_id.id),
('name', '=', 'currency_id')]):
'ir.model.fields'].sudo().search([('model', '=', self.model_id.id),
('name', '=', 'currency_id')]):
self.env['ir.model.fields'].sudo().create({
'name': 'x_currency_id',
'field_description': 'Currency',
@ -105,9 +186,9 @@ class DynamicFields(models.Model):
'copied': self.copied,
'is_dynamic_field': True
})
inherit_form_view_name = str(
self.form_view_id.name) + ".inherit.dynamic.custom." + \
str(self.field_description) + ".field"
inherit_form_view_name = (str(
self.form_view_id.name) + ".inherit.dynamic.custom." +
str(self.field_description) + ".field")
xml_id = self.form_view_id.xml_id
inherit_id = self.env.ref(xml_id)
arch_base = _('<?xml version="1.0"?>'
@ -115,18 +196,18 @@ class DynamicFields(models.Model):
'<field name="%s" position="%s">'
'<field name="%s"/>'
'</field>'
'</data>') % (self.position_field.name,
'</data>') % (self.position_field_id.name,
self.position, self.name)
if self.widget:
if self.widget_id:
arch_base = _('<?xml version="1.0"?>'
'<data>'
'<field name="%s" position="%s">'
'<field name="%s" widget="%s"/>'
'</field>'
'</data>') % (self.position_field.name,
'</data>') % (self.position_field_id.name,
self.position, self.name,
self.widget.name)
self.form_view_id = self.env['ir.ui.view'].sudo().create({
self.widget_id.name)
self.created_from_id = self.env['ir.ui.view'].sudo().create({
'name': inherit_form_view_name,
'type': 'form',
'model': self.model_id.model,
@ -140,80 +221,82 @@ class DynamicFields(models.Model):
'tag': 'reload',
}
def add_field_to_tree_view(self):
if self.add_field_in_tree:
if self.add_field_in_tree:
inherit_tree_view_name = str(
self.tree_view_id.name) + ".inherit.dynamic.custom" + \
str(self.field_description) + ".field"
tree_view_arch_base = _(
'<?xml version="1.0"?>'
'<data>'
'''<xpath expr="//tree" position="inside">'''
'''<field name="%s" optional="show"/>'''
'''</xpath>'''
'''</data>''') % self.name
self.tree_view_id = self.env['ir.ui.view'].sudo().create({
'name': inherit_tree_view_name,
'type': 'tree',
'model': self.model_id.model,
'mode': 'extension',
'inherit_id': self.tree_view_id.id,
'arch_base': tree_view_arch_base,
'active': True})
self.write({'status': 'tree'})
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
def action_add_field_to_tree_view(self):
"""Function to add created dynamic field to selected tree view"""
if self.is_add_field_in_tree:
inherit_tree_view_name = str(
self.tree_view_id.name) + ".inherit.dynamic.custom" + \
str(self.field_description) + ".field"
optional = "show" if self.is_tree_view_toggle else "hide"
tree_view_arch_base = (_(f'''
<data>
<xpath expr="//field[@name='{self.tree_view_field_id.name}']" position="{self.tree_field_position}">
<field name="{self.name}" optional="{optional}"/>
</xpath>
</data>'''))
self.created_tree_view_id = self.env['ir.ui.view'].sudo().create({
'name': inherit_tree_view_name,
'type': 'tree',
'model': self.model_id.model,
'mode': 'extension',
'inherit_id': self.tree_view_id.id,
'arch_base': tree_view_arch_base,
'active': True})
self.write({'status': 'tree'})
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
else:
raise ValidationError(
_('Error! Please select the boolean field Add Field to the Tree View.'))
_('Error! Please select the boolean field Add Field to the '
'Tree View.'))
@api.depends('model_id','add_field_in_tree')
@api.onchange('model_id','add_field_in_tree')
@api.onchange('model_id', 'is_add_field_in_tree')
def set_domain(self):
"""Return the fields that currently present in the form"""
form_view_ids = self.model_id.view_ids.filtered(
lambda l: l.type == 'form' and l.mode == 'primary')
lambda x: x.type == 'form' and x.mode == 'primary')
tree_view_ids = self.model_id.view_ids.filtered(
lambda l: l.type == 'tree' and l.mode == 'primary')
fields = self.env['ir.model.fields'].sudo().search([
lambda x: x.type == 'tree' and x.mode == 'primary')
fields_domain = self.env['ir.model.fields'].sudo().search([
('model', '=', self.model_id.model)])
field_list = []
for rec in fields:
for rec in fields_domain:
for field in rec:
field_list.append(field.id)
return {'domain': {
'form_view_id': [('id', 'in', form_view_ids.ids)],
'tree_view_id': [('id', 'in', tree_view_ids.ids)],
'position_field': [('id', 'in', field_list)]
'position_field_id': [('id', 'in', field_list)]
}}
@api.depends('field_type')
@api.onchange('field_type')
def onchange_field_type(self):
"""Function to determine domain for field widget"""
if self.field_type:
if self.field_type == 'binary':
return {'domain': {'widget': [('name', '=', 'image')]}}
return {'domain': {'widget_id': [('name', '=', 'image')]}}
elif self.field_type == 'many2many':
return {'domain': {'widget': [
return {'domain': {'widget_id': [
('name', 'in', ['many2many_tags', 'binary'])]}}
elif self.field_type == 'selection':
return {'domain': {
'widget': [('name', 'in', ['radio', 'priority'])]}}
'widget_id': [('name', 'in', ['radio', 'priority'])]}}
elif self.field_type == 'float':
return {'domain': {'widget': [('name', '=', 'monetary')]}}
return {'domain': {'widget_id': [('name', '=', 'monetary')]}}
elif self.field_type == 'many2one':
return {'domain': {'widget': [('name', '=', 'selection')]}}
return {'domain': {'widget_id': [('name', '=', 'selection')]}}
else:
return {'domain': {'widget': [('id', '=', False)]}}
return {'domain': {'widget': [('id', '=', False)]}}
return {'domain': {'widget_id': [('id', '=', False)]}}
return {'domain': {'widget_id': [('id', '=', False)]}}
def unlink(self):
if self.form_view_id:
self.form_view_id.active = False
if self.tree_view_id:
self.tree_view_id.active = False
"""Unlink function to make the created tree view and from view to
inactive"""
if self.created_from_id:
self.created_from_id.active = False
if self.created_tree_view_id:
self.created_tree_view_id.active = False
res = super(DynamicFields, self).unlink()
return res

10
all_in_one_dynamic_custom_fields/models/ir_model_fields.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
###################################################################################
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2022-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Copyright (C) 2024-TODAY Cybrosys Technologies (<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
################################################################################
from odoo import models, fields
@ -28,4 +28,6 @@ class IrModelFields(models.Model):
_inherit = 'ir.model.fields'
is_dynamic_field = fields.Boolean(string="Dynamic Field")
is_dynamic_field = fields.Boolean(string="Dynamic Field",
help="id created using All In One "
"Dynamic Custom Fields")

3
all_in_one_dynamic_custom_fields/security/ir.model.access.csv

@ -1,5 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_all_in_one_dynamic_custom_fields_administrator,dynamic.fields,model_dynamic_fields,all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator,1,1,1,1
access_all_in_one_dynamic_custom_fields_user,dynamic.fields,model_dynamic_fields,all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_user,1,0,0,0
access_dynamic_field_widgets,"dynamic.field.widgets","model_dynamic_field_widgets",,1,1,1,1
access_dynamic_field_widgets,dynamic.field.widgets,model_dynamic_field_widgets,base.group_user,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_all_in_one_dynamic_custom_fields_administrator dynamic.fields model_dynamic_fields all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator 1 1 1 1
3 access_all_in_one_dynamic_custom_fields_user dynamic.fields model_dynamic_fields all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_user 1 0 0 0
4 access_dynamic_field_widgets dynamic.field.widgets model_dynamic_field_widgets base.group_user 1 1 1 1

8
all_in_one_dynamic_custom_fields/security/security.xml

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<!--Created a module category for all in one dynamic custom fields-->
<record id="module_category_all_in_one_dynamic_custom_fields"
model="ir.module.category">
<field name="name">All in One Custom Dynamic Fields</field>
<field name="description">Helps you handle your All-in-One Custom Dynamic Fields Permissions </field>
<field name="sequence">5</field>
</record>
<!--Created a new group User in one dynamic custom fields-->
<record id="group_all_in_one_dynamic_custom_fields_user"
model="res.groups">
<field name="name">User</field>
<field name="category_id"
ref="all_in_one_dynamic_custom_fields.module_category_all_in_one_dynamic_custom_fields"/>
</record>
<!--Created a new group Administrator in one dynamic custom fields-->
<record id="group_all_in_one_dynamic_custom_fields_administrator"
model="res.groups">
<field name="name">Administrator</field>
@ -26,7 +26,5 @@
<field name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
</odoo>

BIN
all_in_one_dynamic_custom_fields/static/description/assets/screenshots/0.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
all_in_one_dynamic_custom_fields/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
all_in_one_dynamic_custom_fields/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
all_in_one_dynamic_custom_fields/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
all_in_one_dynamic_custom_fields/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

10
all_in_one_dynamic_custom_fields/static/description/index.html

@ -171,14 +171,14 @@
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Open the module and Click Create Button to create new custom fields and fill the details.Then click the Create Field.</p>
<img src="assets/screenshots/tree.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic2.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic3.png" class="img-thumbnail">
<img src="assets/screenshots/0.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Model
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Select the model for which you want to create a custom field.</p>
<img src="assets/screenshots/dynamic4.png" class="img-thumbnail">
<img src="assets/screenshots/1.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic5.png" class="img-thumbnail">
</div>
@ -186,14 +186,14 @@
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Field Type
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">Choose the field type</p>
<img src="assets/screenshots/dynamic6.png" class="img-thumbnail">
<img src="assets/screenshots/2.png" class="img-thumbnail">
</div>
<div style="display: block; margin: 30px auto;">
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">List / Tree View
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;">The custom field also we can add to the module List/Tree view.</p>
<img src="assets/screenshots/dynamic7.png" class="img-thumbnail">
<img src="assets/screenshots/3.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic8.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic9.png" class="img-thumbnail">
</div>
@ -209,7 +209,7 @@
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> Sale Order Tree/List View
</h3>
<p style="font-weight: 400; font-family: 'Montserrat', sans-serif; font-size: 14px;"> A new custom field is created in the sale order tree view.</p>
<img src="assets/screenshots/dynamic11.png" class="img-thumbnail">
<img src="assets/screenshots/4.png" class="img-thumbnail">
<img src="assets/screenshots/dynamic12.png" class="img-thumbnail">
</div>

108
all_in_one_dynamic_custom_fields/views/dynamic_fields.xml

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="custom_dynamic_fields_view_tree" model="ir.ui.view">
<field name="name">custom_dynamic_fields_view_tree</field>
<field name="model">dynamic.fields</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="field_description"/>
<field name="model_id"/>
<field name="status"/>
</tree>
</field>
</record>
<record id='custom_dynamic_fields_view_form' model='ir.ui.view'>
<field name="name">custom_dynamic_fields_view_form</field>
<field name="model">dynamic.fields</field>
<field name="arch" type="xml">
<form>
<header>
<button name="create_dynamic_fields" string="Create Field" type="object" class="oe_highlight"
attrs="{'invisible': [('status', 'in', ['form','tree'])]}" groups="all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator"/>
<button name="add_field_to_tree_view" string="Add to Tree View" type="object" class="oe_highlight"
attrs="{'invisible': [('status', 'in', ['draft','tree'])]}" groups="all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator"/>
<field name="status" widget="statusbar"
statusbar_visible="draft,form,tree"/>
</header>
<sheet>
<group>
<group string="Field Info">
<field name="name"/>
<field name="field_description"/>
<field name="state" readonly="1" groups="base.group_no_one"/>
<field name="model_id" options='{"no_open": True, "no_create": True}'/>
<field name="field_type"/>
<field name="selection_field" placeholder="[('blue', 'Blue'),('yellow', 'Yellow')]"
attrs="{'required': [('field_type','in',['selection','reference'])],
'readonly': [('field_type','not in',['selection','reference'])],
'invisible': [('field_type','not in',['selection','reference'])]}"/>
<field name="ref_model_id" options='{"no_open": True, "no_create": True}' attrs="{'required': [('field_type','in',['many2one','many2many'])],
'readonly': [('field_type','not in',['many2one','many2many'])],
'invisible': [('field_type','not in',['many2one','many2many'])]}"/>
<field name="widget" widget="selection"
attrs="{'invisible': [('field_type','not in',['binary', 'many2many', 'selection', 'float', 'many2one'])]}"/>
<field name="required"/>
<field name="form_view_id"/>
<field name="form_view_inherit_id"/>
</group>
<group string="Tree View">
<field name="add_field_in_tree"/>
<field name="tree_view_id" attrs="{'invisible': [('add_field_in_tree', '=', False)],
'required': [('add_field_in_tree', '=', True)]}"/>
<field name="tree_view_inherit_id" attrs="{'invisible': [('add_field_in_tree', '=', False)]}"/>
</group>
<group string="Position">
<field name="position_field" options='{"no_open": True, "no_create": True}'/>
<field name="position"/>
</group>
</group>
<group string="Extra Properties">
<group>
<field name="extra_features"/>
</group>
<group attrs="{'invisible': [('extra_features', '=', False)]}">
<field name="help"/>
</group>
<group attrs="{'invisible': [('extra_features', '=', False)]}">
<field name="readonly"/>
<field name="store"/>
<field name="index"/>
<field name="copied"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id='action_dynamic_custom_fields' model='ir.actions.act_window'>
<field name="name">Custom Dynamic Fields</field>
<field name="res_model">dynamic.fields</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create New Custom Dynamic Field!
</p>
</field>
</record>
<menuitem id="menu_all_in_one_dynamic_custom_fields_root"
name="All in One Custom Dynamic Fields"
groups="group_all_in_one_dynamic_custom_fields_user,group_all_in_one_dynamic_custom_fields_administrator"
web_icon="all_in_one_dynamic_custom_fields,static/description/icon.png"
sequence="01"/>
<menuitem id="menu_create_custom_dynamic_fields"
name="Fields"
parent="menu_all_in_one_dynamic_custom_fields_root"
sequence="1"/>
<menuitem id="menu_create_fields"
name="Create Fields"
parent="menu_create_custom_dynamic_fields"
action="action_dynamic_custom_fields"
groups="group_all_in_one_dynamic_custom_fields_user,group_all_in_one_dynamic_custom_fields_administrator"
sequence="2"/>
</odoo>

116
all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Tree view for dynamic fields-->
<record id="dynamic_fields_view_tree" model="ir.ui.view">
<field name="name">dynamic.fields.view.tree</field>
<field name="model">dynamic.fields</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="field_description"/>
<field name="model_id"/>
<field name="status"/>
</tree>
</field>
</record>
<!--From view for dynamic fields-->
<record id='dynamic_fields_view_form' model='ir.ui.view'>
<field name="name">dynamic.fields.view.form</field>
<field name="model">dynamic.fields</field>
<field name="arch" type="xml">
<form>
<header>
<button name="action_create_dynamic_fields" string="Create Field" type="object" class="oe_highlight"
attrs="{'invisible': [('status', 'in', ['form','tree'])]}" groups="all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator"/>
<button name="action_add_field_to_tree_view" string="Add to Tree View" type="object" class="oe_highlight"
attrs="{'invisible': [('status', 'in', ['draft','tree'])]}" groups="all_in_one_dynamic_custom_fields.group_all_in_one_dynamic_custom_fields_administrator"/>
<field name="status" widget="statusbar"
statusbar_visible="draft,form,tree"/>
</header>
<sheet>
<group>
<group string="Field Info">
<field name="name" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="field_description" attrs="{'readonly': [('status', '!=', 'draft')]}"/>/>
<field name="state" readonly="1" groups="base.group_no_one"/>
<field name="model_id" options='{"no_open": True, "no_create": True}' attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="field_type" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="selection_field" placeholder="[('blue', 'Blue'),('yellow', 'Yellow')]"
attrs="{'required': [('field_type','in',['selection','reference'])],
'readonly': [('field_type','not in',['selection','reference'])],
'invisible': [('field_type','not in',['selection','reference'])]}"/>
<field name="ref_model_id" options='{"no_open": True, "no_create": True}' attrs="{'required': [('field_type','in',['many2one','many2many'])],
'readonly': ['|',('field_type','not in',['many2one','many2many']),('status', '!=', 'draft')],
'invisible': [('field_type','not in',['many2one','many2many'])]}"/>
<field name="widget_id" widget="selection"
attrs="{'invisible': [('field_type','not in',['binary', 'many2many', 'selection', 'float', 'many2one'])],
'readonly': [('status', '!=', 'draft')]}"/>
<field name="required" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="form_view_id" options='{"no_open": True, "no_create": True}' attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="form_view_inherit_id"/>
</group>
<group string="Tree View">
<field name="is_add_field_in_tree" attrs="{'readonly': [('status', 'not in', ['draft', 'form'])]}"/>
<field name="tree_view_id" options='{"no_open": True, "no_create": True}' attrs="{'invisible': [('is_add_field_in_tree', '=', False)],
'required': [('is_add_field_in_tree', '=', True)], 'readonly': [('status', 'not in', ['draft', 'form'])]}"/>
<field name="tree_view_inherit_id" attrs="{'invisible': [('is_add_field_in_tree', '=', False)]}"/>
<field name="tree_view_field_id" options='{"no_open": True, "no_create": True}' attrs="{'invisible': [('is_add_field_in_tree', '=', False)],
'required': [('is_add_field_in_tree', '=', True)], 'readonly': [('status', 'not in', ['draft', 'form'])]}"/>
<field name="tree_field_position" attrs="{'invisible': [('is_add_field_in_tree', '=', False)],
'required': [('is_add_field_in_tree', '=', True)], 'readonly': [('status', 'not in', ['draft', 'form'])]}"/>
<field name="is_tree_view_toggle" attrs="{'invisible': [('is_add_field_in_tree', '=', False)],
'required': [('is_add_field_in_tree', '=', True)], 'readonly': [('status', 'not in', ['draft', 'form'])]}"/>
<field name="tree_field_ids" invisible="1"/>
</group>
<group string="Position">
<field name="position_field_id" options='{"no_open": True, "no_create": True}' attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="position" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
</group>
</group>
<group string="Extra Properties">
<group>
<field name="is_extra_features" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
</group>
<group attrs="{'invisible': [('is_extra_features', '=', False)], 'readonly': [('status', '!=', 'draft')]}">
<field name="help" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
</group>
<group attrs="{'invisible': [('is_extra_features', '=', False)]}">
<field name="readonly" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="store" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="index" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
<field name="copied" attrs="{'readonly': [('status', '!=', 'draft')]}"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!--Action for dynamic fields-->
<record id='dynamic_fields_action' model='ir.actions.act_window'>
<field name="name">Custom Dynamic Fields</field>
<field name="res_model">dynamic.fields</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create New Custom Dynamic Field!
</p>
</field>
</record>
<!--Menu item for dynamic fields-->
<menuitem id="menu_all_in_one_dynamic_custom_fields_root"
name="All in One Custom Dynamic Fields"
groups="group_all_in_one_dynamic_custom_fields_user,group_all_in_one_dynamic_custom_fields_administrator"
web_icon="all_in_one_dynamic_custom_fields,static/description/icon.png"
sequence="01"/>
<menuitem id="menu_create_custom_dynamic_fields"
name="Fields"
parent="menu_all_in_one_dynamic_custom_fields_root"
sequence="1"/>
<menuitem id="menu_create_fields"
name="Create Fields"
parent="menu_create_custom_dynamic_fields"
action="dynamic_fields_action"
groups="group_all_in_one_dynamic_custom_fields_user,group_all_in_one_dynamic_custom_fields_administrator"
sequence="2"/>
</odoo>
Loading…
Cancel
Save