Skip to content
Snippets Groups Projects
Commit 0d220a7b authored by Alvaro Fuentes's avatar Alvaro Fuentes
Browse files

[FIX] point_of_sale: fix memory error


When there are too many (millions) of POS order lines associated to
opened POS sessions we get too many taxes, most are duplicated. This
causes a MemorryError.

Example queries from a real DB:
```
> select count(distinct r.account_tax_id) from pos_order_line l join pos_order o on o.id = l.order_id join pos_session s on s.id = o.session_id join account_tax_pos_order_line_rel r on r.pos_order_
 line_id = l.id where s.state != 'closed'
+-------+
| count |
|-------|
| 24    |
+-------+
> select count(r.account_tax_id) from pos_order_line l join pos_order o on o.id = l.order_id join pos_session s on s.id = o.session_id join account_tax_pos_order_line_rel r on r.pos_order_line_id =
  l.id where s.state != 'closed'
+---------+
| count   |
|---------|
| 2504539 |
+---------+
```

opw-3295467

closes odoo/odoo#124180

X-original-commit: 45d19b265033aa626e110e51d8b1d01408717a3e
Signed-off-by: default avatarChristophe Simonis (chs) <chs@odoo.com>
parent b0844d2f
No related branches found
No related tags found
No related merge requests found
......@@ -2,27 +2,29 @@
from odoo import _, api, models
from odoo.exceptions import UserError
from odoo.tools import split_every
class AccountTax(models.Model):
_inherit = 'account.tax'
def write(self, vals):
forbidden_fields = set([
forbidden_fields = {
'amount_type', 'amount', 'type_tax_use', 'tax_group_id', 'price_include',
'include_base_amount'
])
}
if forbidden_fields & set(vals.keys()):
tax_ids = self.env['pos.order.line'].sudo().search([
lines = self.env['pos.order.line'].sudo().search([
('order_id.session_id.state', '!=', 'closed')
]).read(['tax_ids'])
# Flatten the list of taxes, see https://stackoverflow.com/questions/952914
tax_ids = set([i for sl in [t['tax_ids'] for t in tax_ids] for i in sl])
if tax_ids & set(self.ids):
raise UserError(_(
'It is forbidden to modify a tax used in a POS order not posted. '
'You must close the POS sessions before modifying the tax.'
))
])
self_ids = set(self.ids)
for lines_chunk in map(self.env['pos.order.line'].browse, split_every(100000, lines.ids)):
if any(tid in self_ids for ts in lines_chunk.read(['tax_ids']) for tid in ts['tax_ids']):
raise UserError(_(
'It is forbidden to modify a tax used in a POS order not posted. '
'You must close the POS sessions before modifying the tax.'
))
lines_chunk.invalidate_cache(['tax_ids'], lines_chunk.ids)
return super(AccountTax, self).write(vals)
def get_real_tax_amount(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment