-
-
Notifications
You must be signed in to change notification settings - Fork 707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.0] ADD Putaway strategy allowing to set a location per product. #151
Changes from all commits
f541885
8bb044d
6be293d
3e9a31a
bd15bf0
5ccf585
96ca34b
bb7baca
c47648c
81ae59f
e5d27e8
93567fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
.. 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 | ||
|
||
============================ | ||
Putaway strategy per product | ||
============================ | ||
|
||
This module extends the functionality of the odoo putaway strategy. | ||
It defines a new type of putaway strategy where users can set a specific | ||
stock location per product. | ||
|
||
On the product form, the case, rack, location fields are replaced with a | ||
specific putaway strategy and location id for the product. | ||
|
||
A putaway strategy can be used to ensure that incoming products will be | ||
stored in the location set on the product form. | ||
|
||
A recommended set-up is to create a separate putaway strategy for each | ||
warehouse. This will ensure that the same product will be placed in the | ||
appropriate location in each warehouse it is received. | ||
|
||
Installation | ||
============ | ||
|
||
To install this module, just click the install button. | ||
|
||
Configuration | ||
============= | ||
|
||
To configure this module, you need to: | ||
|
||
#. Go to Settings -> Configuration -> Warehouse | ||
#. Enable "Manage multiple locations and warehouses' | ||
#. Enable "Manage advanced routes for your warehouse" | ||
#. Go to Warehouse -> Configuration -> Locations | ||
#. On the main inventory location of your warehouse, | ||
set a new putaway strategy. | ||
#. For the new putaway strategy, select 'Fixed per product location' | ||
as method | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
#. Select the proper stock locations for each product on the product form | ||
on the "Inventory" tab | ||
|
||
.. 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/8.0 | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
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 | ||
<https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_putaway_product%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
||
Images | ||
------ | ||
|
||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. | ||
|
||
Contributors | ||
------------ | ||
|
||
* Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
|
||
|
||
Maintainer | ||
---------- | ||
|
||
.. 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. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2016 Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
from . import models | ||
from . import tests | ||
from . import wizard |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2016 Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
{ | ||
'name': 'Putaway strategy per product', | ||
'summary': 'Set a product location and put-away strategy per product', | ||
'version': '8.0.1.0.0', | ||
'category': 'Inventory', | ||
'website': 'http://www.apertoso.be', | ||
'author': 'Apertoso N.V., Odoo Community Association (OCA)', | ||
'license': 'AGPL-3', | ||
'applicaton': False, | ||
'installable': True, | ||
'depends': [ | ||
'product', | ||
'stock' | ||
], | ||
'data': [ | ||
'views/product.xml', | ||
'views/product_putaway.xml', | ||
'security/ir.model.access.csv', | ||
], | ||
'demo': [ | ||
'demo/product_putaway.xml', | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<openerp> | ||
<data> | ||
|
||
<record id="product_putaway_per_product_wh" | ||
model="product.putaway"> | ||
<field name="name">WH - Putaway Per Product</field> | ||
<field name="method">per_product</field> | ||
</record> | ||
|
||
<record id="stock.stock_location_stock" | ||
model="stock.location"> | ||
<field name="putaway_strategy_id" | ||
ref="product_putaway_per_product_wh"/> | ||
</record> | ||
|
||
<record id="product_putaway_strategy_product_4" | ||
model="stock.product.putaway.strategy"> | ||
<field name="product_product_id" | ||
ref="product.product_product_4"/> | ||
<field name="product_template_id" | ||
ref="product.product_product_4_product_template"/> | ||
<field name="putaway_id" | ||
ref="product_putaway_per_product_wh"/> | ||
<field name="fixed_location_id" | ||
ref="stock.stock_location_components"/> | ||
</record> | ||
</data> | ||
</openerp> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from . import product_putaway | ||
from . import product |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import logging | ||
|
||
from openerp import models, fields | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class ProductTemplate(models.Model): | ||
_inherit = 'product.template' | ||
|
||
product_putaway_ids = fields.One2many( | ||
comodel_name='stock.product.putaway.strategy', | ||
inverse_name='product_template_id', | ||
string="Product stock locations") | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JosDeGraeve After some tests (and intense reflection to understand :-)), it does not seem to work with variants... With this related field, its impossible to create put-away strategy for two variants on same product. Example: With demo data enable, iPad Retina Display already has a put-away strategy for variant 16 GB, White, 2.4 GHz. If you try to create a strategy for another variant, it will raise a Constraint Error (on unique(putaway_id,product_product_id)). The One2many widget try to add the new strategy on product.template.product_putaway_ids but with related, it seems that he write the new strategy on first variant (regardless of the product_product_id's value in putaway.strategy) . I am a new developer Odoo, then a confirmation from an expert would be appreciated but I think you cannot write on this field... |
||
|
||
class ProductProduct(models.Model): | ||
_inherit = 'product.product' | ||
|
||
product_putaway_ids = fields.One2many( | ||
comodel_name='stock.product.putaway.strategy', | ||
inverse_name='product_product_id', | ||
string="Product stock locations") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2016 Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
import logging | ||
|
||
from openerp import models, fields, api, _ | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class ProductPutawayStrategy(models.Model): | ||
_inherit = 'product.putaway' | ||
|
||
@api.model | ||
def _get_putaway_options(self): | ||
ret = super(ProductPutawayStrategy, self)._get_putaway_options() | ||
return ret + [('per_product', 'Fixed per product location')] | ||
|
||
product_location_ids = fields.One2many( | ||
comodel_name='stock.product.putaway.strategy', | ||
inverse_name='putaway_id', | ||
string='Fixed per product location', | ||
copy=True) | ||
method = fields.Selection( | ||
selection=_get_putaway_options, | ||
string="Method", | ||
required=True) | ||
|
||
@api.model | ||
def putaway_apply(self, putaway_strategy, product): | ||
if putaway_strategy.method == 'per_product': | ||
strategy_domain = [ | ||
('putaway_id', '=', putaway_strategy.id), | ||
('product_product_id', '=', product.id), | ||
] | ||
for strategy in putaway_strategy.product_location_ids.search( | ||
strategy_domain, limit=1): | ||
return strategy.fixed_location_id.id | ||
else: | ||
return super(ProductPutawayStrategy, self).putaway_apply( | ||
putaway_strategy, product) | ||
|
||
|
||
class FixedPutawayStrat(models.Model): | ||
_name = 'stock.product.putaway.strategy' | ||
_rec_name = 'product_product_id' | ||
|
||
_sql_constraints = [( | ||
'putaway_product_unique', | ||
'unique(putaway_id,product_product_id)', | ||
_('There can only be one fixed location per product!') | ||
)] | ||
|
||
@api.model | ||
def get_default_inventory_id(self): | ||
return self.env['stock.inventory'].search( | ||
[('id', '=', self.env.context.get('active_id', False))]) | ||
|
||
putaway_id = fields.Many2one( | ||
comodel_name='product.putaway', | ||
sting='Put Away Method', | ||
required=True, | ||
select=True) | ||
product_template_id = fields.Many2one( | ||
comodel_name='product.template', | ||
string='Product Template', | ||
select=True, | ||
required=True) | ||
product_product_id = fields.Many2one( | ||
comodel_name='product.product', | ||
string='Product Variant', | ||
required=True, | ||
select=True, | ||
domain=[('product_tmpl_id', '=', 'product_template_id.id')]) | ||
fixed_location_id = fields.Many2one( | ||
comodel_name='stock.location', | ||
string='Location', | ||
required=True, | ||
domain=[('usage', '=', 'internal')]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
access_stock_product_putaway_strategy,stock_product_putaway_strategy managers,model_stock_product_putaway_strategy,stock.group_stock_manager,1,1,1,1 | ||
access_stock_product_putaway_user,stock_product_putaway_strategy user,model_stock_product_putaway_strategy,stock.group_stock_user,1,0,0,0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2016 Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from . import test_product_putaway |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2016 Jos De Graeve - Apertoso N.V. <Jos.DeGraeve@apertoso.be> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from openerp.tests import common | ||
|
||
|
||
class TestProductPutaway(common.TransactionCase): | ||
# Check if "per_product" is a valid putaway method | ||
def test_01_putaway_methods(self): | ||
field_method = self.env[ | ||
'product.putaway']._fields.get('method') | ||
self.assertIn('per_product', field_method.get_values(self.env)) | ||
|
||
def test_02_putway_apply(self): | ||
putaway_per_product = self.browse_ref( | ||
'stock_putaway_product.product_putaway_per_product_wh') | ||
product_ipad = self.browse_ref( | ||
'product.product_product_4') | ||
location_shelf1 = self.browse_ref( | ||
'stock.stock_location_components') | ||
|
||
self.assertEqual( | ||
self.env['product.putaway'].putaway_apply( | ||
putaway_per_product, product_ipad), | ||
location_shelf1.id) | ||
|
||
def test_03_stock_change_product_qty_default(self): | ||
product_ipad = self.browse_ref( | ||
'product.product_product_4') | ||
location_shelf1 = self.browse_ref( | ||
'stock.stock_location_components') | ||
|
||
wiz_obj = self.env['stock.change.product.qty'] | ||
|
||
test_context = { | ||
'active_model': 'product.product', | ||
'active_id': product_ipad.id, | ||
} | ||
wiz_instance = wiz_obj.with_context(test_context).create({}) | ||
self.assertEqual( | ||
wiz_instance.location_id, | ||
location_shelf1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add:
A recommended set-up is to create a separate Putaway Strategy per Warehouse. This will ensure that the same product will be placed in the appropiate location in each warehouse it is received.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggestion is attended in the next line.