Skip to content

Commit

Permalink
[11.0][MIG] stock_inventory_exclude_sublocation
Browse files Browse the repository at this point in the history
  • Loading branch information
LoisRForgeFlow committed Sep 12, 2018
1 parent 672bc52 commit 44a001d
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 114 deletions.
61 changes: 39 additions & 22 deletions stock_inventory_exclude_sublocation/README.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

===================================
Stock Inventory Exclude Sublocation
===================================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
:target: https://odoo-community.org/page/development-status
:alt: Mature
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-warehouse/tree/11.0/stock_inventory_exclude_sublocation
:alt: OCA/stock-logistics-warehouse
.. |badge4| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/153/11.0
:alt: Try me on Runbot

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

This module extends the functionality of Inventory Adjustment to allow you to
exclude all the sublocations when doing an inventory adjustment for a
given location.
Expand All @@ -16,6 +32,10 @@ do inventories of smaller locations contained in our stock, so we don't want
to count them again when doing an inventory adjustment of the parent location.
E.g. if we apply a cycle count strategy.

**Table of contents**

.. contents::
:local:

Usage
=====
Expand All @@ -26,44 +46,41 @@ To use this module, you simply need to:
#. Select the option inventory of all products.
#. Check the box "Exclude Sublocations".

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/153/10.0


Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/OCA/{project_repo}/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Images
------
Authors
~~~~~~~

* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
* Eficent

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

* Lois Rilo Antelo <lois.rilo@eficent.com>

Maintainers
~~~~~~~~~~~

Maintainer
----------
This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

This module is maintained by the OCA.

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

To contribute to this module, please visit https://odoo-community.org.
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/11.0/stock_inventory_exclude_sublocation>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
6 changes: 0 additions & 6 deletions stock_inventory_exclude_sublocation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import models
from . import tests
8 changes: 4 additions & 4 deletions stock_inventory_exclude_sublocation/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Stock Inventory Exclude Sublocation",
"summary": "Allow to perform inventories of a location without including "
"its child locations.",
"version": "10.0.1.0.0",
"author": "Eficent,"
"version": "11.0.1.0.0",
"development_status": "Mature",
"author": "Eficent, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"category": "Warehouse Management",
"depends": ["stock", "stock_inventory_chatter"],
"data": [
'views/stock_inventory_view.xml'
'views/stock_inventory_view.xml',
],
"license": "AGPL-3",
'installable': True,
Expand Down
5 changes: 0 additions & 5 deletions stock_inventory_exclude_sublocation/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import stock_inventory
133 changes: 71 additions & 62 deletions stock_inventory_exclude_sublocation/models/stock_inventory.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models
from odoo import fields, models


class Inventory(models.Model):
Expand All @@ -14,68 +13,78 @@ class Inventory(models.Model):
track_visibility='onchange', readonly=True,
states={'draft': [('readonly', False)]})

@api.multi
def _get_inventory_lines_values(self):
if self.exclude_sublocation:
domain = ' location_id = %s'
args = (tuple(self.location_id.ids),)
"""This method is a copy of standard one but considering only the
current location.
WARNING: In case of excluding sublocations standard method
is overridden by this one."""
if not self.exclude_sublocation:
# Early return if exclude_sublocation is not set
return super()._get_inventory_lines_values()

vals = []
product_obj = self.env['product.product']
# Empty recordset of products available in stock_quants
quant_products = self.env['product.product']
# Empty recordset of products to filter
products_to_filter = self.env['product.product']
# STAR OF MODIFIED CODE:
domain = ' location_id in %s'
args = (tuple(self.location_id.ids),)
# END OF MODIFIED CODE.

if self.company_id.id:
domain += ' AND company_id = %s'
args += (self.company_id.id,)
if self.partner_id:
domain += ' AND owner_id = %s'
args += (self.partner_id.id,)
if self.lot_id:
domain += ' AND lot_id = %s'
args += (self.lot_id.id,)
if self.product_id:
domain += ' AND product_id = %s'
args += (self.product_id.id,)
products_to_filter |= self.product_id
if self.package_id:
domain += ' AND package_id = %s'
args += (self.package_id.id,)
if self.category_id:
categ_products = product_obj.search(
[('categ_id', '=', self.category_id.id)])
domain += ' AND product_id = ANY (%s)'
args += (categ_products.ids,)
products_to_filter |= categ_products
vals = []
Product = self.env['product.product']
# Empty recordset of products available in stock_quants
quant_products = self.env['product.product']
# Empty recordset of products to filter
products_to_filter = self.env['product.product']

# disable error about SQL injection as the code here is generating
# a vulnerability
# pylint: disable = E8103
self.env.cr.execute(
"SELECT product_id, SUM(qty) AS product_qty, location_id, "
" lot_id AS prod_lot_id, package_id, owner_id AS partner_id "
"FROM stock_quant "
"WHERE " + domain + " " +
"GROUP BY product_id, location_id, lot_id, package_id, "
"partner_id """, args)
# case 0: Filter on company
if self.company_id:
domain += ' AND company_id = %s'
args += (self.company_id.id,)

