This commit is contained in:
guohuadeng
2018-07-27 11:50:38 +08:00
parent a097a79bc5
commit e667248c8b
28 changed files with 1679 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
.. 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
=============
Split picking
=============
This module adds a "Split" button on the outgoing pickings form.
It works like the classical picking Transfer but it leaves both pickings
(picking and its backorder) as confirmed without processing the transfer.
Installation
============
This module only needs `stock` module.
Usage
=====
To use this module, you need to:
#. Go to **Inventory** dashboard and open any picking.
#. If picking state is **available** you can see an split button.
#. On the "Operations" tab, fill the field "Done" to the quantity you want to
split for each line.
#. If you click on **Split** button, wizard will split current picking into
two different pickings depends on quantity done you entered above.
#. Both pickings remain confirmed.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/154/11.0
Known issues / Roadmap
======================
* When splitting a picking in an unassigned state, wizard won't
be auto completed with picking lines.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/stock-logistics-workflow/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.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.png>`_.
Contributors
------------
* Nicolas Bessi <nicolas.bessi@camptocamp.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Vicent Cubells <vicent.cubells@tecnativa.com>
* Julien Coux <julien.coux@camptocamp.com>
Do not contact contributors directly about support or help with technical issues.
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,4 @@
# Copyright 2013-2015 Camptocamp SA - Nicolas Bessi
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models

View File

@@ -0,0 +1,22 @@
# Copyright 2013-2015 Camptocamp SA - Nicolas Bessi
# Copyright 2013-2015 Camptocamp SA - Guewen Baconnier
# Copyright 2013-2015 Camptocamp SA - Yannick Vaucher
# Copyright 2017 Tecnativa - Vicent Cubells
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'App Split picking',
'summary': 'Split a picking in two not transferred pickings',
'version': '11.0.1.0.0',
'category': 'Inventory',
'author': "Camptocamp, "
"Tecnativa, "
"Odoo Community Association (OCA)",
'license': 'AGPL-3',
'website': 'https://github.com/OCA/stock-logistics-workflow',
'depends': [
'stock',
],
'data': [
'views/stock_partial_picking.xml',
],
}

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2018-06-30 05:01+0000\n"
"Last-Translator: Osoul <baruni@osoul.ly>\n"
"Language-Team: none\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 3.0.1\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr "هل أنت متأكد أنّك تريد تقسيم الشحنة؟"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "تقسيم الشحنة"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid "The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d\">%s</a> has been created."
msgstr ""
"تم إنشاء الشحنة المؤجّلة <a href=\"#\" data-oe-model=\"stock.picking\" data-"
"oe-id=\"%d\">%s</a>."
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "نقل"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid "You must enter done quantity in order to split your picking in several ones."
msgstr ""
"يجب إدخال الكميات المنتهية لكي تتمكن من تقسيم الشحنة الحالية إلى أكثر من "
"شحنة."

View File

@@ -0,0 +1,58 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-workflow (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-31 09:53+0000\n"
"PO-Revision-Date: 2015-10-21 16:34+0000\n"
"Last-Translator: <>\n"
"Language-Team: Catalan (http://www.transifex.com/oca/OCA-stock-logistics-"
"workflow-8-0/language/ca/)\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
#~ msgid "Stock Move"
#~ msgstr "Moure l'estoc"

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "Aufteilung"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Lieferung vornehmen"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Transferir"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,58 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-workflow (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-03 06:09+0000\n"
"PO-Revision-Date: 2015-10-21 16:34+0000\n"
"Last-Translator: <>\n"
"Language-Team: Spanish (Mexico) (http://www.transifex.com/oca/OCA-stock-"
"logistics-workflow-8-0/language/es_MX/)\n"
"Language: es_MX\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
#~ msgid "Stock Move"
#~ msgstr "Movimiento bursátil"

View File

@@ -0,0 +1,61 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-workflow (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-25 08:38+0000\n"
"PO-Revision-Date: 2015-10-21 16:34+0000\n"
"Last-Translator: <>\n"
"Language-Team: Finnish (http://www.transifex.com/oca/OCA-stock-logistics-"
"workflow-8-0/language/fi/)\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
#~ msgid "Picking List"
#~ msgstr "Keräilylista"
#~ msgid "Stock Move"
#~ msgstr "Varastosiirto"

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "Diviser"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Transfert"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,59 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# Bole <bole@dajmi5.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-02-28 03:51+0000\n"
"PO-Revision-Date: 2018-02-28 03:51+0000\n"
"Last-Translator: Bole <bole@dajmi5.com>, 2018\n"
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
#, fuzzy
msgid "Are you sure you want to split current picking?"
msgstr "Jeste li sigurni da želite razdijeliti trenutnu otpremnicu?"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr "Ovu otpremnicu označi za napraviti."
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "Razdijeli"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Prenos"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
"Morate upisati isporučenu količinu kako bi razdijelili otpremu na više "
"dokumenata."

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Trasferisci"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,56 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# Peter Hageman <hageman.p@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-17 01:29+0000\n"
"PO-Revision-Date: 2017-06-17 01:29+0000\n"
"Last-Translator: Peter Hageman <hageman.p@gmail.com>, 2017\n"
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/"
"teams/23907/nl_NL/)\n"
"Language: nl_NL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "Splitsen"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Verplaats"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# Pedro Castro Silva <pedrocs@exo.pt>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-12-18 03:48+0000\n"
"PO-Revision-Date: 2017-12-18 03:48+0000\n"
"Last-Translator: Pedro Castro Silva <pedrocs@exo.pt>, 2017\n"
"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Transferência"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,56 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/"
"teams/23907/pt_BR/)\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr "Transferir"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,56 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 02:08+0000\n"
"PO-Revision-Date: 2017-06-01 02:08+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \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_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr "Razdelitev"
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,48 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \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_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid "The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid "You must enter done quantity in order to split your picking in several ones."
msgstr ""

View File

@@ -0,0 +1,62 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
# Ahmet Altinisik <aaltinisik@altinkaya.com.tr>, 2017
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-workflow (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-31 09:53+0000\n"
"PO-Revision-Date: 2017-01-16 19:30+0000\n"
"Last-Translator: Ahmet Altinisik <aaltinisik@altinkaya.com.tr>\n"
"Language-Team: Turkish (http://www.transifex.com/oca/OCA-stock-logistics-"
"workflow-8-0/language/tr/)\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
#~ msgid "Picking List"
#~ msgstr "Toplama Listesi"
#~ msgid "Stock Move"
#~ msgstr "Stok hareketi"

View File

@@ -0,0 +1,61 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_split_picking
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: stock-logistics-workflow (8.0)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-12-31 09:53+0000\n"
"PO-Revision-Date: 2015-10-21 16:34+0000\n"
"Last-Translator: <>\n"
"Language-Team: Turkish (Turkey) (http://www.transifex.com/oca/OCA-stock-"
"logistics-workflow-8-0/language/tr_TR/)\n"
"Language: tr_TR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Are you sure you want to split current picking?"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:22
#, python-format
msgid "Mark as todo this picking please."
msgstr ""
#. module: stock_split_picking
#: model:ir.ui.view,arch_db:stock_split_picking.view_picking_form
msgid "Split"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:65
#, python-format
msgid ""
"The backorder <a href=\"#\" data-oe-model=\"stock.picking\" data-oe-id=\"%d"
"\">%s</a> has been created."
msgstr ""
#. module: stock_split_picking
#: model:ir.model,name:stock_split_picking.model_stock_picking
msgid "Transfer"
msgstr ""
#. module: stock_split_picking
#: code:addons/stock_split_picking/models/stock_picking.py:25
#, python-format
msgid ""
"You must enter done quantity in order to split your picking in several ones."
msgstr ""
#~ msgid "Picking List"
#~ msgstr "Seçim listesi"
#~ msgid "Stock Move"
#~ msgstr "Stok hareketi"

View File

@@ -0,0 +1,4 @@
# Copyright 2013-2015 Camptocamp SA - Nicolas Bessi
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import stock_picking

View File

@@ -0,0 +1,418 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import Counter
from odoo import api, fields, models, _
from odoo.addons import decimal_precision as dp
from odoo.exceptions import UserError, ValidationError
from odoo.tools.pycompat import izip
from odoo.tools.float_utils import float_round, float_compare, float_is_zero
class StockMoveLine(models.Model):
_inherit = "stock.move.line"
@api.onchange('product_id', 'product_uom_id')
def onchange_product_id(self):
if self.product_id:
self.lots_visible = self.product_id.tracking != 'none'
if not self.product_uom_id or self.product_uom_id.category_id != self.product_id.uom_id.category_id:
if self.move_id.product_uom:
self.product_uom_id = self.move_id.product_uom.id
else:
self.product_uom_id = self.product_id.uom_id.id
res = {'domain': {'product_uom_id': [('category_id', '=', self.product_uom_id.category_id.id)]}}
else:
res = {'domain': {'product_uom_id': []}}
return res
@api.onchange('lot_name', 'lot_id')
def onchange_serial_number(self):
""" When the user is encoding a move line for a tracked product, we apply some logic to
help him. This includes:
- automatically switch `qty_done` to 1.0
- warn if he has already encoded `lot_name` in another move line
"""
res = {}
if self.product_id.tracking == 'serial':
if not self.qty_done:
self.qty_done = 1
message = None
if self.lot_name or self.lot_id:
move_lines_to_check = self._get_similar_move_lines() - self
if self.lot_name:
counter = Counter(move_lines_to_check.mapped('lot_name'))
if counter.get(self.lot_name) and counter[self.lot_name] > 1:
message = _('You cannot use the same serial number twice. Please correct the serial numbers encoded.')
elif self.lot_id:
counter = Counter(move_lines_to_check.mapped('lot_id.id'))
if counter.get(self.lot_id.id) and counter[self.lot_id.id] > 1:
message = _('You cannot use the same serial number twice. Please correct the serial numbers encoded.')
if message:
res['warning'] = {'title': _('Warning'), 'message': message}
return res
@api.onchange('qty_done')
def _onchange_qty_done(self):
""" When the user is encoding a move line for a tracked product, we apply some logic to
help him. This onchange will warn him if he set `qty_done` to a non-supported value.
"""
res = {}
if self.product_id.tracking == 'serial':
if float_compare(self.qty_done, 1.0, precision_rounding=self.move_id.product_id.uom_id.rounding) != 0:
message = _('You can only process 1.0 %s for products with unique serial number.') % self.product_id.uom_id.name
res['warning'] = {'title': _('Warning'), 'message': message}
return res
@api.constrains('qty_done')
def _check_positive_qty_done(self):
if any([ml.qty_done < 0 for ml in self]):
raise ValidationError(_('You can not enter negative quantities!'))
def _get_similar_move_lines(self):
self.ensure_one()
lines = self.env['stock.move.line']
picking_id = self.move_id.picking_id if self.move_id else self.picking_id
if picking_id:
lines |= picking_id.move_line_ids.filtered(lambda ml: ml.product_id == self.product_id and (ml.lot_id or ml.lot_name))
return lines
@api.model
def create(self, vals):
vals['ordered_qty'] = vals.get('product_uom_qty')
# If the move line is directly create on the picking view.
# If this picking is already done we should generate an
# associated done move.
if 'picking_id' in vals and 'move_id' not in vals:
picking = self.env['stock.picking'].browse(vals['picking_id'])
if picking.state == 'done':
product = self.env['product.product'].browse(vals['product_id'])
new_move = self.env['stock.move'].create({
'name': _('New Move:') + product.display_name,
'product_id': product.id,
'product_uom_qty': 'qty_done' in vals and vals['qty_done'] or 0,
'product_uom': vals['product_uom_id'],
'location_id': 'location_id' in vals and vals['location_id'] or picking.location_id.id,
'location_dest_id': 'location_dest_id' in vals and vals['location_dest_id'] or picking.location_dest_id.id,
'state': 'done',
'additional': True,
'picking_id': picking.id,
})
vals['move_id'] = new_move.id
ml = super(StockMoveLine, self).create(vals)
if ml.state == 'done':
if ml.product_id.type == 'product':
Quant = self.env['stock.quant']
quantity = ml.product_uom_id._compute_quantity(ml.qty_done, ml.move_id.product_id.uom_id,rounding_method='HALF-UP')
in_date = None
available_qty, in_date = Quant._update_available_quantity(ml.product_id, ml.location_id, -quantity, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id)
if available_qty < 0 and ml.lot_id:
# see if we can compensate the negative quants with some untracked quants
untracked_qty = Quant._get_available_quantity(ml.product_id, ml.location_id, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
if untracked_qty:
taken_from_untracked_qty = min(untracked_qty, abs(quantity))
Quant._update_available_quantity(ml.product_id, ml.location_id, -taken_from_untracked_qty, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id)
Quant._update_available_quantity(ml.product_id, ml.location_id, taken_from_untracked_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id)
Quant._update_available_quantity(ml.product_id, ml.location_dest_id, quantity, lot_id=ml.lot_id, package_id=ml.result_package_id, owner_id=ml.owner_id, in_date=in_date)
next_moves = ml.move_id.move_dest_ids.filtered(lambda move: move.state not in ('done', 'cancel'))
next_moves._do_unreserve()
next_moves._action_assign()
return ml
def write(self, vals):
""" Through the interface, we allow users to change the charateristics of a move line. If a
quantity has been reserved for this move line, we impact the reservation directly to free
the old quants and allocate the new ones.
"""
if self.env.context.get('bypass_reservation_update'):
return super(StockMoveLine, self).write(vals)
Quant = self.env['stock.quant']
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
# We forbid to change the reserved quantity in the interace, but it is needed in the
# case of stock.move's split.
# TODO Move me in the update
if 'product_uom_qty' in vals:
for ml in self.filtered(lambda m: m.state in ('partially_available', 'assigned') and m.product_id.type == 'product'):
if not ml.location_id.should_bypass_reservation():
qty_to_decrease = ml.product_qty - ml.product_uom_id._compute_quantity(vals['product_uom_qty'], ml.product_id.uom_id, rounding_method='HALF-UP')
try:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -qty_to_decrease, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
except UserError:
if ml.lot_id:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -qty_to_decrease, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
else:
raise
triggers = [
('location_id', 'stock.location'),
('location_dest_id', 'stock.location'),
('lot_id', 'stock.production.lot'),
('package_id', 'stock.quant.package'),
('result_package_id', 'stock.quant.package'),
('owner_id', 'res.partner')
]
updates = {}
for key, model in triggers:
if key in vals:
updates[key] = self.env[model].browse(vals[key])
if updates:
for ml in self.filtered(lambda ml: ml.state in ['partially_available', 'assigned'] and ml.product_id.type == 'product'):
if not ml.location_id.should_bypass_reservation():
try:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
except UserError:
if ml.lot_id:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
else:
raise
if not updates.get('location_id', ml.location_id).should_bypass_reservation():
new_product_qty = 0
try:
q = Quant._update_reserved_quantity(ml.product_id, updates.get('location_id', ml.location_id), ml.product_qty, lot_id=updates.get('lot_id', ml.lot_id),
package_id=updates.get('package_id', ml.package_id), owner_id=updates.get('owner_id', ml.owner_id), strict=True)
new_product_qty = sum([x[1] for x in q])
except UserError:
if updates.get('lot_id'):
# If we were not able to reserve on tracked quants, we can use untracked ones.
try:
q = Quant._update_reserved_quantity(ml.product_id, updates.get('location_id', ml.location_id), ml.product_qty, lot_id=False,
package_id=updates.get('package_id', ml.package_id), owner_id=updates.get('owner_id', ml.owner_id), strict=True)
new_product_qty = sum([x[1] for x in q])
except UserError:
pass
if new_product_qty != ml.product_qty:
new_product_uom_qty = self.product_id.uom_id._compute_quantity(new_product_qty, self.product_uom_id, rounding_method='HALF-UP')
ml.with_context(bypass_reservation_update=True).product_uom_qty = new_product_uom_qty
# When editing a done move line, the reserved availability of a potential chained move is impacted. Take care of running again `_action_assign` on the concerned moves.
next_moves = self.env['stock.move']
if updates or 'qty_done' in vals:
for ml in self.filtered(lambda ml: ml.move_id.state == 'done' and ml.product_id.type == 'product'):
# undo the original move line
qty_done_orig = ml.move_id.product_uom._compute_quantity(ml.qty_done, ml.move_id.product_id.uom_id, rounding_method='HALF-UP')
in_date = Quant._update_available_quantity(ml.product_id, ml.location_dest_id, -qty_done_orig, lot_id=ml.lot_id,
package_id=ml.result_package_id, owner_id=ml.owner_id)[1]
Quant._update_available_quantity(ml.product_id, ml.location_id, qty_done_orig, lot_id=ml.lot_id,
package_id=ml.package_id, owner_id=ml.owner_id, in_date=in_date)
# move what's been actually done
product_id = ml.product_id
location_id = updates.get('location_id', ml.location_id)
location_dest_id = updates.get('location_dest_id', ml.location_dest_id)
qty_done = vals.get('qty_done', ml.qty_done)
lot_id = updates.get('lot_id', ml.lot_id)
package_id = updates.get('package_id', ml.package_id)
result_package_id = updates.get('result_package_id', ml.result_package_id)
owner_id = updates.get('owner_id', ml.owner_id)
quantity = ml.move_id.product_uom._compute_quantity(qty_done, ml.move_id.product_id.uom_id, rounding_method='HALF-UP')
if not location_id.should_bypass_reservation():
ml._free_reservation(product_id, location_id, quantity, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
if not float_is_zero(quantity, precision_digits=precision):
available_qty, in_date = Quant._update_available_quantity(product_id, location_id, -quantity, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
if available_qty < 0 and lot_id:
# see if we can compensate the negative quants with some untracked quants
untracked_qty = Quant._get_available_quantity(product_id, location_id, lot_id=False, package_id=package_id, owner_id=owner_id, strict=True)
if untracked_qty:
taken_from_untracked_qty = min(untracked_qty, abs(available_qty))
Quant._update_available_quantity(product_id, location_id, -taken_from_untracked_qty, lot_id=False, package_id=package_id, owner_id=owner_id)
Quant._update_available_quantity(product_id, location_id, taken_from_untracked_qty, lot_id=lot_id, package_id=package_id, owner_id=owner_id)
if not location_id.should_bypass_reservation():
ml._free_reservation(ml.product_id, location_id, untracked_qty, lot_id=False, package_id=package_id, owner_id=owner_id)
Quant._update_available_quantity(product_id, location_dest_id, quantity, lot_id=lot_id, package_id=result_package_id, owner_id=owner_id, in_date=in_date)
# Unreserve and reserve following move in order to have the real reserved quantity on move_line.
next_moves |= ml.move_id.move_dest_ids.filtered(lambda move: move.state not in ('done', 'cancel'))
# Log a note
if ml.picking_id:
ml._log_message(ml.picking_id, ml, 'stock.track_move_template', vals)
res = super(StockMoveLine, self).write(vals)
# Update scrap object linked to move_lines to the new quantity.
if 'qty_done' in vals:
for move in self.mapped('move_id'):
if move.scrapped:
move.scrap_ids.write({'scrap_qty': move.quantity_done})
# As stock_account values according to a move's `product_uom_qty`, we consider that any
# done stock move should have its `quantity_done` equals to its `product_uom_qty`, and
# this is what move's `action_done` will do. So, we replicate the behavior here.
if updates or 'qty_done' in vals:
moves = self.filtered(lambda ml: ml.move_id.state == 'done').mapped('move_id')
for move in moves:
move.product_uom_qty = move.quantity_done
next_moves._do_unreserve()
next_moves._action_assign()
return res
def unlink(self):
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
for ml in self:
if ml.state in ('done', 'cancel'):
raise UserError(_('You can not delete product moves if the picking is done. You can only correct the done quantities.'))
# Unlinking a move line should unreserve.
if ml.product_id.type == 'product' and not ml.location_id.should_bypass_reservation() and not float_is_zero(ml.product_qty, precision_digits=precision):
self.env['stock.quant']._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id,
package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
moves = self.mapped('move_id')
res = super(StockMoveLine, self).unlink()
if moves:
moves._recompute_state()
return res
def _action_done(self):
""" This method is called during a move's `action_done`. It'll actually move a quant from
the source location to the destination location, and unreserve if needed in the source
location.
This method is intended to be called on all the move lines of a move. This method is not
intended to be called when editing a `done` move (that's what the override of `write` here
is done.
"""
# First, we loop over all the move lines to do a preliminary check: `qty_done` should not
# be negative and, according to the presence of a picking type or a linked inventory
# adjustment, enforce some rules on the `lot_id` field. If `qty_done` is null, we unlink
# the line. It is mandatory in order to free the reservation and correctly apply
# `action_done` on the next move lines.
ml_to_delete = self.env['stock.move.line']
for ml in self:
qty_done_float_compared = float_compare(ml.qty_done, 0, precision_rounding=ml.product_uom_id.rounding)
if qty_done_float_compared > 0:
if ml.product_id.tracking != 'none':
picking_type_id = ml.move_id.picking_type_id
if picking_type_id:
if picking_type_id.use_create_lots:
# If a picking type is linked, we may have to create a production lot on
# the fly before assigning it to the move line if the user checked both
# `use_create_lots` and `use_existing_lots`.
if ml.lot_name and not ml.lot_id:
lot = self.env['stock.production.lot'].create(
{'name': ml.lot_name, 'product_id': ml.product_id.id}
)
ml.write({'lot_id': lot.id})
elif not picking_type_id.use_create_lots and not picking_type_id.use_existing_lots:
# If the user disabled both `use_create_lots` and `use_existing_lots`
# checkboxes on the picking type, he's allowed to enter tracked
# products without a `lot_id`.
continue
elif ml.move_id.inventory_id:
# If an inventory adjustment is linked, the user is allowed to enter
# tracked products without a `lot_id`.
continue
if not ml.lot_id:
raise UserError(_('You need to supply a lot/serial number for %s.') % ml.product_id.name)
elif qty_done_float_compared < 0:
raise UserError(_('No negative quantities allowed'))
else:
ml_to_delete |= ml
ml_to_delete.unlink()
# Now, we can actually move the quant.
for ml in self - ml_to_delete:
if ml.product_id.type == 'product':
Quant = self.env['stock.quant']
rounding = ml.product_uom_id.rounding
# if this move line is force assigned, unreserve elsewhere if needed
if not ml.location_id.should_bypass_reservation() and float_compare(ml.qty_done, ml.product_qty, precision_rounding=rounding) > 0:
extra_qty = ml.qty_done - ml.product_qty
ml._free_reservation(ml.product_id, ml.location_id, extra_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id)
# unreserve what's been reserved
if not ml.location_id.should_bypass_reservation() and ml.product_id.type == 'product' and ml.product_qty:
try:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
except UserError:
Quant._update_reserved_quantity(ml.product_id, ml.location_id, -ml.product_qty, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
# move what's been actually done
quantity = ml.product_uom_id._compute_quantity(ml.qty_done, ml.move_id.product_id.uom_id, rounding_method='HALF-UP')
available_qty, in_date = Quant._update_available_quantity(ml.product_id, ml.location_id, -quantity, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id)
if available_qty < 0 and ml.lot_id:
# see if we can compensate the negative quants with some untracked quants
untracked_qty = Quant._get_available_quantity(ml.product_id, ml.location_id, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id, strict=True)
if untracked_qty:
taken_from_untracked_qty = min(untracked_qty, abs(quantity))
Quant._update_available_quantity(ml.product_id, ml.location_id, -taken_from_untracked_qty, lot_id=False, package_id=ml.package_id, owner_id=ml.owner_id)
Quant._update_available_quantity(ml.product_id, ml.location_id, taken_from_untracked_qty, lot_id=ml.lot_id, package_id=ml.package_id, owner_id=ml.owner_id)
Quant._update_available_quantity(ml.product_id, ml.location_dest_id, quantity, lot_id=ml.lot_id, package_id=ml.result_package_id, owner_id=ml.owner_id, in_date=in_date)
# Reset the reserved quantity as we just moved it to the destination location.
(self - ml_to_delete).with_context(bypass_reservation_update=True).write({'product_uom_qty': 0.00})
def _log_message(self, record, move, template, vals):
data = vals.copy()
if 'lot_id' in vals and vals['lot_id'] != move.lot_id.id:
data['lot_name'] = self.env['stock.production.lot'].browse(vals.get('lot_id')).name
if 'location_id' in vals:
data['location_name'] = self.env['stock.location'].browse(vals.get('location_id')).name
if 'location_dest_id' in vals:
data['location_dest_name'] = self.env['stock.location'].browse(vals.get('location_dest_id')).name
if 'package_id' in vals and vals['package_id'] != move.package_id.id:
data['package_name'] = self.env['stock.quant.package'].browse(vals.get('package_id')).name
if 'package_result_id' in vals and vals['package_result_id'] != move.package_result_id.id:
data['result_package_name'] = self.env['stock.quant.package'].browse(vals.get('result_package_id')).name
if 'owner_id' in vals and vals['owner_id'] != move.owner_id.id:
data['owner_name'] = self.env['res.partner'].browse(vals.get('owner_id')).name
record.message_post_with_view(template, values={'move': move, 'vals': dict(vals, **data)}, subtype_id=self.env.ref('mail.mt_note').id)
def _free_reservation(self, product_id, location_id, quantity, lot_id=None, package_id=None, owner_id=None):
""" When editing a done move line or validating one with some forced quantities, it is
possible to impact quants that were not reserved. It is therefore necessary to edit or
unlink the move lines that reserved a quantity now unavailable.
"""
self.ensure_one()
# Check the available quantity, with the `strict` kw set to `True`. If the available
# quantity is greather than the quantity now unavailable, there is nothing to do.
available_quantity = self.env['stock.quant']._get_available_quantity(
product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=True
)
if quantity > available_quantity:
# We now have to find the move lines that reserved our now unavailable quantity. We
# take care to exclude ourselves and the move lines were work had already been done.
oudated_move_lines_domain = [
('move_id.state', 'not in', ['done', 'cancel']),
('product_id', '=', product_id.id),
('lot_id', '=', lot_id.id if lot_id else False),
('location_id', '=', location_id.id),
('owner_id', '=', owner_id.id if owner_id else False),
('package_id', '=', package_id.id if package_id else False),
('product_qty', '>', 0.0),
('id', '!=', self.id),
]
oudated_candidates = self.env['stock.move.line'].search(oudated_move_lines_domain)
# As the move's state is not computed over the move lines, we'll have to manually
# recompute the moves which we adapted their lines.
move_to_recompute_state = self.env['stock.move']
rounding = self.product_uom_id.rounding
for candidate in oudated_candidates:
if float_compare(candidate.product_qty, quantity, precision_rounding=rounding) <= 0:
quantity -= candidate.product_qty
move_to_recompute_state |= candidate.move_id
if candidate.qty_done:
candidate.product_uom_qty = 0.0
else:
candidate.unlink()
else:
# split this move line and assign the new part to our extra move
quantity_split = float_round(
candidate.product_qty - quantity,
precision_rounding=self.product_uom_id.rounding,
rounding_method='UP')
candidate.product_uom_qty = self.product_id.uom_id._compute_quantity(quantity_split, candidate.product_uom_id, rounding_method='HALF-UP')
quantity -= quantity_split
move_to_recompute_state |= candidate.move_id
if quantity == 0.0:
break
move_to_recompute_state._recompute_state()

View File

@@ -0,0 +1,80 @@
# Copyright 2013-2015 Camptocamp SA - Nicolas Bessi
# Copyright 2018 Camptocamp SA - Julien Coux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, models
from odoo.exceptions import UserError
from odoo.tools.float_utils import float_compare
class StockPicking(models.Model):
"""Adds picking split without done state."""
_inherit = "stock.picking"
@api.multi
def split_process(self):
"""Use to trigger the wizard from button with correct context"""
for picking in self:
# Check the picking state and condition before split
if picking.state == 'draft':
raise UserError(_('Mark as todo this picking please.'))
if all([x.qty_done == 0.0 for x in picking.move_line_ids]):
raise UserError(
_('You must enter done quantity in order to split your '
'picking in several ones.'))
# Split moves considering the qty_done on moves
new_moves = self.env['stock.move']
for move in picking.move_lines:
rounding = move.product_uom.rounding
qty_done = move.quantity_done
qty_initial = move.product_uom_qty
qty_diff_compare = float_compare(
qty_done, qty_initial, precision_rounding=rounding
)
if qty_diff_compare < 0:
qty_split = qty_initial - qty_done
qty_uom_split = move.product_uom._compute_quantity(
qty_split,
move.product_id.uom_id,
rounding_method='HALF-UP'
)
new_move_id = move._split(qty_uom_split)
for move_line in move.move_line_ids:
if move_line.product_qty and move_line.qty_done:
# To avoid an error
# when picking is partially available
try:
move_line.write(
{'product_uom_qty': move_line.qty_done})
except UserError:
pass
new_moves |= self.env['stock.move'].browse(new_move_id)
# If we have new moves to move, create the backorder picking
if new_moves:
backorder_picking = picking.copy({
'name': '/',
'move_lines': [],
'move_line_ids': [],
'backorder_id': picking.id,
})
picking.message_post(
_(
'The backorder <a href="#" '
'data-oe-model="stock.picking" '
'data-oe-id="%d">%s</a> has been created.'
) % (
backorder_picking.id,
backorder_picking.name
)
)
new_moves.write({
'picking_id': backorder_picking.id,
})
new_moves.mapped('move_line_ids').write({
'picking_id': backorder_picking.id,
})
new_moves._action_assign()

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,55 @@
<section class="oe_container">
<div class="oe_row oe_spaced" style="max-width: 800px;">
<div class="oe_span12">
<h2 class="oe_slogan">App MRP BOM Location for Manufacturing/Unbuild Order</h2>
<div class="oe_demo" style=" margin: 30px auto 0; padding: 0 15px 0 0; border:none; width: 96%;">
<p>This moduld allows user to . </p>
<h1>More Powerful addons:
<a class="btn btn-primary mb16" href="http://www.odoo.com/apps/modules/browse?author=Sunpop.cn">Supop.cn Odoo Addons</a>
</h1>
<br>
<h3>Lastest update: v11.0.7.27, 2018-07-27</h3>
<ul>
<li>1. ...</li>
</ul>
</div>
<div class="oe_demo oe_screenshot mt32">
<img src="banner.png" style="border:1px solid black"/>
<br/>
</div>
</div>
</div>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced text-center">
<div class="oe_span12">
<h2 class="oe_slogan">Technical Help & Support</h2>
</div>
<div class="col-md-12 pad0">
<div class="oe_mt16">
<p><h4>
For any type of technical help & support requests, Feel free to contact us</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="mailto:guohuadeng@hotmail.com"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-envelope"></i> guohuadeng@hotmail.com</a>
<p><h4>
Via QQ: 300883</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="mailto:300883@qq.com"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-envelope"></i> 300883@qq.com</a>
</div>
<div class="oe_mt16">
<p><h4>
Visit our website for more support.</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="http://www.sunpop.cn" target="_blank"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-web"></i>http://www.sunpop.cn</a>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_stock_split_picking

View File

@@ -0,0 +1,87 @@
# Copyright 2017 Tecnativa - Vicent Cubells <vicent.cubells@tecnativa.com>
# Copyright 2018 Camptocamp SA - Julien Coux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import SavepointCase
from odoo.exceptions import UserError
class TestStockSplitPicking(SavepointCase):
@classmethod
def setUpClass(cls):
super(TestStockSplitPicking, cls).setUpClass()
cls.src_location = cls.env.ref('stock.stock_location_stock')
cls.dest_location = cls.env.ref('stock.stock_location_customers')
cls.product = cls.env['product.product'].create({
'name': 'Test product',
})
cls.partner = cls.env['res.partner'].create({
'name': 'Test partner',
})
cls.picking = cls.env['stock.picking'].create({
'partner_id': cls.partner.id,
'picking_type_id': cls.env.ref('stock.picking_type_out').id,
'location_id': cls.src_location.id,
'location_dest_id': cls.dest_location.id,
})
cls.move = cls.env['stock.move'].create({
'name': '/',
'picking_id': cls.picking.id,
'product_id': cls.product.id,
'product_uom_qty': 10,
'product_uom': cls.product.uom_id.id,
'location_id': cls.src_location.id,
'location_dest_id': cls.dest_location.id,
})
def test_stock_split_picking(self):
# Picking state is draft
self.assertEqual(self.picking.state, 'draft')
# We can't split a draft picking
with self.assertRaises(UserError):
self.picking.split_process()
# Confirm picking
self.picking.action_confirm()
# We can't split an unassigned picking
with self.assertRaises(UserError):
self.picking.split_process()
# We assign quantities in order to split
self.picking.action_assign()
move_line = self.env['stock.move.line'].search(
[('picking_id', '=', self.picking.id)], limit=1)
move_line.qty_done = 4.0
# Split picking: 4 and 6
# import pdb; pdb.set_trace()
self.picking.split_process()
# We have a picking with 4 units in state assigned
self.assertAlmostEqual(move_line.qty_done, 4.0)
self.assertAlmostEqual(move_line.product_qty, 4.0)
self.assertAlmostEqual(move_line.product_uom_qty, 4.0)
self.assertAlmostEqual(move_line.ordered_qty, 10.0)
self.assertAlmostEqual(self.move.quantity_done, 4.0)
self.assertAlmostEqual(self.move.product_qty, 4.0)
self.assertAlmostEqual(self.move.product_uom_qty, 4.0)
self.assertAlmostEqual(self.move.ordered_qty, 10.0)
self.assertEqual(self.picking.state, 'assigned')
# An another one with 6 units in state assigned
new_picking = self.env['stock.picking'].search(
[('backorder_id', '=', self.picking.id)], limit=1)
move_line = self.env['stock.move.line'].search(
[('picking_id', '=', new_picking.id)], limit=1)
self.assertAlmostEqual(move_line.qty_done, 0.0)
self.assertAlmostEqual(move_line.product_qty, 6.0)
self.assertAlmostEqual(move_line.product_uom_qty, 6.0)
self.assertAlmostEqual(move_line.ordered_qty, 6.0)
self.assertAlmostEqual(new_picking.move_lines.quantity_done, 0.0)
self.assertAlmostEqual(new_picking.move_lines.product_qty, 6.0)
self.assertAlmostEqual(new_picking.move_lines.product_uom_qty, 6.0)
self.assertAlmostEqual(new_picking.move_lines.ordered_qty, 6.0)
self.assertEqual(new_picking.state, 'assigned')

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_picking_form" model="ir.ui.view">
<field name="name">Stock picking out Split button</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<field name ="state" position="before">
<button name="split_process"
states="draft,assigned,partially_available"
string="Split"
confirm="Are you sure you want to split current picking?"
groups="stock.group_stock_user"
type="object"/>
</field>
</field>
</record>
</odoo>