Merge pull request #144 from cyrilgdn/9.0-stock_quant_merge

[9.0] new v8 unported module: stock_quant_merge
This commit is contained in:
Alexandre Fayolle
2016-03-21 14:42:15 +01:00
14 changed files with 381 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
.. 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
===========
Quant merge
===========
Odoo splits quants each time a reservation is done: this module makes Odoo
merge them back if they still meet the following requirements:
* same product
* same serial number/lot
* same location
* same package
Usage
=====
The merge is done automatically when a reservation is undone. No user intervention is needed.
.. 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:%20
stock_quant_merge%0Aversion:%20
8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Oihane Crucelaegui <oihanecrucelaegi@avanzosc.es>
* Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>
* Ana Juaristi <ajuaristio@gmail.com>
* Lionel Sausin <ls@numerigraphe.com>
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.

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# © 2015 OdooMRP team
# © 2015 AvanzOSC
# © 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models

View File

@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# © 2015 OdooMRP team
# © 2015 AvanzOSC
# © 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Stock - Quant merge",
"version": "8.0.1.0.0",
"depends": [
"stock",
],
"author": "OdooMRP team,"
"AvanzOSC,"
"Serv. Tecnol. Avanzados - Pedro M. Baeza,"
"Odoo Community Association (OCA)",
"website": "http://www.odoomrp.com",
"category": "Warehouse Management",
"installable": False,
"license": "AGPL-3",
"images": [],
}

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-warehouse (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-01-14 01:38+0000\n"
"PO-Revision-Date: 2015-12-03 11:29+0000\n"
"Last-Translator: <>\n"
"Language-Team: German (http://www.transifex.com/oca/OCA-stock-logistics-warehouse-8-0/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Quants"

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-warehouse (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-12-04 01:47+0000\n"
"PO-Revision-Date: 2015-12-03 11:29+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>\n"
"Language-Team: English (http://www.transifex.com/oca/OCA-stock-logistics-warehouse-8-0/language/en/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: en\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Quants"

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: odoomrp-wip (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-07 10:45+0000\n"
"PO-Revision-Date: 2015-10-09 10:50+0000\n"
"Last-Translator: Pedro M. Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/oca/odoomrp-wip-8-0/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Quants"

View File

@@ -0,0 +1,24 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
# Miku Laitinen <miku.laitinen@gmail.com>, 2016
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-warehouse (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-03-04 07:59+0000\n"
"PO-Revision-Date: 2016-03-05 08:46+0000\n"
"Last-Translator: Miku Laitinen <miku.laitinen@gmail.com>\n"
"Language-Team: Finnish (http://www.transifex.com/oca/OCA-stock-logistics-warehouse-8-0/language/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: fi\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Määrät"

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: odoomrp-wip (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-07 10:45+0000\n"
"PO-Revision-Date: 2015-09-10 16:35+0000\n"
"Last-Translator: <>\n"
"Language-Team: French (http://www.transifex.com/oca/odoomrp-wip-8-0/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Quants"

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: odoomrp-wip (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-07 10:45+0000\n"
"PO-Revision-Date: 2015-10-09 03:19+0000\n"
"Last-Translator: danimaribeiro <danimaribeiro@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/odoomrp-wip-8-0/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Quants"

View File

@@ -0,0 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_quant_merge
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: odoomrp-wip (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-10-07 10:45+0000\n"
"PO-Revision-Date: 2015-09-20 19:06+0000\n"
"Last-Translator: Matjaž Mozetič <m.mozetic@matmoz.si>\n"
"Language-Team: Slovenian (http://www.transifex.com/oca/odoomrp-wip-8-0/language/sl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: sl\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
#. module: stock_quant_merge
#: model:ir.model,name:stock_quant_merge.model_stock_quant
msgid "Quants"
msgstr "Kvant"

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# © 2015 OdooMRP team
# © 2015 AvanzOSC
# © 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import stock

View File

@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# © 2015 OdooMRP team
# © 2015 AvanzOSC
# © 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api
class StockQuant(models.Model):
_inherit = 'stock.quant'
@api.multi
def _mergeable_domain(self):
"""Return the quants which may be merged with the current record"""
self.ensure_one()
return [('id', '!=', self.id),
('product_id', '=', self.product_id.id),
('lot_id', '=', self.lot_id.id),
('package_id', '=', self.package_id.id),
('location_id', '=', self.location_id.id),
('reservation_id', '=', False),
('propagated_from_id', '=', self.propagated_from_id.id)]
@api.multi
def merge_stock_quants(self):
# Get a copy of the recorset
pending_quants = self.browse(self.ids)
for quant2merge in self.filtered(lambda x: not x.reservation_id):
if quant2merge in pending_quants:
quants = self.search(quant2merge._mergeable_domain())
cont = 1
cost = quant2merge.cost
for quant in quants:
if (self._get_latest_move(quant2merge) ==
self._get_latest_move(quant)):
quant2merge.sudo().qty += quant.qty
cost += quant.cost
cont += 1
pending_quants -= quant
quant.with_context(force_unlink=True).sudo().unlink()
quant2merge.sudo().cost = cost / cont
@api.model
def quants_unreserve(self, move):
quants = move.reserved_quant_ids
super(StockQuant, self).quants_unreserve(move)
quants.merge_stock_quants()

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2014 Numérigraphe SARL
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_merge

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# © 2015 Numérigraphe SARL
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
class TestMerge(TransactionCase):
"""Test the potential quantity on a product with a multi-line BoM"""
def setUp(self):
super(TestMerge, self).setUp()
# Get the warehouses
self.wh_main = self.browse_ref('stock.warehouse0')
self.wh_ch = self.browse_ref('stock.stock_warehouse_shop0')
# Get a product
self.product = self.browse_ref('product.product_product_4')
# Zero out the inventory of the product
inventory = self.env['stock.inventory'].create(
{'name': 'Remove product for test',
'location_id': self.ref('stock.stock_location_locations'),
'filter': 'product',
'product_id': self.product.id})
inventory.prepare_inventory()
inventory.reset_real_qty()
inventory.action_done()
# Make sure we have some products in Chicago
inventory = self.env['stock.inventory'].create(
{'name': 'Test stock available for reservation',
'location_id': self.wh_ch.lot_stock_id.id,
'filter': 'none'})
inventory.prepare_inventory()
self.env['stock.inventory.line'].create({
'inventory_id': inventory.id,
'product_id': self.product.id,
'location_id': self.wh_ch.lot_stock_id.id,
'product_qty': 10.0})
inventory.action_done()
def test_merge(self):
quant_obj = self.env['stock.quant']
domain = [('location_id', '=', self.wh_ch.lot_stock_id.id),
('product_id', '=', self.product.id)]
quants = quant_obj.search(domain)
self.assertEqual(len(quants), 1, "There should be 1 quant")
# Make a reservation to split the quant
move = self.env['stock.move'].create(
{'name': 'Test move',
'product_id': self.product.id,
'location_id': self.wh_ch.lot_stock_id.id,
'location_dest_id': self.wh_main.lot_stock_id.id,
'product_uom_qty': 5.0,
'product_uom': self.product.uom_id.id})
move.action_confirm()
move.action_assign()
quants = quant_obj.search(domain)
self.assertEqual(len(quants), 2, "There should be 2 quants")
# Cancel the move : the quants should be merged back together
move.action_cancel()
quants = quant_obj.search(domain)
self.assertEqual(len(quants), 1, "There should be 1 quant")