Skip to content

Commit

Permalink
[MIG] stock_picking_auto_create_lot_qty: Migration to 16.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dessanhemrayev committed Dec 19, 2024
1 parent dcb0f00 commit 9745b15
Show file tree
Hide file tree
Showing 18 changed files with 289 additions and 192 deletions.
47 changes: 22 additions & 25 deletions stock_picking_auto_create_lot_qty/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Stock Picking Auto Create Lot Quantity
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9da0cd91088d3be4a92d7376e09e59d73080bdad49e1fe1d1c9dc6b039a7a561
!! source digest: sha256:31abf6223e281237e7c286a76e4f06a04aaeff5bb04aaef7548eee5df36c5256
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
Expand All @@ -28,8 +28,7 @@ Stock Picking Auto Create Lot Quantity

|badge1| |badge2| |badge3| |badge4| |badge5|

This module extends the functionality of stock module to allow auto
create lots with certain count for incoming pickings.
Add a unique lot sequence for lots being created for every company

**Table of contents**

Expand All @@ -41,28 +40,26 @@ Configuration

To configure this module, you need to:

#. Go to a *Inventory > Master Data > Products*. #. Set 'auto create
lot'option and set 'create lot every' count of uoms for the products you
need.

If you need to create lots for different companies, you can set the
sequence for the company #. Go to a General Settings > Inventory > Stock
Serial Lots > Select sequence for current company
#. Go to *Inventory > Master Data > Products*, select a product.
#. Set 'Auto create lot' option, and set 'Create lot every' count of UoMs for the products you need.
#. Go the *Settings > Inventory > Stock Serial Lot*.
#. Press --> Sequences button to create/configure your lot sequence for a company in 'ir.sequence' module. The default sequence is 'stock.lot.serial'.
#. Once a sequence is created/updated select the stock lot sequence for the current company.

Usage
=====

To use this module you need to:

#. Go to a *Product > Inventory tab*. #. Set a tracking option for this
product. #. Set auto create lot. #. Go to *Inventory > Incoming* and
create one. #. Validate picking without lot. #. If *Only multiples
allowed* has been selected in product, picking validation will be
blocked if qty received is not a multiple of the value set in product.
#. Go to *Inventory* tab of a product.
#. Set a tracking option for this product.
#. Set 'Auto create lot'.
#. Go to *Inventory > Incoming* and create a new transfer.
#. Validate picking without lot.
#. If 'Only multiples allowed' has been selected in the product, picking validation will be blocked if qty received is not a multiple of the value set in the product.


If you need to create lots for different companies, you can set the
sequence for the company #. Go to a General Settings > Inventory > Stock
Serial Lots > Select sequence for current company
Company sequence will be applied automatically on validating the lots based on the sequence selected in settings.

Bug Tracker
===========
Expand All @@ -78,24 +75,24 @@ Credits
=======

Authors
-------
~~~~~~~

* Ooops
* Cetmix OÜ

Contributors
------------
~~~~~~~~~~~~

- `Ooops <https://www.ooops404.com>`__
* `Ooops <https://ooops404.com>`_

- `Francesco Foresti <[email protected]>`__
* `Francesco Foresti <[email protected]>`_

- `Cetmix <https://www.cetmix.com>`__:
* `Cetmix <https://cetmix.com>`_

- `Alexander Yartsev <[email protected]>`__
* `Alexander Yartsev <[email protected]>`_

Maintainers
-----------
~~~~~~~~~~~

This module is maintained by the OCA.

Expand Down
7 changes: 5 additions & 2 deletions stock_picking_auto_create_lot_qty/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
{
"name": "Stock Picking Auto Create Lot Quantity",
"summary": "Auto batch generation by quantity",
"version": "14.0.1.0.0",
"version": "16.0.1.0.0",
"development_status": "Production/Stable",
"category": "stock",
"website": "https://github.com/OCA/stock-logistics-workflow",
"author": "Ooops, Cetmix OÜ, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": ["stock_picking_auto_create_lot"],
"data": ["views/product_template_view.xml", "views/res_config_settings_view.xml"],
"data": [
"views/product_template_view.xml",
"views/res_config_settings_view.xml",
],
}
5 changes: 4 additions & 1 deletion stock_picking_auto_create_lot_qty/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import product_template
from . import stock_picking
from . import res_company
from . import stock_production_lot
from . import stock_lot
from . import res_config_settings
14 changes: 10 additions & 4 deletions stock_picking_auto_create_lot_qty/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class ProductTemplate(models.Model):
" set a value and select one of the UoMs available"
" for purchase (if value = 0, behavior stays the"
" same as base module)",
compute="_compute_create_lot_every_n",
readonly=False,
store=True,
)

