Expected singleton: res.company() error Odoo

Question:

I am creating an API that searches and reverses an entry in the account.move model. I am able to find the correct entry and reverse it using the refund_moves() method. However, whenever I try to confirm the reversed entry using the action_post() method, I get a "Expected singleton: res.company()" error.
I’ve used the action_post() method before on other models such as sale.order/account.move and it works fine.

Code:

@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()

Custom Authorization:

    @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:

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()

Update:
I added the company using with_company() to the confirmation method and it fixed the problem

refundInvoice.with_company(invoice.company_id).action_post()

Asked By: Brandon Huynh

||

Answers:

You can Debug below line:

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)

and check what comes in self.company_id and self._context

  • There must be 0 or more than 1 company records in self.company.
  • So when it calls _get_violated_lock_dates method, it assumes it have one company_id and proceeds.
  • Try checking from where this self.company id is not getting exact 1 value
Answered By: Vinay Davda
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.