You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
6.2 KiB
149 lines
6.2 KiB
# -*- coding: utf-8 -*-
|
|
###############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
|
|
# Author: Aysha Shalin (odoo@cybrosys.com )
|
|
#
|
|
# You can modify it under the terms of the GNU AFFERO
|
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC
|
|
# LICENSE (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
###############################################################################
|
|
from psycopg2 import sql
|
|
from odoo import api
|
|
from odoo.exceptions import UserError
|
|
from odoo.fields import Selection
|
|
from odoo.tools.translate import _
|
|
from odoo.addons.base.models.ir_model import IrModelFields
|
|
from odoo.addons.base.models.ir_model import IrModelSelection
|
|
|
|
|
|
def convert_to_cache(self, value, record, validate=True):
|
|
""" Monkey patched the function convert_to_cache and added condition to check
|
|
value in by search get all selections of that field. """
|
|
if not validate:
|
|
return value or None
|
|
if value and self.column_type[0] == 'int4':
|
|
value = int(value)
|
|
if value in self.get_values(record.env):
|
|
return value
|
|
elif not value:
|
|
return None
|
|
if self.type == 'selection':
|
|
field_id = record.env['ir.model.fields'].search(
|
|
[('model', '=', str(self).rsplit(".", 1)[0]),
|
|
('name', '=', str(self).rsplit(".", 1)[1])]).id
|
|
value_list = [i.value for i in
|
|
record.env['ir.model.fields.selection'].search(
|
|
[('field_id', '=', field_id)])]
|
|
if value in value_list:
|
|
return value
|
|
raise UserError(
|
|
_("User Error: Custom selection requires Python code implementation, "
|
|
"preferably through a custom addon to provide the desired "
|
|
"functionalities."))
|
|
|
|
Selection.convert_to_cache = convert_to_cache
|
|
|
|
def write(self, vals):
|
|
""" Monkey Patching the write function to remove raise error for editing in
|
|
base fields. """
|
|
# If set, *one* column can be renamed here
|
|
column_rename = None
|
|
patched_models = set()
|
|
if vals and self:
|
|
for item in self:
|
|
if vals.get('model_id', item.model_id.id) != item.model_id.id:
|
|
raise UserError(
|
|
_("Changing the model of a field is forbidden!"))
|
|
if vals.get('ttype', item.ttype) != item.ttype:
|
|
raise UserError(
|
|
_("Changing the type of a field is not yet supported. "
|
|
"Please drop it and create it again!"))
|
|
obj = self.pool.get(item.model)
|
|
field = getattr(obj, '_fields', {}).get(item.name)
|
|
if vals.get('name', item.name) != item.name:
|
|
# We need to rename the field
|
|
item._prepare_update()
|
|
if item.ttype in ('one2many', 'many2many', 'binary'):
|
|
# Those field names are not explicit in the database!
|
|
return True
|
|
else:
|
|
if column_rename:
|
|
raise UserError(
|
|
_('Can only rename one field at a time!'))
|
|
column_rename = (
|
|
obj._table, item.name, vals['name'], item.index,
|
|
item.store)
|
|
# We don't check the 'state', because it might come from the context
|
|
# (thus be set for multiple fields) and will be ignored anyway.
|
|
if obj is not None and field is not None:
|
|
patched_models.add(obj._name)
|
|
# These shall never be written (modified)
|
|
for column_name in ('model_id', 'model', 'state'):
|
|
if column_name in vals:
|
|
del vals[column_name]
|
|
res = super(IrModelFields, self).write(vals)
|
|
self.env.flush_all()
|
|
if column_rename:
|
|
# Rename column in database, and its corresponding index if present
|
|
table, oldname, newname, index, stored = column_rename
|
|
if stored:
|
|
self._cr.execute(
|
|
sql.SQL('ALTER TABLE {} RENAME COLUMN {} TO {}').format(
|
|
sql.Identifier(table),
|
|
sql.Identifier(oldname),
|
|
sql.Identifier(newname)))
|
|
if index:
|
|
self._cr.execute(
|
|
sql.SQL('ALTER INDEX {} RENAME TO {}').format(
|
|
sql.Identifier(f'{table}_{oldname}_index'),
|
|
sql.Identifier(f'{table}_{newname}_index'), ))
|
|
if column_rename or patched_models:
|
|
# Setup models, this will reload all manual fields in registry
|
|
self.env.flush_all()
|
|
self.pool.setup_models(self._cr)
|
|
if patched_models:
|
|
# Update the database schema of the models to patch
|
|
models = self.pool.descendants(patched_models, '_inherits')
|
|
self.pool.init_models(self._cr, models, dict(
|
|
self._context, update_custom_fields=True))
|
|
return res
|
|
|
|
IrModelFields.write = write
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
""" Monkey Patching the create function to remove raise error for editing in
|
|
base fields. """
|
|
field_ids = {vals['field_id'] for vals in vals_list}
|
|
field_names = set()
|
|
for field in self.env['ir.model.fields'].browse(field_ids):
|
|
field_names.add((field.model, field.name))
|
|
recs = super(IrModelSelection, self).create(vals_list)
|
|
if any(model in self.pool and name in self.pool[model]._fields
|
|
for model, name in field_names):
|
|
# Setup models; this re-initializes model in registry
|
|
self.env.flush_all()
|
|
self.pool.setup_models(self._cr)
|
|
return recs
|
|
|
|
IrModelSelection.create = create
|
|
|
|
@api.ondelete(at_uninstall=False)
|
|
def _unlink_if_manual(self):
|
|
""" Monkey Patching the _unlink_if_manual function to remove raise error for
|
|
editing in base fields. """
|
|
return True
|
|
|
|
IrModelSelection._unlink_if_manual = _unlink_if_manual
|
|
|