mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
proc_auto_create_grp_by_product: fix raised error
Raise correct error to allow correct catching and retry
This commit is contained in:
@@ -5,7 +5,26 @@ import hashlib
|
||||
import struct
|
||||
|
||||
from odoo import fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
def pg_advisory_lock(env, int_lock: int):
|
||||
"""Attempts to acquire a Postgres transactional advisory lock.
|
||||
|
||||
Raises an OperationalError LOCK_NOT_AVAILABLE if the lock could not be acquired.
|
||||
"""
|
||||
env.cr.execute(
|
||||
"""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT pg_try_advisory_xact_lock(%s) THEN
|
||||
RAISE EXCEPTION USING
|
||||
MESSAGE = 'Lock not available',
|
||||
ERRCODE = '55P03';
|
||||
END IF;
|
||||
END $$;
|
||||
""",
|
||||
(int_lock),
|
||||
)
|
||||
|
||||
|
||||
class StockRule(models.Model):
|
||||
@@ -17,21 +36,12 @@ class StockRule(models.Model):
|
||||
if self.auto_create_group_by_product:
|
||||
if product.auto_create_procurement_group_ids:
|
||||
return fields.first(product.auto_create_procurement_group_ids)
|
||||
else:
|
||||
# Make sure that two transactions can not create a procurement group
|
||||
# For the same product at the same time.
|
||||
lock_name = f"product.product,{product.id}-auto-proc-group"
|
||||
hasher = hashlib.sha1(str(lock_name).encode())
|
||||
int_lock = struct.unpack("q", hasher.digest()[:8])
|
||||
self.env.cr.execute(
|
||||
"SELECT pg_try_advisory_xact_lock(%s);", (int_lock,)
|
||||
)
|
||||
lock_acquired = self.env.cr.fetchone()[0]
|
||||
if not lock_acquired:
|
||||
raise UserError(
|
||||
f"The auto procurement group for product {product.name} "
|
||||
"is already being created by someone else."
|
||||
)
|
||||
# Make sure that two transactions cannot create a procurement group
|
||||
# For the same product at the same time.
|
||||
lock_name = f"product.product,{product.id}-auto-proc-group"
|
||||
hasher = hashlib.sha1(str(lock_name).encode())
|
||||
bigint_lock = struct.unpack("q", hasher.digest()[:8])
|
||||
pg_advisory_lock(self.env, bigint_lock)
|
||||
return super()._get_auto_procurement_group(product)
|
||||
|
||||
def _prepare_auto_procurement_group_data(self, product):
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, registry
|
||||
from odoo.exceptions import UserError
|
||||
import psycopg2
|
||||
|
||||
from odoo import api, registry, tools
|
||||
from odoo.service.model import PG_CONCURRENCY_ERRORS_TO_RETRY
|
||||
|
||||
from odoo.addons.procurement_auto_create_group.tests.test_auto_create import (
|
||||
TestProcurementAutoCreateGroup,
|
||||
@@ -135,9 +137,9 @@ class TestProcurementAutoCreateGroupByProduct(TestProcurementAutoCreateGroup):
|
||||
rule2.auto_create_group_by_product = True
|
||||
product2 = new_env["product.product"].browse(product.id)
|
||||
self.assertFalse(product2.auto_create_procurement_group_ids)
|
||||
exception_msg = (
|
||||
f"The auto procurement group for product {product2.name} "
|
||||
"is already being created by someone else."
|
||||
)
|
||||
with self.assertRaisesRegex(UserError, exception_msg):
|
||||
with self.assertRaises(psycopg2.OperationalError) as cm, tools.mute_logger(
|
||||
"odoo.sql_db"
|
||||
):
|
||||
rule2._get_auto_procurement_group(product2)
|
||||
self.assertTrue(cm.exception.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY)
|
||||
new_cr.rollback()
|
||||
|
||||
Reference in New Issue
Block a user