Я создаю API, который ищет и отменяет запись в модели account.move. Я могу найти правильную запись и отменить ее, используя метод return_moves(). Однако всякий раз, когда я пытаюсь подтвердить обратную запись с помощью метода action_post(), я получаю ошибку «Ожидаемый синглтон: res.company()». Раньше я использовал метод action_post() в других моделях, таких как sale.order/account.move, и он работал нормально.
Код:
@http.route('/update_invoice', website = "false", auth='custom_auth', type='json', methods=['POST'])
#Searching for entry
invoice = request.env['account.move'].sudo().search([('matter_id','=',matterID),('account_id','=',accountID),('move_type','=','out_invoice'),('company_id','=',creditor.id)])
if invoice:
#Create Reversal
move_reversal = request.env['account.move.reversal'].with_context(active_model = "account.move", active_ids=invoice.id).sudo().create({
'date': intakeDate,
'reason': 'Balance Adjustment',
'journal_id': invoice.journal_id.id,
})
#Reverse Entry
move_reversal.refund_moves()
#Search for created reversed entry
refundInvoice = request.env['account.move'].sudo().search([('name','=',"/"),('company_id','=',creditor.id),('move_type','=','out_refund')])
if refundInvoice:
_logger.info("Refund Invoice Found")
#Error occurs
refundInvoice.action_post()
Пользовательская авторизация:
@classmethod
def _auth_method_custom_auth(cls):
access_token = request.httprequest.headers.get('Authorization')
_logger.info(access_token)
if not access_token:
_logger.info('Access Token Missing')
raise BadRequest('Missing Access Token')
if access_token.startswith('Bearer '):
access_token = access_token[7:]
_logger.info(access_token)
user_id = request.env["res.users.apikeys"]._check_credentials(scope='odoo.restapi', key=access_token)
if not user_id:
_logger.info('No user with api key found')
raise BadRequest('Access token Invalid')
request.update_env(user=user_id)
Выслеживать:
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/models.py", line 5841, in ensure_one
_id, = self._ids
ValueError: not enough values to unpack (expected 1, got 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/http.py", line 2189, in __call__
response = request._serve_db()
File "/home/odoo/src/odoo/odoo/http.py", line 1765, in _serve_db
return service_model.retrying(self._serve_ir_http, self.env)
File "/home/odoo/src/odoo/odoo/service/model.py", line 133, in retrying
result = func()
File "/home/odoo/src/odoo/odoo/http.py", line 1792, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/odoo/src/odoo/odoo/http.py", line 1996, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/odoo/src/odoo/addons/website/models/ir_http.py", line 235, in _dispatch
response = super()._dispatch(endpoint)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 222, in _dispatch
result = endpoint(**request.params)
File "/home/odoo/src/odoo/odoo/http.py", line 722, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/user/account_ext/controllers/main.py", line 411, in update_invoice
refundInvoice.action_post()
File "/home/odoo/src/odoo/addons/sale/models/account_move.py", line 63, in action_post
res = super(AccountMove, self).action_post()
File "/home/odoo/src/enterprise/account_accountant/models/account_move.py", line 76, in action_post
res = super().action_post()
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 4072, in action_post
other_moves._post(soft=False)
File "/home/odoo/src/enterprise/sale_subscription/models/account_move.py", line 13, in _post
posted_moves = super()._post(soft=soft)
File "/home/odoo/src/enterprise/account_asset/models/account_move.py", line 109, in _post
posted = super()._post(soft)
File "/home/odoo/src/odoo/addons/sale/models/account_move.py", line 99, in _post
posted = super()._post(soft)
File "/home/odoo/src/enterprise/account_reports/models/account_move.py", line 48, in _post
return super()._post(soft)
File "/home/odoo/src/enterprise/account_avatax/models/account_move.py", line 15, in _post
res = super()._post(soft=soft)
File "/home/odoo/src/enterprise/account_invoice_extract/models/account_invoice.py", line 262, in _post
posted = super()._post(soft)
File "/home/odoo/src/enterprise/account_inter_company_rules/models/account_move.py", line 14, in _post
posted = super()._post(soft)
File "/home/odoo/src/enterprise/account_external_tax/models/account_move.py", line 53, in _post
return super()._post(soft=soft)
File "/home/odoo/src/enterprise/account_accountant/models/account_move.py", line 68, in _post
posted = super()._post(soft)
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 3876, in _post
draft_reverse_moves.reversed_entry_id._reconcile_reversed_moves(draft_reverse_moves, self._context.get('move_reverse_cancel', False))
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 3694, in _reconcile_reversed_moves
lines.with_context(move_reverse_cancel=move_reverse_cancel).reconcile()
File "/home/odoo/src/odoo/addons/account/models/account_move_line.py", line 2935, in reconcile
return self._reconcile_plan([self])
File "/home/odoo/src/odoo/addons/account/models/account_move_line.py", line 2345, in _reconcile_plan
self._reconcile_plan_with_sync(plan_list, all_amls)
File "/home/odoo/src/odoo/addons/account/models/account_move_line.py", line 2492, in _reconcile_plan_with_sync
exchange_diff_values = exchange_lines_to_fix._prepare_exchange_difference_move_vals(
File "/home/odoo/src/odoo/addons/account/models/account_move_line.py", line 2603, in _prepare_exchange_difference_move_vals
accounting_exchange_date = journal.with_context(move_date=exchange_date).accounting_date
File "/home/odoo/src/odoo/odoo/fields.py", line 1207, in __get__
self.compute_value(recs)
File "/home/odoo/src/odoo/odoo/fields.py", line 1389, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/addons/mail/models/mail_thread.py", line 424, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/odoo/models.py", line 4867, in _compute_field_value
fields.determine(field.compute, self)
File "/home/odoo/src/odoo/odoo/fields.py", line 102, in determine
return needle(*args)
File "/home/odoo/src/odoo/addons/account/models/account_journal.py", line 366, in _compute_accounting_date
journal.accounting_date = temp_move._get_accounting_date(move_date, has_tax)
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 4358, in _get_accounting_date
lock_dates = self._get_violated_lock_dates(invoice_date, has_tax)
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 4389, in _get_violated_lock_dates
return self.company_id._get_violated_lock_dates(invoice_date, has_tax)
File "/home/odoo/src/odoo/addons/account/models/company.py", line 369, in _get_violated_lock_dates
self.ensure_one()
File "/home/odoo/src/odoo/odoo/models.py", line 5844, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: res.company()
Обновлять: Я добавил компанию, использующую with_company(), в метод подтверждения, и это устранило проблему.
refundInvoice.with_company(invoice.company_id).action_post()
Я использую odoo17, активировано несколько компаний, и я не уверен, что вы подразумеваете под пользователем, вошедшим в систему. Я использую пользовательскую авторизацию, которая использует собственный ключ API пользователя, чтобы убедиться, что он является пользователем в системе. Я добавил код для пользовательской авторизации, а также http.route.
Ладно, я слепой, не увидел первую строку кода. Хм, я не разбираюсь в том, как контекст или среда строятся на основе этих вызовов, но я думаю, что чего-то не хватает в вашей пользовательской аутентификации, когда вы устанавливаете пользователя для env. Активен ли пользователь в компании? И когда да, в какой компании? Тот, который ему нужен для выставления счетов/возвратов?
Да, я вхожу в систему под нужным пользователем, и у него есть доступ ко всем компаниям. Я создал другие API, которые создают записи в моделях sale.order и account.move и подтверждают их с помощью метода action_post(). Только когда я переворачиваю его и пытаюсь подтвердить обратное, я получаю эту ошибку.






Вы можете выполнить отладку ниже строки:
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 4389, in _get_violated_lock_dates
return self.company_id._get_violated_lock_dates(invoice_date, has_tax)
и проверь, что приходит self.company_id и self._context
Хорошо, я понял это. Поскольку запись о компании отсутствует, я передал компанию, указанную в счете, с помощью returnInvoice.with_company(invoice.company_id).action_post() при подтверждении обратной записи.
Большой ! иногда это можно решить, добавив контекст, например: self.env['account.pay'].sudo().with_context(default_company_id=user_rec.company_id.id).create(payment_order_vals)
У меня много вопросов: Какая версия Odoo? Какой пользователь входит в систему при использовании API? Активирована ли функция работы с несколькими компаниями?