This question has been flagged
1 Reply
3953 Views

While developing new modules I face weird behaviours from time to time.

It seems that when something is not properly coded is quite easy to leave "stuff" on database or somewhere else, so you still see the old modules in the list of local modules even when they have been removed from the module director, the server restarted and the module list updated.

It is actually really annoying and after 8 months working intensively with Odoo I still find myself more time fixing these kind of issues in Odoo than doing actual work.

This time I am getting this error:

Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 537, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 574, in dispatch
result = self._call_function(**self.params)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 310, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/service/model.py", line 113, in wrapper
return f(dbname, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 307, in checked_call
return self.endpoint(*a, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 803, in __call__
return self.method(*args, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 403, in response_wrap
response = f(*args, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/addons/web/controllers/main.py", line 948, in call_button
action = self._call_kw(model, method, args, {})
File "/usr/lib/python2.7/dist-packages/openerp/addons/web/controllers/main.py", line 936, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/addons/base/module/module.py", line 446, in button_immediate_install
return self._button_immediate_function(cr, uid, ids, self.button_install, context=context)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/addons/base/module/module.py", line 494, in _button_immediate_function
registry = openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True)
File "/usr/lib/python2.7/dist-packages/openerp/modules/registry.py", line 370, in new
openerp.modules.load_modules(registry._db, force_demo, status, update_module)
File "/usr/lib/python2.7/dist-packages/openerp/modules/loading.py", line 355, in load_modules
loaded_modules, update_module)
File "/usr/lib/python2.7/dist-packages/openerp/modules/loading.py", line 255, in load_marked_modules
loaded, processed = load_module_graph(cr, graph, progressdict, report=report, skip_modules=loaded_modules, perform_checks=perform_checks)
File "/usr/lib/python2.7/dist-packages/openerp/modules/loading.py", line 152, in load_module_graph
models = registry.load(cr, package)
File "/usr/lib/python2.7/dist-packages/openerp/modules/registry.py", line 163, in load
model = cls._build_model(self, cr)
File "/usr/lib/python2.7/dist-packages/openerp/models.py", line 596, in _build_model
original_module = pool[name]._original_module if name in parents else cls._module
File "/usr/lib/python2.7/dist-packages/openerp/modules/registry.py", line 102, in __getitem__
return self.models[model_name]
KeyError: 'account_invoice'

The module I am trying to write is coded now in "delete_invoice" folder:

# cat delete_invoice.py

# -*- coding: utf-8 -*-
from openerp import models, fields, api

# DESCRIPTION:
# Class DeleteInvoices allows invoice deletion
# NOTES:
# account_cancel is needed and diaries need

class delete_invoice ( models.Model ):
_inherit = 'account.invoice'

@api.multi
def unlink(self):
for invoice in self:
if invoice.state not in ('draft', 'cancel'):
raise Warning(_('You cannot delete an invoice which is not draft or cancelled. You should refund it instead.'))
# elif invoice.internal_number:
# raise Warning(_('You cannot delete an invoice after it has been validated (and received a number). You can set it back to "Draft" state and modify its content, then re-confirm it.'))
return super(delete_invoice, self).unlink()

# cat __init__.py
from . import delete_invoice

# cat __openerp__.py
{
'name': 'Allow delete invoice',
'description': 'This module allows to delete invoices once they have been cancelled',
'author': 'E.M.',
'depends': ['account', 'account_cancel'],
'data': [],
}

Still wondering why I see "delete_invoices" and "delete_invoices2" modules in the list, which where the former names of this module.

Any tips on how to clean up failed module installations or fully remove registered old modules?


Avatar
Discard
Best Answer

I don't see anything in the code that deletes modules that are no longer on disk when the list of modules is updated: https://github.com/odoo/odoo/blob/9.0/openerp/addons/base/module/module.py#L641

Any module in the list can be deleted, just like any other Odoo record, as long as it has been uninstalled - so manually delete anything you don't want there.   

Avatar
Discard
Author

And how do I manually delete those modules?

It is just like deleting any other Odoo record. Select it in the list, or open it, and from the Action (or More on v8) menu, point to "Delete".