summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKinjal Mehta <kme@odoo.com>2018-12-12 10:28:27 +0000
committerJeremy Kersten <jke@odoo.com>2019-04-19 06:22:02 +0000
commit2b484317ff01160dbfebc69fada654aecf594f87 (patch)
tree95f0b1ded56bcfc9c90a7d9c14aed07dd8b34beb
parent25153b50efd5fe7c005482018a0c460acb6f0599 (diff)
[ADD] website_sale_stock: allow to set warehouse on the website.
Purpose: Add option to set a default warehouse on the website. Before this: We are showing all quantity of product for specific company not specific warehouse. After this: We will see availability of product based on warehouse set on the website. task-1913031 closes odoo/odoo#30104 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
-rw-r--r--addons/website_sale_stock/models/product_template.py3
-rw-r--r--addons/website_sale_stock/models/res_config_settings.py8
-rw-r--r--addons/website_sale_stock/models/sale_order.py4
-rw-r--r--addons/website_sale_stock/models/website.py6
-rw-r--r--addons/website_sale_stock/tests/__init__.py4
-rw-r--r--addons/website_sale_stock/tests/test_website_sale_stock_product_warehouse.py76
-rw-r--r--addons/website_sale_stock/views/res_config_settings_views.xml8
7 files changed, 102 insertions, 7 deletions
diff --git a/addons/website_sale_stock/models/product_template.py b/addons/website_sale_stock/models/product_template.py
index ee8ea1e3ac3..ed39cdd0659 100644
--- a/addons/website_sale_stock/models/product_template.py
+++ b/addons/website_sale_stock/models/product_template.py
@@ -27,8 +27,9 @@ class ProductTemplate(models.Model):
if combination_info['product_id']:
product = self.env['product.product'].sudo().browse(combination_info['product_id'])
+ website = self.env['website'].get_current_website()
combination_info.update({
- 'virtual_available': product.virtual_available,
+ 'virtual_available': product.with_context(warehouse=website.warehouse_id.id).virtual_available,
'product_type': product.type,
'inventory_availability': product.inventory_availability,
'available_threshold': product.available_threshold,
diff --git a/addons/website_sale_stock/models/res_config_settings.py b/addons/website_sale_stock/models/res_config_settings.py
index 73b02412726..51b05aa01ae 100644
--- a/addons/website_sale_stock/models/res_config_settings.py
+++ b/addons/website_sale_stock/models/res_config_settings.py
@@ -10,10 +10,11 @@ class ResConfigSettings(models.TransientModel):
inventory_availability = fields.Selection([
('never', 'Sell regardless of inventory'),
('always', 'Show inventory on website and prevent sales if not enough stock'),
- ('threshold', 'Show inventory below a threshold and prevent sales if not enough stock'),
+ ('threshold', 'Show inventory when below the threshold and prevent sales if not enough stock'),
('custom', 'Show product-specific notifications'),
], string='Inventory Availability', default='never')
available_threshold = fields.Float(string='Availability Threshold')
+ website_warehouse_id = fields.Many2one('stock.warehouse', related='website_id.warehouse_id', domain="[('company_id', '=', website_company_id)]", readonly=False)
@api.multi
def set_values(self):
@@ -29,3 +30,8 @@ class ResConfigSettings(models.TransientModel):
res.update(inventory_availability=IrDefault.get('product.template', 'inventory_availability') or 'never',
available_threshold=IrDefault.get('product.template', 'available_threshold') or 5.0)
return res
+
+ @api.onchange('website_company_id')
+ def _onchange_website_company_id(self):
+ if self.website_warehouse_id.company_id != self.website_company_id:
+ return {'value': {'website_warehouse_id': False}}
diff --git a/addons/website_sale_stock/models/sale_order.py b/addons/website_sale_stock/models/sale_order.py
index 2896163c673..060577c8e80 100644
--- a/addons/website_sale_stock/models/sale_order.py
+++ b/addons/website_sale_stock/models/sale_order.py
@@ -17,8 +17,8 @@ class SaleOrder(models.Model):
for line in self.order_line:
if line.product_id.type == 'product' and line.product_id.inventory_availability in ['always', 'threshold']:
cart_qty = sum(self.order_line.filtered(lambda p: p.product_id.id == line.product_id.id).mapped('product_uom_qty'))
- if cart_qty > line.product_id.virtual_available and (line_id == line.id):
- qty = line.product_id.virtual_available - cart_qty
+ if cart_qty > line.product_id.with_context(warehouse=self.warehouse_id.id).virtual_available and (line_id == line.id):
+ qty = line.product_id.with_context(warehouse=self.warehouse_id.id).virtual_available - cart_qty
new_val = super(SaleOrder, self)._cart_update(line.product_id.id, line.id, qty, 0, **kwargs)
values.update(new_val)
diff --git a/addons/website_sale_stock/models/website.py b/addons/website_sale_stock/models/website.py
index bee131093b7..e9730cffed0 100644
--- a/addons/website_sale_stock/models/website.py
+++ b/addons/website_sale_stock/models/website.py
@@ -1,15 +1,19 @@
# -*- coding: utf-8 -*-
-from odoo import api, models
+from odoo import api, fields, models
+
class Website(models.Model):
_inherit = 'website'
+ warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse')
+
@api.multi
def _prepare_sale_order_values(self, partner, pricelist):
self.ensure_one()
values = super(Website, self)._prepare_sale_order_values(partner, pricelist)
if values['company_id']:
warehouse_id = (
+ self.warehouse_id and self.warehouse_id.id or
self.env['ir.default'].get('sale.order', 'warehouse_id', company_id=values.get('company_id')) or
self.env['ir.default'].get('sale.order', 'warehouse_id') or
self.env['stock.warehouse'].sudo().search([('company_id', '=', values['company_id'])], limit=1).id
diff --git a/addons/website_sale_stock/tests/__init__.py b/addons/website_sale_stock/tests/__init__.py
new file mode 100644
index 00000000000..778ed8c0ec7
--- /dev/null
+++ b/addons/website_sale_stock/tests/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import test_website_sale_stock_product_warehouse
diff --git a/addons/website_sale_stock/tests/test_website_sale_stock_product_warehouse.py b/addons/website_sale_stock/tests/test_website_sale_stock_product_warehouse.py
new file mode 100644
index 00000000000..9ae58e320f0
--- /dev/null
+++ b/addons/website_sale_stock/tests/test_website_sale_stock_product_warehouse.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo.addons.website_sale.tests.test_website_sale_product_attribute_value_config import TestWebsiteSaleProductAttributeValueConfig
+
+
+class TestWebsiteSaleStockProductWarehouse(TestWebsiteSaleProductAttributeValueConfig):
+
+ def test_get_combination_info(self):
+ """ Checked that correct product quantity is shown in website according to the warehouse
+ which is set in current website.
+ - Create two warehouse
+ - Create two stockable products
+ - Update quantity of Product A in Warehouse 1
+ - Update quantity of Product B in Warehouse 2
+ - Set Warehouse 1 in website
+ - Check available quantity of Product A and Product B in website
+ Product A should be available in the website as it is available in warehouse 1 but Product B
+ should not be available in website as it is stored in warehouse 2.
+ """
+ # Create two warehouses
+ warehouse_1 = self.env['stock.warehouse'].create({
+ 'name': 'Warehouse 1',
+ 'code': 'WH1'
+ })
+ warehouse_2 = self.env['stock.warehouse'].create({
+ 'name': 'Warehouse 2',
+ 'code': 'WH2'
+ })
+
+ # Create two stockable products
+ product_1 = self.env['product.product'].create({
+ 'name': 'Product A',
+ 'inventory_availability': 'always',
+ 'type': 'product',
+ 'default_code': 'E-COM1',
+ })
+
+ product_2 = self.env['product.product'].create({
+ 'name': 'Product B',
+ 'inventory_availability': 'always',
+ 'type': 'product',
+ 'default_code': 'E-COM2',
+ })
+
+ # Update quantity of Product A in Warehouse 1
+ inventory_wizard = self.env['stock.change.product.qty'].create({
+ 'product_id': product_1.id,
+ 'new_quantity': 10.0,
+ 'location_id': warehouse_1.lot_stock_id.id,
+ })
+ inventory_wizard.change_product_qty()
+
+ # Update quantity of Product B in Warehouse 2
+ inventory_wizard = self.env['stock.change.product.qty'].create({
+ 'product_id': product_2.id,
+ 'new_quantity': 10.0,
+ 'location_id': warehouse_2.lot_stock_id.id,
+ })
+ inventory_wizard.change_product_qty()
+
+ # Get current website and set warehouse_id of Warehouse 1
+ current_website = self.env['website'].get_current_website()
+ current_website.warehouse_id = warehouse_1
+
+ product = product_1.with_context(website_id=current_website.id)
+ combination_info = product.product_tmpl_id.with_context(website_sale_stock_get_quantity=True)._get_combination_info()
+
+ # Check available quantity of product is according to warehouse
+ self.assertEqual(combination_info['virtual_available'], 10, "10 units of Product A should be available in warehouse 1.")
+
+ product = product_2.with_context(website_id=current_website.id)
+ combination_info = product.product_tmpl_id.with_context(website_sale_stock_get_quantity=True)._get_combination_info()
+
+ # Check available quantity of product is according to warehouse
+ self.assertEqual(combination_info['virtual_available'], 0, "Product B should not be available in warehouse 1.")
diff --git a/addons/website_sale_stock/views/res_config_settings_views.xml b/addons/website_sale_stock/views/res_config_settings_views.xml
index 1bbd33ef454..58dd9ce059f 100644
--- a/addons/website_sale_stock/views/res_config_settings_views.xml
+++ b/addons/website_sale_stock/views/res_config_settings_views.xml
@@ -12,12 +12,16 @@
<xpath expr="//div[@name='stock_inventory_availability']" position="inside">
<div class="content-group">
+ <div class="row mt16" attrs="{'invisible': [('group_stock_multi_warehouses', '=', False)]}">
+ <label for="website_warehouse_id" string="Warehouse" class="col-lg-3 o_light_label" />
+ <field name="website_warehouse_id"/>
+ </div>
<div class="row mt16" title="Default availability mode set on newly created storable products. This can be changed at the product level.">
- <label for="inventory_availability" string="Default Mode" class="col-lg-3 o_light_label" />
+ <label for="inventory_availability" string="Mode" class="col-lg-3 o_light_label" />
<field name="inventory_availability" string="Inventory"/>
</div><br/>
<div class="row" attrs="{'invisible': [('inventory_availability', '!=', 'threshold')]}">
- <label for="available_threshold" string="Default threshold" class="col-lg-3 o_light_label" />
+ <label for="available_threshold" string="Threshold" class="col-lg-3 o_light_label" />
<field name="available_threshold" class="oe_inline" attrs="{'required': [('inventory_availability', '=', 'threshold')]}"/>
</div>
</div>