diff --git a/all_in_one_dynamic_custom_fields/__manifest__.py b/all_in_one_dynamic_custom_fields/__manifest__.py
index a5468779c..9fcf5d293 100755
--- a/all_in_one_dynamic_custom_fields/__manifest__.py
+++ b/all_in_one_dynamic_custom_fields/__manifest__.py
@@ -21,13 +21,13 @@
################################################################################
{
'name': 'All in One Dynamic Fields',
- 'version': '17.0.1.0.0',
+ 'version': '17.0.1.1.1',
'category': 'Extra Tools',
'summary': 'Create Custom Fields As Per Your Need Without Any Coding.',
'description': "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.",
+ "to any view within a model, allowing users to specify"
+ "attributes and properties at their preferred "
+ "location.",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
diff --git a/all_in_one_dynamic_custom_fields/data/dynamic_field_widgets_data.xml b/all_in_one_dynamic_custom_fields/data/dynamic_field_widgets_data.xml
index be0e7c4fe..fd2795e61 100755
--- a/all_in_one_dynamic_custom_fields/data/dynamic_field_widgets_data.xml
+++ b/all_in_one_dynamic_custom_fields/data/dynamic_field_widgets_data.xml
@@ -2,43 +2,43 @@
-
+
image
binary
Image
-
+
many2many_tags
many2many
Many2many Tags
-
+
binary
many2many
Binary
-
+
radio
selection
Radio
-
+
priority
selection
Priority
-
-
+
+
monetary
float
Monetary
-
+
selection
many2one
Selection
diff --git a/all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md b/all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md
index dfe0eed21..ffdd4ff0e 100755
--- a/all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md
+++ b/all_in_one_dynamic_custom_fields/doc/RELEASE_NOTES.md
@@ -5,3 +5,8 @@
##### ADD
- Initial commit for All in One Custom Dynamic Fields
+
+#### 13.06.2024
+#### Version 17.0.1.1.1
+##### 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.
diff --git a/all_in_one_dynamic_custom_fields/models/__init__.py b/all_in_one_dynamic_custom_fields/models/__init__.py
index 70627ee22..bca849147 100755
--- a/all_in_one_dynamic_custom_fields/models/__init__.py
+++ b/all_in_one_dynamic_custom_fields/models/__init__.py
@@ -20,5 +20,5 @@
#
################################################################################
from . import dynamic_fields
-from . import field_widgets
+from . import dynamic_field_widgets
from . import ir_model_fields
diff --git a/all_in_one_dynamic_custom_fields/models/field_widgets.py b/all_in_one_dynamic_custom_fields/models/dynamic_field_widgets.py
similarity index 97%
rename from all_in_one_dynamic_custom_fields/models/field_widgets.py
rename to all_in_one_dynamic_custom_fields/models/dynamic_field_widgets.py
index 8bf409e49..706797428 100755
--- a/all_in_one_dynamic_custom_fields/models/field_widgets.py
+++ b/all_in_one_dynamic_custom_fields/models/dynamic_field_widgets.py
@@ -22,7 +22,7 @@
from odoo import fields, models
-class FieldWidgets(models.Model):
+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,
diff --git a/all_in_one_dynamic_custom_fields/models/dynamic_fields.py b/all_in_one_dynamic_custom_fields/models/dynamic_fields.py
index 06aca196d..69bf80731 100755
--- a/all_in_one_dynamic_custom_fields/models/dynamic_fields.py
+++ b/all_in_one_dynamic_custom_fields/models/dynamic_fields.py
@@ -19,6 +19,8 @@
# If not, see .
#
################################################################################
+from xlrd.xlsx import ET
+
from odoo import api, fields, models, _
@@ -65,7 +67,7 @@ class DynamicFields(models.Model):
required=True, help="Position of new field")
model_id = fields.Many2one(comodel_name='ir.model', string='Model',
required=True,
- index=True, ondelete='cascade',
+ index=True,
help="The model this field belongs to")
ref_model_id = fields.Many2one(comodel_name='ir.model', string='Relational '
'Model',
@@ -76,16 +78,20 @@ class DynamicFields(models.Model):
field_type = fields.Selection(selection='get_possible_field_types',
string='Field Type', required=True,
help="Data type of new field")
+ tree_field_ids = fields.Many2many('ir.model.fields',
+ 'tree_field_ids',
+ compute='_compute_tree_field_ids')
ttype = fields.Selection(string="Field Type", related='field_type',
help="Field type of field")
- widget = fields.Many2one(comodel_name='dynamic.field.widgets',
- string='Widget', help="Widgets for field",
- domain=lambda self: "[('data_type', '=', "
- "field_type)]")
+ widget_id = fields.Many2one(comodel_name='dynamic.field.widgets',
+ string='Widget', help="Widgets for field",
+ domain=lambda self: "[('data_type', '=', "
+ "field_type)]")
groups = fields.Many2many('res.groups',
- 'employee_dynamic_fields_group_rel',
- 'field_id', 'group_id',
- help="Groups of field")
+ 'dynamic_fields_group_rel',
+ 'dynamic_field_id',
+ 'dynamic_group_id',
+ help="Groups of field")
extra_features = fields.Boolean(string="Show Extra Properties",
help="Enable to add extra features")
status = fields.Selection(selection=[('draft', 'Draft'), ('form',
@@ -93,7 +99,7 @@ class DynamicFields(models.Model):
string='Status',
index=True, readonly=True, tracking=True,
copy=False, default='draft',
- required=True, help='State for record')
+ help='State for record')
form_view_ids = fields.Many2many(comodel_name='ir.ui.view',
string="Form View IDs",
help="Stores form view ids")
@@ -112,26 +118,78 @@ class DynamicFields(models.Model):
help="Form view inherit id(adds"
" by selecting form view id)")
add_field_in_tree = fields.Boolean(string="Add Field to the Tree View",
- default=False,
help="Enable to add field in tree view")
tree_view_id = fields.Many2one(comodel_name='ir.ui.view',
string="Tree View ID",
help="Tree view id of the model",
domain=lambda self: "[('id', 'in', "
"tree_view_ids)]")
- tree_view_inherit_id = fields.Char(string="Tree View Inherit Id",
+ tree_view_inherit_id = fields.Char(string="External Id",
related='tree_view_id.xml_id',
help="Tree view inherit id(adds"
" by selecting tree view id)")
+ tree_field_id = fields.Many2one('ir.model.fields',
+ string='Tree Field',
+ help='Position for new field',
+ domain="[('id', 'in', tree_field_ids)]")
+ tree_field_position = fields.Selection(selection=[('before', 'Before'),
+ ('after', 'After')],
+ string='Tree Position',
+ help="Position of new field in "
+ "tree view")
+ is_visible_in_tree_view = fields.Boolean(string='Visible In List View',
+ help="Enable to make the field "
+ "visible in selected list "
+ "view of the model")
+ created_tree_view_id = fields.Many2one('ir.ui.view',
+ string='Created Tree view',
+ help='This is the currently '
+ 'created tree view')
+ created_form_view_id = fields.Many2one('ir.ui.view',
+ string='Created form view',
+ help='Created form view id for the '
+ 'dynamic field')
+
+ @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:
+ fields = ET.fromstring(self.env.ref(
+ rec.tree_view_id.xml_id).arch).findall(".//field")
+ for field in 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:
+ fields = ET.fromstring(self.env.ref(
+ inherit_id.xml_id).arch).findall(".//field")
+ for field in 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
+
+ @api.onchange('add_field_in_tree')
+ def _onchange_add_field_in_tree(self):
+ """Function to clear values of tree_view_id and tree_field_id"""
+ if not self.add_field_in_tree:
+ self.tree_view_id = False
+ self.tree_field_id = False
def action_create_dynamic_field(self):
"""Function to create dynamic field to a particular model, data type,
properties and etc"""
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',
@@ -139,6 +197,7 @@ class DynamicFields(models.Model):
'ttype': 'many2one',
'relation': 'res.currency',
'is_dynamic_field': True
+
})
self.env['ir.model.fields'].sudo().create({
'name': self.name,
@@ -156,8 +215,8 @@ class DynamicFields(models.Model):
'is_dynamic_field': True
})
inherit_form_view_name = str(
- self.form_view_id.name) + ".inherit.dynamic.custom." + str(self.
- field_description) + ".field"
+ 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 = _(''
@@ -167,7 +226,7 @@ class DynamicFields(models.Model):
''
'') % (self.position_field_id.name,
self.position, self.name)
- if self.widget:
+ if self.widget_id:
arch_base = _(''
''
''
@@ -175,8 +234,8 @@ class DynamicFields(models.Model):
''
'') % (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_form_view_id = self.env['ir.ui.view'].sudo().create({
'name': inherit_form_view_name,
'type': 'form',
'model': self.model_id.model,
@@ -194,22 +253,23 @@ class DynamicFields(models.Model):
def action_create_to_tree_view(self):
"""Function to add field to tree view"""
if self.add_field_in_tree:
+ optional = "show" if self.is_visible_in_tree_view else "hide"
+ tree_view_arch_base = (_(f'''
+
+
+
+
+ '''))
inherit_tree_view_name = str(
self.tree_view_id.name) + ".inherit.dynamic.custom" + \
str(self.field_description) + ".field"
- self.tree_view_id = self.env['ir.ui.view'].sudo().create({
+ 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': _(
- ''
- ''
- ''''''
- ''''''
- ''''''
- '''''') % self.name,
+ 'arch_base': tree_view_arch_base,
'active': True})
return {
'type': 'ir.actions.client',
@@ -219,8 +279,8 @@ class DynamicFields(models.Model):
def unlink(self):
"""Super unlink function"""
if self.form_view_id:
- self.form_view_id.active = False
+ self.created_form_view_id.active = False
if self.tree_view_id:
- self.tree_view_id.active = False
+ self.created_tree_view_id.active = False
res = super(DynamicFields, self).unlink()
return res
diff --git a/all_in_one_dynamic_custom_fields/security/ir.model.access.csv b/all_in_one_dynamic_custom_fields/security/ir.model.access.csv
index 32e953a65..e8d222874 100755
--- a/all_in_one_dynamic_custom_fields/security/ir.model.access.csv
+++ b/all_in_one_dynamic_custom_fields/security/ir.model.access.csv
@@ -1,4 +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
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/1.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/1.png
new file mode 100644
index 000000000..4a2db22a8
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/1.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/2.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/2.png
new file mode 100644
index 000000000..9d70df317
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/2.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/3.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/3.png
new file mode 100644
index 000000000..004db3bc5
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/3.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/4.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/4.png
new file mode 100644
index 000000000..8ffad588b
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/4.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/5.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/5.png
new file mode 100644
index 000000000..0cd16a080
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/5.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/6.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/6.png
new file mode 100644
index 000000000..184e14573
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/6.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/7.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/7.png
new file mode 100644
index 000000000..a9361fd41
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/7.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/8.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/8.png
new file mode 100644
index 000000000..5e58c4251
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/8.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/9.png b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/9.png
new file mode 100644
index 000000000..05601c6e3
Binary files /dev/null and b/all_in_one_dynamic_custom_fields/static/description/assets/screenshots/9.png differ
diff --git a/all_in_one_dynamic_custom_fields/static/description/index.html b/all_in_one_dynamic_custom_fields/static/description/index.html
index 5ccc18a95..6f4156627 100755
--- a/all_in_one_dynamic_custom_fields/static/description/index.html
+++ b/all_in_one_dynamic_custom_fields/static/description/index.html
@@ -222,7 +222,7 @@
height="auto">
-
@@ -240,12 +240,12 @@
create a custom field.
-
-
@@ -262,7 +262,7 @@
Choose the field type.
-
@@ -281,17 +281,17 @@
module List/Tree view.
-
-
-
@@ -309,7 +309,7 @@
order form view.
-
@@ -327,7 +327,7 @@
order tree view.
-
diff --git a/all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml b/all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml
index 141b2551e..aad1bee15 100755
--- a/all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml
+++ b/all_in_one_dynamic_custom_fields/views/dynamic_fields_views.xml
@@ -51,7 +51,7 @@
required="field_type in ('many2one','many2many')"
readonly="field_type not in ('many2one','many2many') or status != 'draft'"
invisible="field_type not in ('many2one','many2many')"/>
-
+
+
+
+