| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/server-ux |
| GIT | |
| GIT | https://github.com/OCA/server-ux.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/server-ux/tree/18.0/chained_swapper |
| VERSION | |
| VERSION | 1.0.0 |
| CATEGORY | |
| CATEGORY | Tools |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Tecnativa, Odoo Community Association (OCA) |
| MAINTAINERS | |
| MAINTAINERS | Tecnativa, Odoo Community Association (OCA) |
| COMMITTERS | |
| COMMITTERS | Pedro M. Baeza, Weblate, OCA-git-bot, oca-ci, juancarlosonate-tecnativa |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/server-ux |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 19:30:16 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - base |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | This module allows to swap the value of a field and propagate it in a chained way to linked records. Example: changing the delivery address in a confirmed sales order, it should be changed in its delivery orders as well. It also allows to apply constraints for not allowing to do that change according rules, so the business logic is not broken. Example: Don't allow to change the delivery address if the delivery order is validated. This module requires some technical knowledge for setting the chained swap and the constraint, as it's defined through technical names and Python code. **WARNING**: Use this module with care, as it can screw up database consistency if swaps are not properly designed . |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
chained_swapper_constraint_view_form |
chained.swapper.constraint.form | chained.swapper.constraint | form | New |
chained_swapper_constraint_view_tree |
chained.swapper.constraint.tree | chained.swapper.constraint | list | New |
chained_swapper_sub_field_view_tree |
chained.swapper.sub.field.tree | chained.swapper.sub.field | list | New |
chained_swapper_view_form |
chained.swapper.form | chained.swapper | form | New |
chained_swapper_view_tree |
chained.swapper.tree | chained.swapper | list | New |
chained_swapper_wizard_view_form |
chained.swapper.wizard.form | chained.swapper.wizard | form | New |
No HTTP endpoints found for this module.
allowed_field_ids_domain
Binary
compute='_compute_allowed_field_ids_domain'
constraint_ids
One2many → chained.swapper.constraint
comodel_name='chained.swapper.constraint'
inverse_name='chained_swapper_id'
string='Constraints'
field_id
Many2one → ir.model.fields
comodel_name='ir.model.fields'
domain='allowed_field_ids_domain'
ondelete='cascade'
required=True
group_ids
Many2many → res.groups
column1='mass_id'
column2='group_id'
comodel_name='res.groups'
relation='mass_group_rel'
string='Groups'
model_id
Many2one → ir.model
comodel_name='ir.model'
help='Model is used for Selecting Field. This is editable until Contextual Action is not created.'
ondelete='cascade'
required=True
name
Char
index=1
required=True
translate=True
ref_ir_act_window_id
Many2one → ir.actions.act_window
comodel_name='ir.actions.act_window'
help='Action to make this template available on records of the related document model.'
readonly=True
string='Action'
sub_field_ids
One2many → chained.swapper.sub.field
comodel_name='chained.swapper.sub.field'
inverse_name='chained_swapper_id'
string='Sub-fields'
add_action(self)
unlink(self)
unlink_action(self)
write(self, vals)
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
expression
Text
default='True'
help="Boolean python expression. You can use the keyword 'records' as the records selected to execute the contextual action. Ex.: bool(records.mapped('parent_id'))"
required=True
string='Constraint expression'
name
Char
required=True
translate=True
No public methods.
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
model_name
Char
related='chained_swapper_id.model_id.model'
string='Model Name'
sub_field_chain
Char
help="You can specify here a field of related fields as dotted names. Ex.: 'child_ids.lang'."
required=True
No public methods.
company_id
Many2one → res.company
default=<expr>
string='Company'
args: 'res.company'
change_action(self)
create(self, vals_list)
default_get(self, fields)
fields_get(self, allfields=None, attributes=None)
get_view(self, view_id=None, view_type='form', **options)
get_views(self, views, options=None)
onchange(self, values, field_names, fields_spec)
post_chained_swap(self, model, field_name, original_values, new_value)
read(self, fields, load='_classic_read')
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/server-ux |
| GIT | |
| GIT | https://github.com/OCA/server-ux.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/server-ux/tree/15.0/chained_swapper |
| VERSION | |
| VERSION | 1.0.4 |
| CATEGORY | |
| CATEGORY | Tools |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Tecnativa, Odoo Community Association (OCA) |
| MAINTAINERS | |
| MAINTAINERS | Tecnativa, Odoo Community Association (OCA) |
| COMMITTERS | |
| COMMITTERS | Pedro M. Baeza, Enric Tobella, Víctor Martínez, Weblate, OCA-git-bot, oca-ci, Cesar Andres Sanchez, josep-tecnativa |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/server-ux |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:46:39 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - base |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
chained_swapper_constraint_view_form |
chained.swapper.constraint.form | chained.swapper.constraint | form | New |
chained_swapper_constraint_view_tree |
chained.swapper.constraint.tree | chained.swapper.constraint | tree | New |
chained_swapper_sub_field_view_tree |
chained.swapper.sub.field.tree | chained.swapper.sub.field | tree | New |
chained_swapper_view_form |
chained.swapper.form | chained.swapper | form | New |
chained_swapper_view_tree |
chained.swapper.tree | chained.swapper | tree | New |
chained_swapper_wizard_view_form |
chained.swapper.wizard.form | chained.swapper.wizard | form | New |
No HTTP endpoints found for this module.
allowed_field_ids
Many2many → ir.model.fields
comodel_name='ir.model.fields'
compute='_compute_allowed_field_ids'
constraint_ids
One2many → chained.swapper.constraint
comodel_name='chained.swapper.constraint'
inverse_name='chained_swapper_id'
string='Constraints'
field_id
Many2one → ir.model.fields
comodel_name='ir.model.fields'
domain="[('id', 'in', allowed_field_ids)]"
ondelete='cascade'
required=True
group_ids
Many2many → res.groups
column1='mass_id'
column2='group_id'
comodel_name='res.groups'
relation='mass_group_rel'
string='Groups'
model_id
Many2one → ir.model
comodel_name='ir.model'
help='Model is used for Selecting Field. This is editable until Contextual Action is not created.'
ondelete='cascade'
required=True
name
Char
index=1
required=True
translate=True
ref_ir_act_window_id
Many2one → ir.actions.act_window
comodel_name='ir.actions.act_window'
help='Action to make this template available on records of the related document model.'
readonly=True
string='Action'
sub_field_ids
One2many → chained.swapper.sub.field
comodel_name='chained.swapper.sub.field'
inverse_name='chained_swapper_id'
string='Sub-fields'
add_action(self)
unlink(self)
unlink_action(self)
write(self, vals)
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
expression
Text
default='True'
help="Boolean python expression. You can use the keyword 'records' as the records selected to execute the contextual action. Ex.: bool(records.mapped('parent_id'))"
required=True
string='Constraint expression'
name
Char
required=True
translate=True
No public methods.
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
sub_field_chain
Char
help="You can specify here a field of related fields as dotted names. Ex.: 'child_ids.lang'."
required=True
No public methods.
No new fields.
Public methods (6)change_action(self)
create(self, vals)
default_get(self, fields)
fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False)
post_chained_swap(self, model, field_name, original_values, new_value)
read(self, fields, load='_classic_read')
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/server-ux |
| GIT | |
| GIT | https://github.com/OCA/server-ux.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/server-ux/tree/14.0/chained_swapper |
| VERSION | |
| VERSION | 1.0.2 |
| CATEGORY | |
| CATEGORY | Tools |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Tecnativa, Odoo Community Association (OCA) |
| MAINTAINERS | |
| MAINTAINERS | Tecnativa, Odoo Community Association (OCA) |
| COMMITTERS | |
| COMMITTERS | Enric Tobella, OCA Transbot, oca-travis, Weblate, OCA-git-bot, Enrique Martín, fshah, schhatbar |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/server-ux |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:41:07 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - base |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
chained_swapper_constraint_view_form |
chained.swapper.constraint.form | chained.swapper.constraint | form | New |
chained_swapper_constraint_view_tree |
chained.swapper.constraint.tree | chained.swapper.constraint | tree | New |
chained_swapper_sub_field_view_tree |
chained.swapper.sub.field.tree | chained.swapper.sub.field | tree | New |
chained_swapper_view_form |
chained.swapper.form | chained.swapper | form | New |
chained_swapper_view_tree |
chained.swapper.tree | chained.swapper | tree | New |
chained_swapper_wizard_view_form |
chained.swapper.wizard.form | chained.swapper.wizard | form | New |
No HTTP endpoints found for this module.
allowed_field_ids
Many2many → ir.model.fields
comodel_name='ir.model.fields'
compute='_compute_allowed_field_ids'
constraint_ids
One2many → chained.swapper.constraint
comodel_name='chained.swapper.constraint'
inverse_name='chained_swapper_id'
string='Constraints'
field_id
Many2one → ir.model.fields
comodel_name='ir.model.fields'
domain="[('id', 'in', allowed_field_ids)]"
ondelete='cascade'
required=True
group_ids
Many2many → res.groups
column1='mass_id'
column2='group_id'
comodel_name='res.groups'
relation='mass_group_rel'
string='Groups'
model_id
Many2one → ir.model
comodel_name='ir.model'
help='Model is used for Selecting Field. This is editable until Contextual Action is not created.'
ondelete='cascade'
required=True
name
Char
index=1
required=True
translate=True
ref_ir_act_window_id
Many2one → ir.actions.act_window
comodel_name='ir.actions.act_window'
help='Action to make this template available on records of the related document model.'
readonly=True
string='Action'
sub_field_ids
One2many → chained.swapper.sub.field
comodel_name='chained.swapper.sub.field'
inverse_name='chained_swapper_id'
string='Sub-fields'
add_action(self)
unlink(self)
unlink_action(self)
write(self, vals)
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
expression
Text
default='True'
help="Boolean python expression. You can use the keyword 'records' as the records selected to execute the contextual action. Ex.: bool(records.mapped('parent_id'))"
required=True
string='Constraint expression'
name
Char
required=True
translate=True
No public methods.
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
sub_field_chain
Char
help="You can specify here a field of related fields as dotted names. Ex.: 'child_ids.lang'."
required=True
No public methods.
No new fields.
Public methods (6)change_action(self)
create(self, vals)
default_get(self, fields)
fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False)
post_chained_swap(self, model, field_name, original_values, new_value)
read(self, fields, load='_classic_read')
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/server-ux |
| GIT | |
| GIT | https://github.com/OCA/server-ux.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/server-ux/tree/13.0/chained_swapper |
| VERSION | |
| VERSION | 1.0.1 |
| CATEGORY | |
| CATEGORY | Tools |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Tecnativa, Odoo Community Association (OCA) |
| MAINTAINERS | |
| MAINTAINERS | Tecnativa, Odoo Community Association (OCA) |
| COMMITTERS | |
| COMMITTERS | Pedro M. Baeza, Ernesto Tejeda, oca-travis, Weblate, OCA-git-bot |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/server-ux |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:34:17 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - base |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
chained_swapper_constraint_view_form |
chained.swapper.constraint.form | chained.swapper.constraint | form | New |
chained_swapper_constraint_view_tree |
chained.swapper.constraint.tree | chained.swapper.constraint | tree | New |
chained_swapper_sub_field_view_tree |
chained.swapper.sub.field.tree | chained.swapper.sub.field | tree | New |
chained_swapper_view_form |
chained.swapper.form | chained.swapper | form | New |
chained_swapper_view_tree |
chained.swapper.tree | chained.swapper | tree | New |
chained_swapper_wizard_view_form |
chained.swapper.wizard.form | chained.swapper.wizard | form | New |
No HTTP endpoints found for this module.
allowed_field_ids
Many2many → ir.model.fields
comodel_name='ir.model.fields'
compute='_compute_allowed_field_ids'
constraint_ids
One2many → chained.swapper.constraint
comodel_name='chained.swapper.constraint'
inverse_name='chained_swapper_id'
string='Constraints'
field_id
Many2one → ir.model.fields
comodel_name='ir.model.fields'
domain="[('id', 'in', allowed_field_ids)]"
required=True
group_ids
Many2many → res.groups
column1='mass_id'
column2='group_id'
comodel_name='res.groups'
relation='mass_group_rel'
string='Groups'
model_id
Many2one → ir.model
comodel_name='ir.model'
help='Model is used for Selecting Field. This is editable until Contextual Action is not created.'
required=True
name
Char
index=1
required=True
translate=True
ref_ir_act_window_id
Many2one → ir.actions.act_window
comodel_name='ir.actions.act_window'
help='Action to make this template available on records of the related document model.'
readonly=True
string='Action'
sub_field_ids
One2many → chained.swapper.sub.field
comodel_name='chained.swapper.sub.field'
inverse_name='chained_swapper_id'
string='Sub-fields'
add_action(self)
unlink(self)
unlink_action(self)
write(self, vals)
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
expression
Text
default='True'
help="Boolean python expression. You can use the keyword 'records' as the records selected to execute the contextual action. Ex.: bool(records.mapped('parent_id'))"
required=True
string='Constraint expression'
name
Char
required=True
translate=True
No public methods.
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
sub_field_chain
Char
help="You can specify here a field of related fields as dotted names. Ex.: 'child_ids.lang'."
required=True
No public methods.
No new fields.
Public methods (6)change_action(self)
create(self, vals)
default_get(self, fields)
fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False)
post_chained_swap(self, model, field_name, original_values, new_value)
read(self, fields, load='_classic_read')
| REPOSITORY | |
|---|---|
| REPOSITORY | OCA/server-ux |
| GIT | |
| GIT | https://github.com/OCA/server-ux.git |
| GIT FOLDER | |
| GIT FOLDER | https://github.com/OCA/server-ux/tree/12.0/chained_swapper |
| VERSION | |
| VERSION | 1.0.1 |
| CATEGORY | |
| CATEGORY | Tools |
| LICENSE | |
| LICENSE | AGPL-3 |
| APPLICATION | |
| APPLICATION | No |
| AUTO-INSTALLABLE | |
| AUTO-INSTALLABLE | No |
| AUTHORS | |
| AUTHORS | Tecnativa, Odoo Community Association (OCA) |
| MAINTAINERS | |
| MAINTAINERS | Tecnativa, Odoo Community Association (OCA) |
| COMMITTERS | |
| COMMITTERS | OCA Transbot, sergio-teruel, Ernesto Tejeda, oca-travis, OCA-git-bot |
| WEBSITE | |
| WEBSITE | https://github.com/OCA/server-ux |
| LAST TRACKING UPDATE | |
| LAST TRACKING UPDATE | 2026-07-06 00:29:22 |
| ODOO DEPENDENCIES | |
| ODOO DEPENDENCIES |
odoo/odoo: - base |
| PYTHON DEPENDENCIES | |
| PYTHON DEPENDENCIES | Not have |
| SYSTEM DEPENDENCIES | |
| SYSTEM DEPENDENCIES | Not have |
| DESCRIPTION | |
| DESCRIPTION | |
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
chained_swapper_constraint_view_form |
chained.swapper.constraint.form | chained.swapper.constraint | form | New |
chained_swapper_constraint_view_tree |
chained.swapper.constraint.tree | chained.swapper.constraint | tree | New |
chained_swapper_sub_field_view_tree |
chained.swapper.sub.field.tree | chained.swapper.sub.field | tree | New |
chained_swapper_view_form |
chained.swapper.form | chained.swapper | form | New |
chained_swapper_view_tree |
chained.swapper.tree | chained.swapper | tree | New |
chained_swapper_wizard_view_form |
chained.swapper.wizard.form | chained.swapper.wizard | form | New |
No HTTP endpoints found for this module.
allowed_field_ids
Many2many → ir.model.fields
comodel_name='ir.model.fields'
compute='_compute_allowed_field_ids'
constraint_ids
One2many → chained.swapper.constraint
comodel_name='chained.swapper.constraint'
inverse_name='chained_swapper_id'
string='Constraints'
field_id
Many2one → ir.model.fields
comodel_name='ir.model.fields'
domain="[('id', 'in', allowed_field_ids)]"
required=True
group_ids
Many2many → res.groups
column1='mass_id'
column2='group_id'
comodel_name='res.groups'
relation='mass_group_rel'
string='Groups'
model_id
Many2one → ir.model
comodel_name='ir.model'
help='Model is used for Selecting Field. This is editable until Contextual Action is not created.'
required=True
name
Char
index=1
required=True
translate=True
ref_ir_act_window_id
Many2one → ir.actions.act_window
comodel_name='ir.actions.act_window'
help='Action to make this template available on records of the related document model.'
readonly=True
string='Action'
sub_field_ids
One2many → chained.swapper.sub.field
comodel_name='chained.swapper.sub.field'
inverse_name='chained_swapper_id'
string='Sub-fields'
add_action(self)
unlink(self)
unlink_action(self)
write(self, vals)
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
expression
Text
default='True'
help="Boolean python expression. You can use the keyword 'records' as the records selected to execute the contextual action. Ex.: bool(records.mapped('parent_id'))"
required=True
string='Constraint expression'
name
Char
required=True
translate=True
No public methods.
chained_swapper_id
Many2one → chained.swapper
comodel_name='chained.swapper'
ondelete='cascade'
sub_field_chain
Char
help="You can specify here a field of related fields as dotted names. Ex.: 'child_ids.lang'."
required=True
No public methods.
No new fields.
Public methods (6)change_action(self)
create(self, vals)
default_get(self, fields)
fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False)
post_chained_swap(self, model, field_name, original_values, new_value)
read(self, fields, load='_classic_read')
| STATUS | |
|---|---|
| STATUS | Open migration PR - not merged yet for this version |
| REPOSITORY | |
| REPOSITORY | OCA/server-ux |
| PULL REQUEST | |
| PULL REQUEST | [19.0][MIG] chained_swapper: Migration to 19.0 (#1297) |