В odoo 17 на уровне кода Python появляется ошибка: при попытке запросить связанный тип поля Many2one это поле распознается как False или пустое, хотя оно запрашивается на уровне базы данных SQL, это же показывает, что поле сохраняется на уровне базы данных, но при попытке запроса на уровне ORM odoo оно отображается как пустое или False, эта ошибка также вызывает ошибку доступа, где указывается, что пользователь не имеет к нему доступа, но эти разрешения уже размещены у соответствующего пользователя, на уровне графического интерфейса поле отображается как заполненное, пользователь может ввести его нормально из графического интерфейса, код проверен, а как поле объявляется и его нет имеют ограничения безопасности, ниже я показываю код, выполняющий этот процесс:
from odoo import SUPERUSER_ID, fields, models, api
import random
import string
import logging
_logger = logging.getLogger(__name__)
class CreateFinancialReport(models.TransientModel):
_name = "create.financial.report"
_description = "Create Financial Report"
name = fields.Char()
company_id = fields.Many2one("res.company", default=lambda self: self.env.company)
type = fields.Selection(
[("balance", "Balance"), ("profit_loss", "Profit and Loss"), ("all", "All")]
)
def create_financial_report(self):
self.env['ir.rule'].clear_caches()
financial_report = self.with_user(SUPERUSER_ID).env["account.report"].create(
{
"name": self.name + " / " + self.company_id.name,
"filter_date_range": True,
"filter_period_comparison": True,
"filter_growth_comparison": True,
"filter_unfold_all": True,
"filter_journals": True,
"filter_analytic": True,
"filter_multi_company": 'selector',
}
)
financial_report.column_ids = [(0, 0, {
"name": "Balance",
"expression_label": "balance",
})]
sql = """
select id
from account_account
where company_id= %s
"""
if self.type == "balance":
sql += " and code between '1' and '399999999999' "
elif self.type == "profit_loss":
sql += " and code between '4' and '699999999999' "
sql += " order by code , company_id "
self.with_user(SUPERUSER_ID)._cr.execute(sql, [self.company_id.id])
values = self.with_user(SUPERUSER_ID)._cr.fetchall()
self_line = self.with_user(SUPERUSER_ID).env["account.report.line"]
msg = "Values: " + str(values)
_logger.info(msg)
for value in values:
_logger.info("Value: " + str(value))
account = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", value[0]),
('company_id', '=', self.company_id.id)])
account_parent = account.sudo().parent_id
account_parent = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", account_parent.id),
('company_id', '=', self.company_id.id)])
_logger.info("Account: " + str(account))
if account:
if account.name and account.code:
name = account.code + " " + account.name
elif account.name:
name = account.name
else:
name = account.code
if account.parent_id:
_logger.info("Whit child lines IDS")
_logger.info("Account Parent: " + str(account_parent))
old_line = self_line.with_user(SUPERUSER_ID).search(
[
("code", "=", account_parent.code),
("report_id", "=", financial_report.id),
],
limit=1,
)
line = self_line.with_user(SUPERUSER_ID).create(
{
"name": name,
"report_id": financial_report.id,
"parent_id": old_line.id,
"code": account.code,
"hide_if_zero": True,
}
)
if account and account.account_type in (
'income',
'liability_current',
'liability_credit_card',
'liability_non_current',
'equity_unaffected',
'income_other',
'equity',
'off_balance',
):
line.with_user(SUPERUSER_ID).expression_ids = [(
0, 0, {
'label': 'balance',
'engine': 'aggregation',
'formula': '-sum',
}
)]
else:
line.expression_ids = [(
0, 0, {
'label': 'balance',
'engine': 'aggregation',
'formula': 'sum',
}
)]
else:
_logger.info("Parent ID is None")
self_line.with_user(SUPERUSER_ID).create(
{
"report_id": financial_report.id,
"name": name,
"code": account.code,
"hide_if_zero": True,
}
)
level = 1
for line in financial_report.line_ids:
_logger.info("Line ID: " + str(line.id))
self.with_user(SUPERUSER_ID).set_data_to_line(line, level)
def set_data_to_line(self, line, level):
line.hierarchy_level = level
level += 1
_logger.info("Line with children IDS: " + str(line.children_ids))
if line.children_ids:
sql_sum = """
select string_agg(CONCAT(code, '.balance'), '+')
from account_report_line
where parent_id = %s
"""
self._cr.execute(sql_sum, [line.id])
value_sum = self._cr.fetchall()
report_expression = self.env['account.report.expression'].search([('report_line_id', '=', line.id)])
for expression in report_expression:
expression.with_user(SUPERUSER_ID).write({
'engine': 'aggregation',
'formula': value_sum[0][0],
'blank_if_zero': True,
})
for child in line.children_ids:
self.set_data_to_line(child, level)
line.with_user(SUPERUSER_ID).groupby = "account_id"
else:
if line.parent_id.code:
report_expression = self.env['account.report.expression'].search(
[('report_line_id', '=', line.id)])
for expression in report_expression:
expression.with_user(SUPERUSER_ID).write({
'engine': 'domain',
'formula': "[('account_id.code', '=', " + "'" + line.code + "'" + ")]",
'blank_if_zero': True,
'subformula': 'sum',
})
line.with_user(SUPERUSER_ID).groupby = "account_id"
В случае if account.parent_id код вводит if, указывая, что поле заполнено, но при попытке выполнить запрос для получения
account_parent = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", account.parent_id.id) ,
('company_id', '=', self.company_id.id)])
Это возвращает пустое значение и не позволяет коду продолжать нормально работать. Бывает также, что при попытке ввести определенное поле, например account_parent.code или account_parent.name, возникает ошибка доступа, как если бы пользователю были назначены разрешения. Разрешения и правила регистрации уже проверены и размещены правильно.
Что требуется, так это иметь доступ к различным полям этой модели, чтобы иметь возможность генерировать финансовые отчеты с их собственные формулы?
В odoo 17 на уровне кода Python появляется ошибка: при попытке запросить связанный тип поля Many2one это поле распознается как False или пустое, хотя оно запрашивается на уровне базы данных SQL, это же показывает, что поле сохраняется на уровне базы данных, но при попытке запроса на уровне ORM odoo оно отображается как пустое или False, эта ошибка также вызывает ошибку доступа, где указывается, что пользователь не имеет к нему доступа, но эти разрешения уже размещены у соответствующего пользователя, на уровне графического интерфейса поле отображается как заполненное, пользователь может ввести его нормально из графического интерфейса, код проверен, а как поле объявляется и его нет имеют ограничения безопасности, ниже я показываю код, выполняющий этот процесс: [code]from odoo import SUPERUSER_ID, fields, models, api import random import string import logging
_logger = logging.getLogger(__name__)
class CreateFinancialReport(models.TransientModel): _name = "create.financial.report" _description = "Create Financial Report"
name = fields.Char() company_id = fields.Many2one("res.company", default=lambda self: self.env.company) type = fields.Selection( [("balance", "Balance"), ("profit_loss", "Profit and Loss"), ("all", "All")] )
sql = """ select id from account_account where company_id= %s """
if self.type == "balance": sql += " and code between '1' and '399999999999' " elif self.type == "profit_loss": sql += " and code between '4' and '699999999999' "
sql += " order by code , company_id " self.with_user(SUPERUSER_ID)._cr.execute(sql, [self.company_id.id]) values = self.with_user(SUPERUSER_ID)._cr.fetchall() self_line = self.with_user(SUPERUSER_ID).env["account.report.line"] msg = "Values: " + str(values) _logger.info(msg) for value in values: _logger.info("Value: " + str(value)) account = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", value[0]), ('company_id', '=', self.company_id.id)]) account_parent = account.sudo().parent_id account_parent = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", account_parent.id), ('company_id', '=', self.company_id.id)]) _logger.info("Account: " + str(account)) if account: if account.name and account.code: name = account.code + " " + account.name elif account.name: name = account.name else: name = account.code if account.parent_id: _logger.info("Whit child lines IDS") _logger.info("Account Parent: " + str(account_parent)) old_line = self_line.with_user(SUPERUSER_ID).search( [ ("code", "=", account_parent.code), ("report_id", "=", financial_report.id), ], limit=1, ) line = self_line.with_user(SUPERUSER_ID).create( { "name": name, "report_id": financial_report.id, "parent_id": old_line.id, "code": account.code, "hide_if_zero": True, } ) if account and account.account_type in ( 'income', 'liability_current', 'liability_credit_card', 'liability_non_current', 'equity_unaffected', 'income_other', 'equity', 'off_balance', ): line.with_user(SUPERUSER_ID).expression_ids = [( 0, 0, { 'label': 'balance', 'engine': 'aggregation', 'formula': '-sum', } )] else: line.expression_ids = [( 0, 0, { 'label': 'balance', 'engine': 'aggregation', 'formula': 'sum', } )] else: _logger.info("Parent ID is None") self_line.with_user(SUPERUSER_ID).create( { "report_id": financial_report.id, "name": name, "code": account.code, "hide_if_zero": True, } ) level = 1 for line in financial_report.line_ids: _logger.info("Line ID: " + str(line.id)) self.with_user(SUPERUSER_ID).set_data_to_line(line, level)
def set_data_to_line(self, line, level): line.hierarchy_level = level level += 1 _logger.info("Line with children IDS: " + str(line.children_ids)) if line.children_ids: sql_sum = """ select string_agg(CONCAT(code, '.balance'), '+') from account_report_line where parent_id = %s """ self._cr.execute(sql_sum, [line.id]) value_sum = self._cr.fetchall() report_expression = self.env['account.report.expression'].search([('report_line_id', '=', line.id)]) for expression in report_expression: expression.with_user(SUPERUSER_ID).write({ 'engine': 'aggregation', 'formula': value_sum[0][0], 'blank_if_zero': True, }) for child in line.children_ids: self.set_data_to_line(child, level) line.with_user(SUPERUSER_ID).groupby = "account_id" else: if line.parent_id.code: report_expression = self.env['account.report.expression'].search( [('report_line_id', '=', line.id)]) for expression in report_expression: expression.with_user(SUPERUSER_ID).write({ 'engine': 'domain', 'formula': "[('account_id.code', '=', " + "'" + line.code + "'" + ")]", 'blank_if_zero': True, 'subformula': 'sum', }) line.with_user(SUPERUSER_ID).groupby = "account_id"
[/code] В случае if account.parent_id код вводит if, указывая, что поле заполнено, но при попытке выполнить запрос для получения account_parent = self.with_user(SUPERUSER_ID).with_company(self.company_id.id).env["account.account"].search([("id", "=", account.parent_id.id) , ('company_id', '=', self.company_id.id)]) Это возвращает пустое значение и не позволяет коду продолжать нормально работать. Бывает также, что при попытке ввести определенное поле, например account_parent.code или account_parent.name, возникает ошибка доступа, как если бы пользователю были назначены разрешения. Разрешения и правила регистрации уже проверены и размещены правильно. Что требуется, так это иметь доступ к различным полям этой модели, чтобы иметь возможность генерировать финансовые отчеты с их собственные формулы?