Skip to content

Commit

Permalink
[FIX] point_of_sale: fix memory error
Browse files Browse the repository at this point in the history
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 #124194

X-original-commit: 0d220a7
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
  • Loading branch information
aj-fuentes committed Jun 8, 2023
1 parent a9273ce commit 14ff7de
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions addons/point_of_sale/models/account_tax.py
Expand Up @@ -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', 'is_base_affected',
])
}
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):
Expand Down

0 comments on commit 14ff7de

Please sign in to comment.