for product_data in self.env.cr.dictfetchall():
for void_field in [item[0] for item in product_data.items() if
item[1] is None]:
product_data[void_field] = False
product_data['theoretical_qty'] = product_data['product_qty']
if product_data['product_id']:
product_data['product_uom_id'] = product_obj.browse(
product_data['product_id']).uom_id.id
quant_products |= product_obj.browse(
product_data['product_id'])
vals.append(product_data)
if self.exhausted:
exhausted_vals = self._get_exhausted_inventory_line(
products_to_filter, quant_products)
vals.extend(exhausted_vals)
return vals
else:
return super(Inventory, self)._get_inventory_lines_values()
# case 1: Filter on One owner only or One product for a specific owner
if self.partner_id:
domain += ' AND owner_id = %s'
args += (self.partner_id.id,)
# case 2: Filter on One Lot/Serial Number
if self.lot_id:
domain += ' AND lot_id = %s'
args += (self.lot_id.id,)
# case 3: Filter on One product
if self.product_id:
domain += ' AND product_id = %s'
args += (self.product_id.id,)
products_to_filter |= self.product_id
# case 4: Filter on A Pack
if self.package_id:
domain += ' AND package_id = %s'
args += (self.package_id.id,)
# case 5: Filter on One product category + Exahausted Products
if self.category_id:
categ_products = Product.search(
[('categ_id', '=', self.category_id.id)])
domain += ' AND product_id = ANY (%s)'
args += (categ_products.ids,)
products_to_filter |= categ_products

self.env.cr.execute("""
SELECT product_id, sum(quantity) as product_qty,
location_id, lot_id as prod_lot_id, package_id,
owner_id as partner_id
FROM stock_quant
WHERE %s
GROUP BY product_id, location_id, lot_id,
package_id, partner_id """ % domain, args)

for product_data in self.env.cr.dictfetchall():
for void_field in [item[0] for item in product_data.items() if
item[1] is None]:
product_data[void_field] = False
product_data['theoretical_qty'] = product_data['product_qty']
if product_data['product_id']:
product_data['product_uom_id'] = Product.browse(
product_data['product_id']).uom_id.id
quant_products |= Product.browse(product_data['product_id'])
vals.append(product_data)
if self.exhausted:
exhausted_vals = self._get_exhausted_inventory_line(
products_to_filter, quant_products)
vals.extend(exhausted_vals)
return vals
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Lois Rilo Antelo <lois.rilo@eficent.com>
9 changes: 9 additions & 0 deletions stock_inventory_exclude_sublocation/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
This module extends the functionality of Inventory Adjustment to allow you to
exclude all the sublocations when doing an inventory adjustment for a
given location.

Sometimes we just want to make an inventory adjustment of just one shelf, or
space and forget about extra subdivisions in the location. In other cases we
do inventories of smaller locations contained in our stock, so we don't want
to count them again when doing an inventory adjustment of the parent location.
E.g. if we apply a cycle count strategy.
5 changes: 5 additions & 0 deletions stock_inventory_exclude_sublocation/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
To use this module, you simply need to:

#. Create a new inventory adjustment.
#. Select the option inventory of all products.
#. Check the box "Exclude Sublocations".
5 changes: 0 additions & 5 deletions stock_inventory_exclude_sublocation/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import test_exclude_sublocation
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
Expand Down Expand Up @@ -104,7 +103,7 @@ def test_not_excluding_sublocations(self):
if the excluding sublocations option is disabled."""
inventory_location = self._create_inventory_all_products(
'location inventory', self.location, False)
inventory_location.prepare_inventory()
inventory_location.action_start()
inventory_location.action_done()
lines = inventory_location.line_ids
self.assertEqual(len(lines), 2, 'Not all expected products are '
Expand All @@ -117,9 +116,9 @@ def test_excluding_sublocations(self):
'location inventory', self.location, True)
inventory_sublocation = self._create_inventory_all_products(
'sublocation inventory', self.sublocation, True)
inventory_location.prepare_inventory()
inventory_location.action_start()
inventory_location.action_done()
inventory_sublocation.prepare_inventory()
inventory_sublocation.action_start()
inventory_sublocation.action_done()
lines_location = inventory_location.line_ids
lines_sublocation = inventory_sublocation.line_ids
Expand All @@ -137,7 +136,7 @@ def test_lot_excluding_sublocation(self):
'lot_id': self.lot_a.id,
'exclude_sublocation': True
})
inventory.prepare_inventory()
inventory.action_start()
inventory.action_done()
lines = inventory.line_ids
self.assertEqual(len(lines), 1, 'The products in the sublocations are '
Expand All @@ -149,7 +148,7 @@ def test_product_and_owner_excluding_sublocation(self):
self.quant_model.create({
'product_id': self.product1.id,
'location_id': self.location.id,
'qty': 1,
'quantity': 1,
'owner_id': self.partner,
})
inventory = self.inventory_model.sudo(self.user.id).create({
Expand All @@ -160,7 +159,7 @@ def test_product_and_owner_excluding_sublocation(self):
'partner_id': self.partner,
'exclude_sublocation': True
})
inventory.prepare_inventory()
inventory.action_start()
lines = inventory.line_ids
self.assertEqual(len(lines), 1,
'The products in the sublocations are '
Expand All @@ -171,7 +170,7 @@ def test_pack_excluding_sublocation(self):
self.quant_model.create({
'product_id': self.product1.id,
'location_id': self.location.id,
'qty': 1,
'quantity': 1,
'package_id': self.package.id
})
inventory = self.inventory_model.sudo(self.user.id).create({
Expand All @@ -181,7 +180,7 @@ def test_pack_excluding_sublocation(self):
'package_id': self.package.id,
'exclude_sublocation': True
})
inventory.prepare_inventory()
inventory.action_start()
lines = inventory.line_ids
self.assertEqual(len(lines), 1, 'The products in the sublocations are '
'not excluded with package filter.')
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<odoo>

<record id="view_inventory_form" model="ir.ui.view">
<field name="name">Inventory form view - cycle count extension </field>
<field name="name">Inventory form view - stock_inventory_exclude_sublocation extension</field>
<field name="model">stock.inventory</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="arch" type="xml">
Expand Down

0 comments on commit 44a001d

Please sign in to comment.