c2c-oerpscenario team mailing list archive
-
c2c-oerpscenario team
-
Mailing list archive
-
Message #23359
[Bug 740361] Re: [6.0.1][account] slow large invoice validation because validate is called for every line
Guys, to support my customers, I created a small ugly patch (attached).
Basically I've seen that after the validate method is called once, we
have an 'invoice' key in the context. I use that criterion to skip the
validation for the next invoice lines.
This is very ugly and likely to be brittle if that invoice key is
removed (but then it will just be as inefficient as today, not worse).
After applying this workaround, the move validation is called 'only'
twice per invoice, that's still one useless call, but at least if you
have an invoice with dozens of lines you will still save dozens of call
to the exact same stupid validation.
So I call that an ugly work around that you can try at home if you are
over 18, this doesn't seem like a proper long term fix, see my first
comments about the problem if you want to elaborate a true solution to
this bug.
Hope this helps. Please consider this is an important bug for 6.1. If
you want to use OpenERP in companies larger than small SMB's you need to
avoid this kind of bugs by design. Here I have a customer with only ~20
employees and he would almost dismiss from OpenERP without such a patch.
** Patch added: "account.patch"
https://bugs.launchpad.net/openobject-addons/+bug/740361/+attachment/2113184/+files/account.patch
--
You received this bug notification because you are a member of C2C
OERPScenario, which is subscribed to the OpenERP Project Group.
https://bugs.launchpad.net/bugs/740361
Title:
[6.0.1][account] slow large invoice validation because validate is
called for every line
Status in OpenERP Modules (addons):
New
Bug description:
edit account/account.py
and introduce some traceback print statement this way:
@@ -1378,6 +1385,9 @@
# Validate a balanced move. If it is a centralised journal, create a move.
#
def validate(self, cr, uid, ids, context=None):
+# import traceback
+# traceback.print_stack()
+ print "validate", ids
if context and ('__last_update' in context):
del context['__last_update']
Now restart your server and try to validate an invoice with many lines, like 10 (cool you are not in production).
As you can see, that slow validate method is called for every invoice line, making the whole process very slow. Here in production it takes like 2 minutes to validate a 50 lines (with Brazilian taxes) invoice... Not very user friendly.
You'll see a similar traceback for every line:
File "/opt/openerp-trunk/server/bin/osv/orm.py", line 181, in <lambda>
return lambda *args, **argv: attr(self._cr, self._uid, [self._id], *args, **argv)
File "/opt/openerp-trunk/addons/l10n_br_account/invoice.py", line 323, in action_move_create
self.pool.get('account.move.line').write(cr, uid, [move_line.id for move_line in inv.move_id.line_id], {'ref': inv.internal_number})
File "/opt/openerp-trunk/addons/account_payment_extension/account_move_line.py", line 168, in write
return super(account_move_line, self).write(cr, uid, ids, vals, context, check, update_check)
File "/opt/openerp-trunk/addons/account/account_move_line.py", line 1171, in write
result = super(account_move_line, self).write(cr, uid, ids, vals, context)
File "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
result += self._columns[field].set(cr, self, id, field, vals[field], user, context=rel_context) or []
File "/opt/openerp-trunk/server/bin/osv/fields.py", line 830, in set
self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
File "/opt/openerp-trunk/server/bin/osv/fields.py", line 881, in _fnct_write
model.write(cr, uid, [t_id], {args[-1]: values}, context=context)
File "/opt/openerp-trunk/addons/account/account.py", line 1240, in write
self.validate(cr, uid, ids, context=context)
File "/opt/openerp-trunk/addons/account/account.py", line 1389, in validate
traceback.print_stack()
validate [543]
In "/opt/openerp-trunk/addons/account/account_move_line.py", line 1171, in write we still have a table of ids, so the hell loop is not born yet.
It will actually birth inside the ORM in "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
where you'll iterate over each id.
I tend to think this is a first bad implementation, may be the real source of the bug. After this, we call validate for each account move line...
Still, it looks like you attempted to prevent this by strong a context c['novalidate'] = True flag.
a grep gives us:
~# grep -r novalidate /opt/openerp-trunk/addons/account/
/opt/openerp-trunk/addons/account/account.py: c['novalidate'] = True
/opt/openerp-trunk/addons/account/account.py: c['novalidate'] = True
But as you can see, it's a bit like marketing: totally useless. Sounds
like a good intention but it has absolutely no effect at all, it's
just no used.
So, I let you determine what is the proper fix, something in the ORM
or some "novalidate" trickery before somebody remove the trick by
mistake again to fox some side effect bug...
Hope this helps.
References