only_multiples_allowed = fields.Boolean(
Expand All @@ -33,7 +36,10 @@ class ProductTemplate(models.Model):
" received is not a multiple of the selected value",
)

@api.onchange("tracking")
def _onchange_tracking(self):
if self.tracking != "lot":
self.create_lot_every_n = False
@api.depends("tracking")
def _compute_create_lot_every_n(self):
for rec in self:
if rec.tracking != "lot":
rec.create_lot_every_n = False
else:
rec.create_lot_every_n = rec.create_lot_every_n
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from odoo import fields, models


class ProductionLot(models.Model):
_inherit = "stock.production.lot"
class StockLot(models.Model):
_inherit = "stock.lot"

name = fields.Char(
default=lambda self: self.env["ir.sequence"].next_by_code(
Expand Down
112 changes: 66 additions & 46 deletions stock_picking_auto_create_lot_qty/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@ class StockPicking(models.Model):
def _split_stock_move_lines(self, pickings):
"""
Split stock move lines into existing and new lines.
This method separates stock move lines into existing and new lines based on
specific criteria and optionally creates automatic lot numbers.
Args:
pickings (recordset): Recordset of stock pickings for which to retrieve
stock move lines
Returns:
tuple (existing_lines, new_lines): A tuple containing two recordsets:
- existing_lines: Existing stock move lines associated with the pickings.
- new_lines: New stock move lines that need to be created.
"""
existing_lines = self.env["stock.move.line"].browse()
new_lines = self.env["stock.move.line"].browse()
Expand All @@ -41,17 +37,15 @@ def _split_stock_move_lines(self, pickings):

@api.model
def _create_multiple_stock_move_lines_for_lots(
self, count_of_lots, line, product_id, every_n
self, count_of_lots, line, product, every_n
):
"""
Create multiple stock move lines for generating lots.
Args:
count_of_lots (int): Number of lots to generate.
line (stock.move.line): Stock move line to use as a template.
product_id (product.product): Product for which lots are generated.
product (product.product): Product for which lots are generated.
every_n (int): Number of units of measure to generate a lot for.
Returns:
new_lines (recordset): List of new stock move lines generated.
"""
Expand All @@ -61,60 +55,40 @@ def _create_multiple_stock_move_lines_for_lots(
new_line.update(
{
"qty_done": every_n,
"product_uom_id": product_id.batch_uom_id or product_id.uom_id,
"product_uom_id": product.batch_uom_id.id or product.uom_id.id,
"product_id": product.id,
}
)
new_lines |= new_line
return new_lines

@api.model
def _prepare_count_by_products(self, lines):
"""
Prepares the number of lots to generate for each product
based on the stock move lines provided.
Args:
lines (recordset): List of stock move lines.
Returns:
count_by_product (dict): Dictionary with product IDs as keys and number of lots
to generate as values.
"""
count_by_product = dict.fromkeys(lines.mapped("product_id"), 0)
for line in lines:
count_by_product[line.product_id] += line.product_uom_qty
return count_by_product

@api.model
def _prepare_stock_move_lines_for_lots(self, product_id, line, current_product_qty):
def _prepare_stock_move_lines_for_lots(self, product, line, current_product_qty):
"""
Prepare stock move lines representing generated lots for a product.
This method is responsible for preparing stock move lines that
represent the lots generated for a specific product based on
the product's configuration and the provided quantity.
Args:
product_id (product.product): Product for which lots are generated.
product (product.product): Product for which lots are generated.
line (stock.move.line): Stock move line to use as a template.
current_product_qty (int): Quantity of the product to generate lots for.
Returns:
lines (recordset): A set of new stock move lines representing the
generated lots.
"""
every_n = product_id.product_tmpl_id.create_lot_every_n
every_n = product.product_tmpl_id.create_lot_every_n
if every_n == 0 or current_product_qty == 0:
raise ValidationError(
_("The qty create lot every n and product qty must be greater than 0")
)
lines = self.env["stock.move.line"].browse()
count_of_lots = int(current_product_qty // every_n)
lines |= self._create_multiple_stock_move_lines_for_lots(
count_of_lots, line, product_id, every_n
count_of_lots, line, product, every_n
)
remainder = current_product_qty - (count_of_lots * every_n)
if product_id.only_multiples_allowed and remainder > 0:
if product.only_multiples_allowed and remainder > 0:
raise UserError(
_(
"The quantity received for the product does"
Expand All @@ -123,30 +97,76 @@ def _prepare_stock_move_lines_for_lots(self, product_id, line, current_product_q
)
if remainder > 0:
lines |= self._create_multiple_stock_move_lines_for_lots(
1, line, product_id, remainder
1, line, product, remainder
)
return lines

def _set_auto_lot(self):
"""
Allows to be called either by button or through code
Create new lots for stock move lines based on product settings.
"""
pickings = self.filtered(lambda p: p.picking_type_id.auto_create_lot)
immediate_pickings = self.filtered(lambda p: p.immediate_transfer)
lines, new_lines = self._split_stock_move_lines(pickings)
if immediate_pickings and lines:
return self._create_lots_for_immediate_pickings(lines)
if new_lines or not lines:
return
count_by_product = self._prepare_count_by_products(lines)
line = lines[0]
for product_id, product_qty in count_by_product.items():
current_product_qty = product_id.uom_id._compute_quantity(
product_qty,
product_id.batch_uom_id or product_id.uom_id,
round=False,
)
for line in lines:
product_id = line.product_id

if product_id.create_lot_every_n:
product_qty = line.reserved_uom_qty
current_product_qty = product_id.uom_id._compute_quantity(
product_qty,
product_id.batch_uom_id or product_id.uom_id,
round=False,
)
new_lines |= self._prepare_stock_move_lines_for_lots(
product_id, line, current_product_qty
)
else:
new_lines |= line

self._set_lotname(new_lines)

@api.model
def _create_lots_for_immediate_pickings(self, lines):
"""
Create stock move lines for immediate pickings,
handling products that require lot creation.
Args:
lines (stock.move.line): A recordset of stock move lines to process.
"""
new_lines = self.env["stock.move.line"].browse()
old_lines = self.env["stock.move.line"].browse()
for line in lines:
product_id = line.product_id

if product_id.create_lot_every_n:
product_qty = line.reserved_uom_qty
current_product_qty = product_id.uom_id._compute_quantity(
product_qty,
product_id.batch_uom_id or product_id.uom_id,
round=False,
)
old_lines |= line
new_lines |= self._prepare_stock_move_lines_for_lots(
product_id, line, current_product_qty
)
else:
new_lines |= line

Check warning on line 159 in stock_picking_auto_create_lot_qty/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

stock_picking_auto_create_lot_qty/models/stock_picking.py#L159

Added line #L159 was not covered by tests
new_lines.set_lot_auto()
old_lines.update({"qty_done": 0})
self._set_lotname(new_lines)

@api.model
def _set_lotname(self, lines):
"""
Set the lot name for each stock move line in the provided recordset.
Args:
lines (stock.move.line): A recordset of stock move lines to update with lot names.
"""
for line in lines:
line.lot_name = line._get_lot_sequence()
8 changes: 0 additions & 8 deletions stock_picking_auto_create_lot_qty/readme/CONFIGURE.md

This file was deleted.

7 changes: 7 additions & 0 deletions stock_picking_auto_create_lot_qty/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
To configure this module, you need to:

#. Go to *Inventory > Master Data > Products*, select a product.
#. Set 'Auto create lot' option, and set 'Create lot every' count of UoMs for the products you need.
#. Go the *Settings > Inventory > Stock Serial Lot*.
#. Press --> Sequences button to create/configure your lot sequence for a company in 'ir.sequence' module. The default sequence is 'stock.lot.serial'.
#. Once a sequence is created/updated select the stock lot sequence for the current company.
4 changes: 0 additions & 4 deletions stock_picking_auto_create_lot_qty/readme/CONTRIBUTORS.md

This file was deleted.

7 changes: 7 additions & 0 deletions stock_picking_auto_create_lot_qty/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* `Ooops <https://ooops404.com>`_

* `Francesco Foresti <[email protected]>`_

* `Cetmix <https://cetmix.com>`_

* `Alexander Yartsev <[email protected]>`_
2 changes: 0 additions & 2 deletions stock_picking_auto_create_lot_qty/readme/DESCRIPTION.md

This file was deleted.

1 change: 1 addition & 0 deletions stock_picking_auto_create_lot_qty/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a unique lot sequence for lots being created for every company
Loading

0 comments on commit 9745b15

Please sign in to comment.