Jika kita mendapatkan error access right odoo yg mungkin tidak tahu detail kesalahan itu dibaris kode yg mana, kita bisa traceback lebih detail. Kita perlu edit model core nya odoo.
Ref https://www.odoo.com/forum/help-1/how-to-debug-access-permissions-121603
Berikut contoh pesan errornya:
Due to security restrictions, you are not allowed to access 'Sale Order' (sale.order) records.
Records: New (id=NewId_0x7f0cf9b06828)
User: ADMINISTRATOR (id=2)
This restriction is due to the following rules:
Contact your administrator to request access if necessary.
Contoh untuk case read error di atas, kita bs tambahkan traceback sbb:
# odoo/models.py
# ...
import traceback
# ...
def _read(self, fields):
""" Read the given fields of the records in ``self`` from the database,
and store them in cache. Access errors are also stored in cache.
Skip fields that are not stored.
:param field_names: list of column names of model ``self``; all those
fields are guaranteed to be read
:param inherited_field_names: list of column names from parent
models; some of those fields may not be read
"""
if not self:
return
self.check_access_rights('read')
# if a read() follows a write(), we must flush updates, as read() will
# fetch from database and overwrites the cache (`test_update_with_id`)
self.flush(fields, self)
field_names = []
inherited_field_names = []
for name in fields:
field = self._fields.get(name)
if field:
if field.store:
field_names.append(name)
elif field.base_field.store:
inherited_field_names.append(name)
else:
_logger.warning("%s.read() with unknown field '%s'", self._name, name)
# determine the fields that are stored as columns in tables; ignore 'id'
fields_pre = [
field
for field in (self._fields[name] for name in field_names + inherited_field_names)
if field.name != 'id'
if field.base_field.store and field.base_field.column_type
if not (field.inherited and callable(field.base_field.translate))
]
if fields_pre:
env = self.env
cr, user, context, su = env.args
# make a query object for selecting ids, and apply security rules to it
query = Query(self.env.cr, self._table, self._table_query)
self._apply_ir_rules(query, 'read')
# the query may involve several tables: we need fully-qualified names
def qualify(field):
col = field.name
res = self._inherits_join_calc(self._table, field.name, query)
if field.type == 'binary' and (context.get('bin_size') or context.get('bin_size_' + col)):
# PG 9.2 introduces conflicting pg_size_pretty(numeric) -> need ::cast
res = 'pg_size_pretty(length(%s)::bigint)' % res
return '%s as "%s"' % (res, col)
# selected fields are: 'id' followed by fields_pre
qual_names = [qualify(name) for name in [self._fields['id']] + fields_pre]
# determine the actual query to execute (last parameter is added below)
query.add_where('"%s".id IN %%s' % self._table)
query_str, params = query.select(*qual_names)
result = []
for sub_ids in cr.split_for_in_conditions(self.ids):
cr.execute(query_str, params + [sub_ids])
result += cr.fetchall()
else:
self.check_access_rule('read')
result = [(id_,) for id_ in self.ids]
fetched = self.browse()
if result:
cols = zip(*result)
ids = next(cols)
fetched = self.browse(ids)
for field in fields_pre:
values = next(cols)
if context.get('lang') and not field.inherited and callable(field.translate):
translate = field.get_trans_func(fetched)
values = list(values)
for index in range(len(ids)):
values[index] = translate(ids[index], values[index])
# store values in cache
self.env.cache.update(fetched, field, values)
# determine the fields that must be processed now;
# for the sake of simplicity, we ignore inherited fields
for name in field_names:
field = self._fields[name]
if not field.column_type:
field.read(fetched)
if field.deprecated:
_logger.warning('Field %s is deprecated: %s', field, field.deprecated)
# possibly raise exception for the records that could not be read
missing = self - fetched
if missing:
extras = fetched - self
if extras:
raise AccessError(
_("Database fetch misses ids ({}) and has extra ids ({}), may be caused by a type incoherence in a previous request").format(
missing._ids, extras._ids,
))
# mark non-existing records in missing
forbidden = missing.exists()
if forbidden:
# debug by arisnew
_logger.info('======start here==========')
for xline in traceback.format_stack():
_logger.info(xline.strip())
_logger.info('======end here==========')
raise self.env['ir.rule']._make_access_error('read', forbidden)Jika kita cek log:
// ...
web_1 | 2024-07-03 06:20:01,507 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/fields.py", line 1157, in recompute
web_1 | self.compute_value(record)
web_1 | 2024-07-03 06:20:01,507 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/fields.py", line 1177, in compute_value
web_1 | records._compute_field_value(self)
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/addons/sale/models/sale.py", line 516, in _compute_field_value
web_1 | super()._compute_field_value(field)
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/addons/mail/models/mail_thread.py", line 410, in _compute_field_value
web_1 | return super()._compute_field_value(field)
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/models.py", line 4074, in _compute_field_value
web_1 | getattr(self, field.compute)()
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/mnt/extra-addons/ckwi-addons/jidoka_sale/models/sale.py", line 90, in _get_document_type
web_1 | self.write({'document_type': 'marketing_quotation'})
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/mnt/extra-addons/ckwi-addons/auditlog/models/rule.py", line 395, in write_full
web_1 | .read(fields_list)
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/models.py", line 3023, in read
web_1 | self._read(stored_fields)
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.models: File "/usr/lib/python3/dist-packages/odoo/models.py", line 3187, in _read
web_1 | for xline in traceback.format_stack():
web_1 | 2024-07-03 06:20:01,508 1 INFO DBODOOCKWI odoo.addons.base.models.ir_rule: Access Denied by record rules for operation: read on record ids: [], uid: 2, model: sale.order
web_1 | 2024-07-03 06:20:01,512 1 WARNING DBODOOCKWI odoo.http: Due to security restrictions, you are not allowed to access 'Sale Order' (sale.order) records.
web_1 |
web_1 | Records: New (id=NewId_0x7f0cf9b06828)
web_1 | User: ADMINISTRATOR (id=2)
web_1 |
web_1 | This restriction is due to the following rules:
web_1 |
web_1 |
web_1 | Contact your administrator to request access if necessary.
// ...
Kita dapat mengetahui eksekusi yg bermasalah dimana, misal contoh di atas pada method _get_document_type.
Semoga bermanfaat.