mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
# Copyright 2020 Camptocamp SA
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
import logging
|
|
|
|
import psycopg2
|
|
|
|
from odoo import models
|
|
|
|
from odoo.addons.queue_job.exception import RetryableJobError
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ProductProduct(models.Model):
|
|
_inherit = "product.product"
|
|
|
|
def _moves_auto_assign_domain(self, locations):
|
|
return [
|
|
("product_id", "=", self.id),
|
|
("location_id", "parent_of", locations.ids),
|
|
("state", "in", ("confirmed", "partially_available")),
|
|
# useless to try reserving a move that waits on another move
|
|
# or is MTO
|
|
("move_orig_ids", "=", False),
|
|
("procure_method", "=", "make_to_stock"),
|
|
# Do not filter on product_id.type by default because it uses an
|
|
# additional query on product_product and product_template.
|
|
# StockMove._prepare_auto_assign() already filtered out
|
|
# non-stockable products and # `_action_assign()` would filter them
|
|
# out anyway.
|
|
]
|
|
|
|
def moves_auto_assign(self, locations):
|
|
"""Job trying to reserve moves based on product and locations
|
|
|
|
When a product has been added to a location, it searches all*
|
|
the moves with a source equal or above this location and try
|
|
to reserve them.
|
|
|
|
* all the moves that would make sense to reserve, so no chained
|
|
moves, no MTO, ...
|
|
"""
|
|
self.ensure_one()
|
|
moves = self.env["stock.move"].search(self._moves_auto_assign_domain(locations))
|
|
pickings = moves.picking_id
|
|
if not pickings:
|
|
return
|
|
self._lock_pickings_or_retry(pickings)
|
|
moves._action_assign()
|
|
|
|
def _lock_pickings_or_retry(self, pickings):
|
|
try:
|
|
self.env.cr.execute(
|
|
"SELECT id FROM stock_picking WHERE id IN %s FOR UPDATE NOWAIT",
|
|
(tuple(pickings.ids),),
|
|
)
|
|
except psycopg2.OperationalError as err:
|
|
if err.pgcode == "55P03": # could not obtain the lock
|
|
_logger.debug(
|
|
"Another job is already auto-assigning moves and acquired a"
|
|
" lock on one or some of stock.picking%s, retry later.",
|
|
tuple(pickings.ids),
|
|
)
|
|
raise RetryableJobError(
|
|
"Could not obtain lock on transfers, will retry.", ignore_retry=True
|
|
)
|
|
raise
|