mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[MIG] stock_inventory_preparation_filter: Migration to 10.0
This commit is contained in:
@@ -20,7 +20,7 @@ Usage
|
||||
|
||||
.. 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
|
||||
:target: https://runbot.odoo-community.org/runbot/153/10.0
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
@@ -28,11 +28,7 @@ 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:%20
|
||||
stock_inventory_preparation_filter%0Aversion:%20
|
||||
8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
help us smash it by providing detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
@@ -41,7 +37,8 @@ Contributors
|
||||
------------
|
||||
|
||||
* Oihane Crucelaegui <oihanecrucelaegi@avanzosc.es>
|
||||
* Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>
|
||||
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
* David Vidal <david.vidal@tecnativa.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import models
|
||||
|
||||
25
stock_inventory_preparation_filter/__manifest__.py
Normal file
25
stock_inventory_preparation_filter/__manifest__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015 AvanzOSC - Oihane Crucelaegi
|
||||
# Copyright 2015 Tecnativa - Pedro M. Baeza
|
||||
# Copyright 2017 Tecnativa - David Vidal
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "Extended Inventory Preparation Filters",
|
||||
"version": "10.0.1.0.0",
|
||||
"depends": [
|
||||
"stock",
|
||||
],
|
||||
"author": "AvanzOSC,"
|
||||
"Tecnativa,"
|
||||
"Odoo Community Association (OCA)",
|
||||
"category": "Inventory, Logistic, Storage",
|
||||
"website": "http://github.com/OCA/stock-logistics-workflow",
|
||||
"summary": "More filters for inventory adjustments",
|
||||
"data": [
|
||||
"views/stock_inventory_view.xml",
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
'installable': True,
|
||||
"license": 'AGPL-3',
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
"name": "Extended Inventory Preparation Filters",
|
||||
"version": "8.0.1.0.0",
|
||||
"depends": [
|
||||
"stock",
|
||||
],
|
||||
"author": "OdooMRP team,"
|
||||
"AvanzOSC,"
|
||||
"Serv. Tecnol. Avanzados - Pedro M. Baeza,"
|
||||
"Odoo Community Association (OCA)",
|
||||
"contributors": [
|
||||
"Oihane Crucelaegui <oihanecrucelaegi@avanzosc.es>",
|
||||
"Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>",
|
||||
],
|
||||
"category": "Inventory, Logistic, Storage",
|
||||
"website": "http://www.odoomrp.com",
|
||||
"summary": "More filters for inventory adjustments",
|
||||
"data": [
|
||||
"views/stock_inventory_view.xml",
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * stock_inventory_preparation_filters
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0rc1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-07-30 08:58+0000\n"
|
||||
"PO-Revision-Date: 2014-07-30 08:58+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: view:stock.inventory:0
|
||||
#: field:stock.inventory,empty_line_ids:0
|
||||
msgid "Capture Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory,categ_ids:0
|
||||
msgid "Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,create_uid:0
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,create_date:0
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: code:addons/stock_inventory_preparation_filters/models/stock_inventory.py:66
|
||||
#, python-format
|
||||
msgid "Empty list"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,id:0
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: model:ir.model,name:stock_inventory_preparation_filters.model_stock_inventory
|
||||
#: field:stock.inventory.line.empty,inventory_id:0
|
||||
msgid "Inventory"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: view:stock.inventory:0
|
||||
msgid "Inventory Details"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,write_uid:0
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,write_date:0
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory,lot_ids:0
|
||||
msgid "Lots"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,product_code:0
|
||||
msgid "Product Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory,product_ids:0
|
||||
msgid "Products"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: field:stock.inventory.line.empty,product_qty:0
|
||||
msgid "Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: code:addons/stock_inventory_preparation_filters/models/stock_inventory.py:61
|
||||
#, python-format
|
||||
msgid "Selected Categories"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: code:addons/stock_inventory_preparation_filters/models/stock_inventory.py:65
|
||||
#, python-format
|
||||
msgid "Selected Lots"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: code:addons/stock_inventory_preparation_filters/models/stock_inventory.py:62
|
||||
#, python-format
|
||||
msgid "Selected Products"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_inventory_preparation_filters
|
||||
#: model:ir.model,name:stock_inventory_preparation_filters.model_stock_inventory_line_empty
|
||||
msgid "stock.inventory.line.empty"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
#
|
||||
##############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import stock_inventory
|
||||
|
||||
@@ -1,68 +1,51 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
#
|
||||
##############################################################################
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015 AvanzOSC - Oihane Crucelaegi
|
||||
# Copyright 2015 Tecnativa - Pedro M. Baeza
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from odoo import _, api, fields, models
|
||||
|
||||
|
||||
class StockInventoryEmptyLines(models.Model):
|
||||
_name = 'stock.inventory.line.empty'
|
||||
|
||||
product_code = fields.Char(
|
||||
string='Product Code', size=64, required=True)
|
||||
string='Product Code',
|
||||
required=True,
|
||||
)
|
||||
product_qty = fields.Float(
|
||||
string='Quantity', required=True, default=1.0)
|
||||
string='Quantity',
|
||||
required=True,
|
||||
default=1.0,
|
||||
)
|
||||
inventory_id = fields.Many2one(
|
||||
comodel_name='stock.inventory', string='Inventory',
|
||||
required=True, ondelete="cascade")
|
||||
|
||||
|
||||
class StockInventoryFake(object):
|
||||
def __init__(self, inventory, product=None, lot=None):
|
||||
self.id = inventory.id
|
||||
self.location_id = inventory.location_id
|
||||
self.product_id = product
|
||||
self.lot_id = lot
|
||||
self.partner_id = inventory.partner_id
|
||||
self.package_id = inventory.package_id
|
||||
comodel_name='stock.inventory',
|
||||
string='Inventory',
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
|
||||
|
||||
class StockInventory(models.Model):
|
||||
_inherit = 'stock.inventory'
|
||||
|
||||
@api.model
|
||||
def _get_available_filters(self):
|
||||
def _selection_filter(self):
|
||||
"""This function will return the list of filters allowed according to
|
||||
the options checked in 'Settings/Warehouse'.
|
||||
|
||||
:return: list of tuple
|
||||
"""
|
||||
res_filters = super(StockInventory, self)._get_available_filters()
|
||||
res_filters = super(StockInventory, self)._selection_filter()
|
||||
res_filters.append(('categories', _('Selected Categories')))
|
||||
res_filters.append(('products', _('Selected Products')))
|
||||
for res_filter in res_filters:
|
||||
if res_filter[0] == 'lot':
|
||||
res_filters.append(('lots', _('Selected Lots')))
|
||||
break
|
||||
res_filters.append(('empty', _('Empty list')))
|
||||
return res_filters
|
||||
|
||||
filter = fields.Selection(
|
||||
selection=_get_available_filters, string='Selection Filter',
|
||||
required=True)
|
||||
categ_ids = fields.Many2many(
|
||||
comodel_name='product.category', relation='rel_inventories_categories',
|
||||
column1='inventory_id', column2='category_id', string='Categories')
|
||||
@@ -77,59 +60,56 @@ class StockInventory(models.Model):
|
||||
string='Capture Lines')
|
||||
|
||||
@api.model
|
||||
def _get_inventory_lines(self, inventory):
|
||||
def _get_inventory_lines_values(self):
|
||||
self.ensure_one()
|
||||
vals = []
|
||||
product_tmpl_obj = self.env['product.template']
|
||||
product_obj = self.env['product.product']
|
||||
if inventory.filter in ('categories', 'products'):
|
||||
products = product_obj
|
||||
if inventory.filter == 'categories':
|
||||
product_tmpls = product_tmpl_obj.search(
|
||||
[('categ_id', 'in', inventory.categ_ids.ids)])
|
||||
products = product_obj.search(
|
||||
[('product_tmpl_id', 'in', product_tmpls.ids)])
|
||||
elif inventory.filter == 'products':
|
||||
products = inventory.product_ids
|
||||
for product in products:
|
||||
fake_inventory = StockInventoryFake(inventory, product=product)
|
||||
vals += super(StockInventory, self)._get_inventory_lines(
|
||||
fake_inventory)
|
||||
elif inventory.filter == 'lots':
|
||||
for lot in inventory.lot_ids:
|
||||
fake_inventory = StockInventoryFake(inventory, lot=lot)
|
||||
vals += super(StockInventory, self)._get_inventory_lines(
|
||||
fake_inventory)
|
||||
elif inventory.filter == 'empty':
|
||||
tmp_lines = {}
|
||||
empty_line_obj = self.env['stock.inventory.line.empty']
|
||||
for line in inventory.empty_line_ids:
|
||||
if line.product_code in tmp_lines:
|
||||
tmp_lines[line.product_code] += line.product_qty
|
||||
else:
|
||||
tmp_lines[line.product_code] = line.product_qty
|
||||
inventory.empty_line_ids.unlink()
|
||||
for product_code in tmp_lines.keys():
|
||||
inventory = self.new(self._convert_to_write(self._cache))
|
||||
if self.filter in ('categories', 'products'):
|
||||
if self.filter == 'categories':
|
||||
products = product_obj.search([
|
||||
'|', ('default_code', '=', product_code),
|
||||
('ean13', '=', product_code),
|
||||
('product_tmpl_id.categ_id', 'in', self.categ_ids.ids)
|
||||
])
|
||||
if products:
|
||||
product = products[0]
|
||||
fake_inventory = StockInventoryFake(
|
||||
inventory, product=product)
|
||||
values = super(StockInventory, self)._get_inventory_lines(
|
||||
fake_inventory)
|
||||
if values:
|
||||
values[0]['product_qty'] = tmp_lines[product_code]
|
||||
else:
|
||||
empty_line_obj.create(
|
||||
{
|
||||
'product_code': product_code,
|
||||
'product_qty': tmp_lines[product_code],
|
||||
'inventory_id': inventory.id,
|
||||
})
|
||||
vals += values
|
||||
else: # filter = 'products'
|
||||
products = self.product_ids
|
||||
inventory.filter = 'product'
|
||||
for product in products:
|
||||
inventory.product_id = product
|
||||
vals += super(StockInventory,
|
||||
inventory)._get_inventory_lines_values()
|
||||
elif self.filter == 'lots':
|
||||
inventory.filter = 'lot'
|
||||
for lot in self.lot_ids:
|
||||
inventory.lot_id = lot
|
||||
vals += super(StockInventory,
|
||||
inventory)._get_inventory_lines_values()
|
||||
elif self.filter == 'empty':
|
||||
tmp_lines = {}
|
||||
for line in self.empty_line_ids:
|
||||
tmp_lines.setdefault(line.product_code, 0)
|
||||
tmp_lines[line.product_code] += line.product_qty
|
||||
self.empty_line_ids.unlink()
|
||||
inventory.filter = 'product'
|
||||
for product_code in tmp_lines.keys():
|
||||
product = product_obj.search([
|
||||
'|',
|
||||
('default_code', '=', product_code),
|
||||
('barcode', '=', product_code),
|
||||
], limit=1)
|
||||
if not product:
|
||||
continue
|
||||
inventory.product_id = product
|
||||
values = super(StockInventory,
|
||||
inventory)._get_inventory_lines_values()
|
||||
if values:
|
||||
values[0]['product_qty'] = tmp_lines[product_code]
|
||||
else:
|
||||
vals += [{
|
||||
'product_id': product.id,
|
||||
'product_qty': tmp_lines[product_code],
|
||||
'location_id': self.location_id.id,
|
||||
}]
|
||||
vals += values
|
||||
else:
|
||||
vals = super(StockInventory, self)._get_inventory_lines(
|
||||
inventory)
|
||||
vals = super(StockInventory, self)._get_inventory_lines_values()
|
||||
return vals
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from . import test_stock_inventory_preparation_filter
|
||||
|
||||
@@ -1,89 +1,101 @@
|
||||
##############################################################################
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import openerp.tests.common as common
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015 AvanzOSC - Oihane Crucelaegi
|
||||
# Copyright 2015 Tecnativa - Pedro M. Baeza
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
@common.at_install(False)
|
||||
@common.post_install(True)
|
||||
class TestStockInventoryPreparationFilterCategories(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestStockInventoryPreparationFilterCategories, self).setUp()
|
||||
self.inventory_model = self.env['stock.inventory']
|
||||
# Create a category
|
||||
self.category = self.env['product.category'].create(
|
||||
{
|
||||
'name': 'Category for inventory',
|
||||
'type': 'normal',
|
||||
})
|
||||
# Create some categories
|
||||
self.category = self.env['product.category'].create({
|
||||
'name': 'Category for inventory',
|
||||
'type': 'normal',
|
||||
})
|
||||
self.category2 = self.env['product.category'].create({
|
||||
'name': 'Category for inventory 2',
|
||||
'type': 'normal',
|
||||
})
|
||||
# Create some products in the category
|
||||
self.product1 = self.env['product.product'].create(
|
||||
{
|
||||
'name': 'Product for inventory 1',
|
||||
'type': 'product',
|
||||
'categ_id': self.category.id,
|
||||
'default_code': 'PROD1',
|
||||
}
|
||||
)
|
||||
self.product2 = self.env['product.product'].create(
|
||||
{
|
||||
'name': 'Product for inventory 2',
|
||||
'type': 'product',
|
||||
'categ_id': self.category.id,
|
||||
'default_code': 'PROD2',
|
||||
}
|
||||
)
|
||||
self.product1 = self.env['product.product'].create({
|
||||
'name': 'Product for inventory 1',
|
||||
'type': 'product',
|
||||
'categ_id': self.category.id,
|
||||
'default_code': 'PROD1-TEST',
|
||||
})
|
||||
self.product2 = self.env['product.product'].create({
|
||||
'name': 'Product for inventory 2',
|
||||
'type': 'product',
|
||||
'categ_id': self.category.id,
|
||||
'default_code': 'PROD2-TEST',
|
||||
})
|
||||
self.product3 = self.env['product.product'].create({
|
||||
'name': 'Product for inventory 3',
|
||||
'type': 'product',
|
||||
'categ_id': self.category.id,
|
||||
'default_code': 'PROD3-TEST',
|
||||
})
|
||||
self.product_lot = self.env['product.product'].create({
|
||||
'name': 'Product for inventory with lots',
|
||||
'type': 'product',
|
||||
'categ_id': self.category2.id,
|
||||
})
|
||||
self.lot = self.env['stock.production.lot'].create({
|
||||
'name': 'Lot test',
|
||||
'product_id': self.product_lot.id,
|
||||
})
|
||||
# Add user to lot tracking group
|
||||
self.env.user.groups_id = [
|
||||
(4, self.env.ref('stock.group_production_lot').id),
|
||||
]
|
||||
# And have some stock in a location
|
||||
self.location = self.env['stock.location'].create(
|
||||
{
|
||||
'name': 'Inventory tests',
|
||||
'usage': 'internal',
|
||||
}
|
||||
)
|
||||
inventory = self.inventory_model.create(
|
||||
{
|
||||
'name': 'Product1 inventory',
|
||||
'filter': 'product',
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'product_id': self.product1.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"product.product_uom_unit").id,
|
||||
'product_qty': 2.0,
|
||||
'location_id': self.location.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': self.product2.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"product.product_uom_unit").id,
|
||||
'product_qty': 4.0,
|
||||
'location_id': self.location.id,
|
||||
}),
|
||||
],
|
||||
})
|
||||
self.location = self.env['stock.location'].create({
|
||||
'name': 'Inventory tests',
|
||||
'usage': 'internal',
|
||||
})
|
||||
inventory = self.inventory_model.create({
|
||||
'name': 'Product1 inventory',
|
||||
'filter': 'product',
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'product_id': self.product1.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"product.product_uom_unit").id,
|
||||
'product_qty': 2.0,
|
||||
'location_id': self.location.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': self.product2.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"product.product_uom_unit").id,
|
||||
'product_qty': 4.0,
|
||||
'location_id': self.location.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': self.product_lot.id,
|
||||
'product_uom_id': self.env.ref(
|
||||
"product.product_uom_unit").id,
|
||||
'product_qty': 6.0,
|
||||
'location_id': self.location.id,
|
||||
'prod_lot_id': self.lot.id,
|
||||
}),
|
||||
],
|
||||
})
|
||||
inventory.action_done()
|
||||
|
||||
def test_inventory_category_filter(self):
|
||||
inventory = self.inventory_model.create(
|
||||
{
|
||||
'name': 'Category inventory',
|
||||
'filter': 'categories',
|
||||
'location_id': self.location.id,
|
||||
'categ_ids': [(6, 0, [self.category.id])],
|
||||
}
|
||||
)
|
||||
inventory = self.inventory_model.create({
|
||||
'name': 'Category inventory',
|
||||
'filter': 'categories',
|
||||
'location_id': self.location.id,
|
||||
'categ_ids': [(6, 0, [self.category.id])],
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
self.assertEqual(len(inventory.line_ids), 2)
|
||||
line1 = inventory.line_ids[0]
|
||||
@@ -115,26 +127,49 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase):
|
||||
self.assertEqual(line2.theoretical_qty, 4.0)
|
||||
self.assertEqual(line2.location_id, self.location)
|
||||
|
||||
def test_inventory_empty_filter(self):
|
||||
def test_inventory_lots_filter(self):
|
||||
inventory = self.inventory_model.create(
|
||||
{
|
||||
'name': 'Products inventory',
|
||||
'filter': 'empty',
|
||||
'filter': 'lots',
|
||||
'location_id': self.location.id,
|
||||
'empty_line_ids': [
|
||||
(0, 0, {
|
||||
'product_code': 'PROD1',
|
||||
'product_qty': 3.0,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_code': 'PROD2',
|
||||
'product_qty': 7.0,
|
||||
}),
|
||||
],
|
||||
'lot_ids': [(6, 0, [self.lot.id, ])],
|
||||
}
|
||||
)
|
||||
inventory.prepare_inventory()
|
||||
self.assertEqual(len(inventory.line_ids), 2)
|
||||
self.assertEqual(len(inventory.line_ids), 1)
|
||||
line1 = inventory.line_ids[0]
|
||||
self.assertEqual(line1.product_id, self.product_lot)
|
||||
self.assertEqual(line1.prod_lot_id, self.lot)
|
||||
self.assertEqual(line1.theoretical_qty, 6.0)
|
||||
self.assertEqual(line1.location_id, self.location)
|
||||
|
||||
def test_inventory_empty_filter(self):
|
||||
inventory = self.inventory_model.create({
|
||||
'name': 'Products inventory',
|
||||
'filter': 'empty',
|
||||
'location_id': self.location.id,
|
||||
'empty_line_ids': [
|
||||
(0, 0, {
|
||||
'product_code': 'PROD1-TEST',
|
||||
'product_qty': 3.0,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_code': 'PROD2-TEST',
|
||||
'product_qty': 7.0,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_code': 'PROD3-TEST',
|
||||
'product_qty': 5.0,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_code': 'UNEXISTING-CODE',
|
||||
'product_qty': 0.0,
|
||||
}),
|
||||
],
|
||||
})
|
||||
inventory.prepare_inventory()
|
||||
self.assertEqual(len(inventory.line_ids), 3)
|
||||
line1 = inventory.line_ids[0]
|
||||
self.assertEqual(line1.product_id, self.product1)
|
||||
self.assertEqual(line1.theoretical_qty, 2.0)
|
||||
@@ -145,3 +180,8 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase):
|
||||
self.assertEqual(line2.theoretical_qty, 4.0)
|
||||
self.assertEqual(line2.product_qty, 7.0)
|
||||
self.assertEqual(line2.location_id, self.location)
|
||||
line3 = inventory.line_ids[2]
|
||||
self.assertEqual(line3.product_id, self.product3)
|
||||
self.assertEqual(line3.theoretical_qty, 0.0)
|
||||
self.assertEqual(line3.product_qty, 5.0)
|
||||
self.assertEqual(line3.location_id, self.location)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="stock_inventory_form">
|
||||
<field name="name">stock.inventory.form</field>
|
||||
<field name="model">stock.inventory</field>
|
||||
@@ -10,9 +10,9 @@
|
||||
<notebook position="attributes">
|
||||
<attribute name="attrs" />
|
||||
</notebook>
|
||||
<page string="Inventory Details" position="attributes">
|
||||
<xpath expr="//button[@name='reset_real_qty']/ancestor::*[position()=1]" position="attributes">
|
||||
<attribute name="attrs">{'invisible':[('state','=','draft')]}</attribute>
|
||||
</page>
|
||||
</xpath>
|
||||
<notebook position="before">
|
||||
<group>
|
||||
<field name="categ_ids"
|
||||
@@ -41,5 +41,4 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user