Merge PR #2121 into 17.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2025-01-20 08:06:23 +00:00
25 changed files with 1800 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
====================
Stock Secondary Unit
====================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:31e6f77419eef15934b2bd7f856a4a83596ab6f4d0ae89ba679f4c9b41961e7d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| 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
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-warehouse/tree/17.0/stock_secondary_unit
:alt: OCA/stock-logistics-warehouse
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-17-0/stock-logistics-warehouse-17-0-stock_secondary_unit
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=17.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module extends the functionality of stock module to allow define
other units with their conversion factor.
**Table of contents**
.. contents::
:local:
Usage
=====
To use this module you need to:
1. Go to a *Product > General Information tab*.
2. Create any record in "Secondary unit of measure".
3. Set the conversion factor.
4. Go to *Inventory tab* and set a second unit of measure.
5. Push button 'Quantity on hand' and set quantities in stock for this
product.
6. Go to product list and you can see the secondary unit value.
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 to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_secondary_unit%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Tecnativa
Contributors
------------
- `Tecnativa <https://www.tecnativa.com>`__
- Carlos Dauden
- Sergio Teruel
- Carlos Roca
- Kitti Upariphutthiphong <kittiu@ecosoft.co.th>
- Pimolnat Suntian <pimolnats@ecosoft.co.th>
- Alan Ramos <alan.ramos@jarsa.com.mx>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
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.
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/17.0/stock_secondary_unit>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

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

View File

@@ -0,0 +1,21 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Stock Secondary Unit",
"summary": "Get product quantities in a secondary unit",
"version": "17.0.1.0.0",
"development_status": "Production/Stable",
"category": "stock",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"author": "Tecnativa, Odoo Community Association (OCA)",
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": ["stock", "product_secondary_unit"],
"data": [
"views/product_views.xml",
"views/stock_move_views.xml",
"views/stock_picking_views.xml",
"report/report_deliveryslip.xml",
],
}

View File

@@ -0,0 +1,132 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-11 06:27+0000\n"
"PO-Revision-Date: 2023-07-27 22:12+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document
msgid "<strong>Secondary Qty</strong>"
msgstr "<strong>Cantidad secundaria</strong>"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid "Demand"
msgstr "Demanda"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__qty_done
msgid "Done"
msgstr "Hecho"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_template
msgid "Product"
msgstr "Producto"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move_line
msgid "Product Moves (Stock Move Line)"
msgstr "Movimientos de productos (línea de movimiento de existencias)"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_product
msgid "Product Variant"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_mixin__secondary_unit_qty_available
msgid "Quantity On Hand (2Unit)"
msgstr "Cantidad a mano (2Ud.)"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_id
msgid "Second unit"
msgstr "Segunda unidad"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__stock_secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__stock_secondary_uom_id
msgid "Second unit for inventory"
msgstr "Segunda unidad de medida para inventario"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_qty
msgid "Secondary Qty"
msgstr "Cantd Secundaria"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.view_template_property_form
msgid "Secondary unit"
msgstr "Unidad Secundaria"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move
msgid "Stock Move"
msgstr "Movimiento de existencias"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit_mixin
msgid "Stock Product Secondary Unit Mixin"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid ""
"This is the quantity of products from an inventory point of view. For moves "
"in the state 'done', this is the quantity of products that were actually "
"moved. For other moves, this is the quantity of product that is planned to "
"be moved. Lowering this quantity does not generate a backorder. Changing "
"this quantity on assigned moves affects the product reservation, and should "
"be done with care."
msgstr ""
"Es la cantidad de productos desde el punto de vista del inventario. Para los "
"movimientos en estado \"realizado\", es la cantidad de productos que se han "
"movido realmente. Para otros movimientos, es la cantidad de productos que "
"está previsto mover. La reducción de esta cantidad no genera un pedido "
"pendiente. La modificación de esta cantidad en los movimientos asignados "
"afecta a la reserva de productos, y debe hacerse con cuidado."
#~ msgid "Product Template"
#~ msgstr "Plantilla de producto"
#~ msgid "Stock Product Secondary Unit"
#~ msgstr "Existencias de unidad secundaria del producto"
#~ msgid "Display Name"
#~ msgstr "Mostrar Nombre"
#~ msgid "ID"
#~ msgstr "ID"
#~ msgid "Last Modified on"
#~ msgstr "Última modificación en"
#, fuzzy
#~ msgid "Stock Secondary Unit Mixin"
#~ msgstr "Unidad Secundaria"
#~ msgid "On Hand (2unit)"
#~ msgstr "A mano (2Ud.)"
#~ msgid "Second Unit Quantity On Hand"
#~ msgstr "Segunda unidad de medida por defecto"

View File

@@ -0,0 +1,112 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-08-11 13:10+0000\n"
"Last-Translator: Oskars Zālītis <oskars.zalitis@avoin.systems>\n"
"Language-Team: none\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"
"X-Generator: Weblate 4.17\n"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document
msgid "<strong>Secondary Qty</strong>"
msgstr "<strong>2. Määrä</strong>"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid "Demand"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__qty_done
msgid "Done"
msgstr "Valmis"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_template
msgid "Product"
msgstr "Tuote"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move_line
msgid "Product Moves (Stock Move Line)"
msgstr "Tuotteiden siirrot (Stock Move Line)"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_product
msgid "Product Variant"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_mixin__secondary_unit_qty_available
msgid "Quantity On Hand (2Unit)"
msgstr "Varastossa (2.yks.)"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_id
msgid "Second unit"
msgstr "2. Yksikkö"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__stock_secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__stock_secondary_uom_id
msgid "Second unit for inventory"
msgstr "Toinen varastointiyksikkö"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_qty
msgid "Secondary Qty"
msgstr "2. Määrä"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.view_template_property_form
msgid "Secondary unit"
msgstr "2. Yksikkö"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move
msgid "Stock Move"
msgstr "Varastosiirto"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit_mixin
msgid "Stock Product Secondary Unit Mixin"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid ""
"This is the quantity of products from an inventory point of view. For moves "
"in the state 'done', this is the quantity of products that were actually "
"moved. For other moves, this is the quantity of product that is planned to "
"be moved. Lowering this quantity does not generate a backorder. Changing "
"this quantity on assigned moves affects the product reservation, and should "
"be done with care."
msgstr ""
"Tämä on tuotteiden määrä varaston näkymästä. \"Valmiissa tilassa\" "
"tapahtuvien siirtojen osalta tämä on tosiasiallisesti siirrettyjen "
"tuotteiden määrä. Muita siirtoja varten tämä on tuotteen määrä, joka on "
"tarkoitus siirtää. Tämän määrän alentaminen ei synny takaisinkytkentää. "
"Tämän määrän muuttaminen määrättyihin liikkeisiin vaikuttaa tuotteen "
"varaamiseen, ja se on tehtävä huolellisesti."
#~ msgid "Product Template"
#~ msgstr "Tuotemalli"
#~ msgid "Stock Product Secondary Unit"
#~ msgstr "Tuotteen toinen varastointiyksikkö"

View File

@@ -0,0 +1,109 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-10-10 10:06+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\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"
"X-Generator: Weblate 5.6.2\n"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document
msgid "<strong>Secondary Qty</strong>"
msgstr "<strong>Qty Secondaria</strong>"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid "Demand"
msgstr "Fabbisogno"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__qty_done
msgid "Done"
msgstr "Evasa"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_template
msgid "Product"
msgstr "Prodotto"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move_line
msgid "Product Moves (Stock Move Line)"
msgstr "Movimenti prodotto (riga movimento di magazzino)"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_product
msgid "Product Variant"
msgstr "Variante prodotto"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_mixin__secondary_unit_qty_available
msgid "Quantity On Hand (2Unit)"
msgstr "Quantità disponibile (2 unità)"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_id
msgid "Second unit"
msgstr "Unità secondaria"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__stock_secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__stock_secondary_uom_id
msgid "Second unit for inventory"
msgstr "Unità secondaria per l'inventario"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_qty
msgid "Secondary Qty"
msgstr "Q.tà secondaria"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.view_template_property_form
msgid "Secondary unit"
msgstr "Unità secondaria"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move
msgid "Stock Move"
msgstr "Movimento di magazzino"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit_mixin
msgid "Stock Product Secondary Unit Mixin"
msgstr "Mixin unità secondaria del prodotto"
#. module: stock_secondary_unit
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid ""
"This is the quantity of products from an inventory point of view. For moves "
"in the state 'done', this is the quantity of products that were actually "
"moved. For other moves, this is the quantity of product that is planned to "
"be moved. Lowering this quantity does not generate a backorder. Changing "
"this quantity on assigned moves affects the product reservation, and should "
"be done with care."
msgstr ""
"Questa è la quantità di prodotto dal punto di vista dell'inventario. Per "
"movimenti in stato 'eseguito', questa è la quantità di prodotto che è stata "
"effettivamente movimentata. Per altri movimenti, questa è la quantità del "
"prodotto pianificata per essere movimentata. Ridurre la quantità non genera "
"un ordine residuo. Modificare questa quantità nei movimenti assegnati incide "
"sulla prenotazione del prodotto e deve essere eseguita con attenzione."
#~ msgid "Product Template"
#~ msgstr "Modello prodotto"

View File

@@ -0,0 +1,97 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.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_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document
msgid "<strong>Secondary Qty</strong>"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid "Demand"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__qty_done
msgid "Done"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_template
msgid "Product"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move_line
msgid "Product Moves (Stock Move Line)"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_product
msgid "Product Variant"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_mixin__secondary_unit_qty_available
msgid "Quantity On Hand (2Unit)"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_id
msgid "Second unit"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__stock_secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__stock_secondary_uom_id
msgid "Second unit for inventory"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_qty
msgid "Secondary Qty"
msgstr ""
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.view_template_property_form
msgid "Secondary unit"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit_mixin
msgid "Stock Product Secondary Unit Mixin"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid ""
"This is the quantity of products from an inventory point of view. For moves "
"in the state 'done', this is the quantity of products that were actually "
"moved. For other moves, this is the quantity of product that is planned to "
"be moved. Lowering this quantity does not generate a backorder. Changing "
"this quantity on assigned moves affects the product reservation, and should "
"be done with care."
msgstr ""

View File

@@ -0,0 +1,118 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2019-10-21 15:32+0000\n"
"Last-Translator: Tony Gu <tony@openerp.cn>\n"
"Language-Team: none\n"
"Language: zh_CN\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"
"X-Generator: Weblate 3.8\n"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document
msgid "<strong>Secondary Qty</strong>"
msgstr "<strong> 辅助单位数量</strong>"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid "Demand"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__qty_done
msgid "Done"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_template
msgid "Product"
msgstr "产品"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move_line
msgid "Product Moves (Stock Move Line)"
msgstr "产品移动(库存移动行)"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_product_product
msgid "Product Variant"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__secondary_unit_qty_available
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_mixin__secondary_unit_qty_available
msgid "Quantity On Hand (2Unit)"
msgstr "在手数量(辅助单位)"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_id
msgid "Second unit"
msgstr "辅助单位"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_product__stock_secondary_uom_id
#: model:ir.model.fields,field_description:stock_secondary_unit.field_product_template__stock_secondary_uom_id
msgid "Second unit for inventory"
msgstr "库存辅助单位"
#. module: stock_secondary_unit
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move__secondary_uom_qty
#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_move_line__secondary_uom_qty
msgid "Secondary Qty"
msgstr "辅助单位数量"
#. module: stock_secondary_unit
#: model_terms:ir.ui.view,arch_db:stock_secondary_unit.view_template_property_form
msgid "Secondary unit"
msgstr "辅助单位"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_move
msgid "Stock Move"
msgstr "库存移动"
#. module: stock_secondary_unit
#: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit_mixin
msgid "Stock Product Secondary Unit Mixin"
msgstr ""
#. module: stock_secondary_unit
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_move__product_uom_qty
#: model:ir.model.fields,help:stock_secondary_unit.field_stock_reservation__product_uom_qty
msgid ""
"This is the quantity of products from an inventory point of view. For moves "
"in the state 'done', this is the quantity of products that were actually "
"moved. For other moves, this is the quantity of product that is planned to "
"be moved. Lowering this quantity does not generate a backorder. Changing "
"this quantity on assigned moves affects the product reservation, and should "
"be done with care."
msgstr ""
#~ msgid "Product Template"
#~ msgstr "产品模板"
#~ msgid "Stock Product Secondary Unit"
#~ msgstr "库存产品辅助单位"
#~ msgid "Display Name"
#~ msgstr "显示名称"
#~ msgid "ID"
#~ msgstr "ID"
#~ msgid "Last Modified on"
#~ msgstr "最后修改时间"
#~ msgid "Stock Secondary Unit Mixin"
#~ msgstr "库存辅助单位混合类"

View File

@@ -0,0 +1,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
# Keep order
from . import stock_product_secondary_unit_mixin
from . import product_product
from . import product_template
from . import stock_move

View File

@@ -0,0 +1,17 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ProductProduct(models.Model):
_inherit = ["product.product", "stock.product.secondary.unit.mixin"]
_name = "product.product"
stock_secondary_uom_id = fields.Many2one(
comodel_name="product.secondary.unit",
string="Second unit for inventory",
readonly=False,
domain="['|', ('product_id', '=', id),"
"'&', ('product_tmpl_id', '=', product_tmpl_id),"
" ('product_id', '=', False)]",
)

View File

@@ -0,0 +1,14 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ProductTemplate(models.Model):
_inherit = ["product.template", "stock.product.secondary.unit.mixin"]
_name = "product.template"
stock_secondary_uom_id = fields.Many2one(
comodel_name="product.secondary.unit",
domain="[('product_tmpl_id', '=', id), ('product_id', '=', False)]",
string="Second unit for inventory",
)

View File

@@ -0,0 +1,63 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class StockMove(models.Model):
_inherit = ["stock.move", "product.secondary.unit.mixin"]
_name = "stock.move"
_secondary_unit_fields = {
"qty_field": "product_uom_qty",
"uom_field": "product_uom",
}
product_uom_qty = fields.Float(
store=True,
readonly=False,
compute="_compute_product_uom_qty",
copy=True,
precompute=True,
)
@api.depends("secondary_uom_qty", "secondary_uom_id")
def _compute_product_uom_qty(self):
self._compute_helper_target_field_qty()
@api.onchange("product_uom")
def onchange_product_uom_for_secondary(self):
self._onchange_helper_product_uom_for_secondary()
@api.model
def _prepare_merge_moves_distinct_fields(self):
"""Don't merge moves with distinct secondary units"""
distinct_fields = super()._prepare_merge_moves_distinct_fields()
distinct_fields += ["secondary_uom_id"]
return distinct_fields
def _prepare_extra_move_vals(self, qty):
vals = super()._prepare_extra_move_vals(qty)
if self.secondary_uom_id:
vals["secondary_uom_id"] = self.secondary_uom_id.id
return vals
class StockMoveLine(models.Model):
_inherit = ["stock.move.line", "product.secondary.unit.mixin"]
_name = "stock.move.line"
_secondary_unit_fields = {"qty_field": "qty_done", "uom_field": "product_uom_id"}
qty_done = fields.Float(
store=True, readonly=False, compute="_compute_qty_done", precompute=True
)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
move = self.env["stock.move"].browse(vals.get("move_id", False))
if move.secondary_uom_id:
vals["secondary_uom_id"] = move.secondary_uom_id.id
return super().create(vals_list)
@api.depends("secondary_uom_id", "secondary_uom_qty")
def _compute_qty_done(self):
self._compute_helper_target_field_qty()

View File

@@ -0,0 +1,28 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools.float_utils import float_round
class StockProductSecondaryUnitMixin(models.AbstractModel):
_name = "stock.product.secondary.unit.mixin"
_description = "Stock Product Secondary Unit Mixin"
secondary_unit_qty_available = fields.Float(
string="Quantity On Hand (2Unit)",
compute="_compute_secondary_unit_qty_available",
digits="Product Unit of Measure",
)
@api.depends("stock_secondary_uom_id")
def _compute_secondary_unit_qty_available(self):
for product in self:
if not product.stock_secondary_uom_id:
product.secondary_unit_qty_available = 0.0
else:
qty = product.qty_available / (
product.stock_secondary_uom_id.factor or 1.0
)
product.secondary_unit_qty_available = float_round(
qty, precision_rounding=product.uom_id.rounding
)

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,7 @@
- [Tecnativa](https://www.tecnativa.com)
- Carlos Dauden
- Sergio Teruel
- Carlos Roca
- Kitti Upariphutthiphong \<<kittiu@ecosoft.co.th>\>
- Pimolnat Suntian \<<pimolnats@ecosoft.co.th>\>
- Alan Ramos \<<alan.ramos@jarsa.com.mx>\>

View File

@@ -0,0 +1,2 @@
This module extends the functionality of stock module to allow define
other units with their conversion factor.

View File

@@ -0,0 +1,9 @@
To use this module you need to:
1. Go to a *Product \> General Information tab*.
2. Create any record in "Secondary unit of measure".
3. Set the conversion factor.
4. Go to *Inventory tab* and set a second unit of measure.
5. Push button 'Quantity on hand' and set quantities in stock for this
product.
6. Go to product list and you can see the secondary unit value.

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Tecnativa - Sergio Teruel
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<template
id="report_delivery_document"
inherit_id="stock.report_delivery_document"
priority="8"
>
<xpath
expr='//table[@t-if="o.state!=&apos;done&apos;"]/thead/tr/th'
position="after"
>
<th>
<strong>Secondary Qty</strong>
</th>
</xpath>
<xpath expr="//span[@t-field='move.product_id']/.." position="after">
<td>
<span t-field="move.secondary_uom_qty" />
<span t-field="move.secondary_uom_id.name" />
</td>
</xpath>
<xpath
expr='//table[@t-elif="o.move_line_ids and o.state==&apos;done&apos;"]/thead/tr/th'
position="after"
>
<th>
<strong>Secondary Qty</strong>
</th>
</xpath>
</template>
<template
id="stock_report_delivery_has_serial_move_line"
inherit_id="stock.stock_report_delivery_has_serial_move_line"
>
<xpath expr="//span[@t-field='move_line.product_id']/.." position="after">
<td>
<span t-field="move_line.secondary_uom_qty" />
<span t-field="move_line.secondary_uom_id" />
</td>
</xpath>
</template>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,443 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Stock Secondary Unit</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="stock-secondary-unit">
<h1 class="title">Stock Secondary Unit</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:31e6f77419eef15934b2bd7f856a4a83596ab6f4d0ae89ba679f4c9b41961e7d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-warehouse/tree/17.0/stock_secondary_unit"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-17-0/stock-logistics-warehouse-17-0-stock_secondary_unit"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module extends the functionality of stock module to allow define
other units with their conversion factor.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>To use this module you need to:</p>
<ol class="arabic simple">
<li>Go to a <em>Product &gt; General Information tab</em>.</li>
<li>Create any record in “Secondary unit of measure”.</li>
<li>Set the conversion factor.</li>
<li>Go to <em>Inventory tab</em> and set a second unit of measure.</li>
<li>Push button Quantity on hand and set quantities in stock for this
product.</li>
<li>Go to product list and you can see the secondary unit value.</li>
</ol>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_secondary_unit%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a><ul>
<li>Carlos Dauden</li>
<li>Sergio Teruel</li>
<li>Carlos Roca</li>
</ul>
</li>
<li>Kitti Upariphutthiphong &lt;<a class="reference external" href="mailto:kittiu&#64;ecosoft.co.th">kittiu&#64;ecosoft.co.th</a>&gt;</li>
<li>Pimolnat Suntian &lt;<a class="reference external" href="mailto:pimolnats&#64;ecosoft.co.th">pimolnats&#64;ecosoft.co.th</a>&gt;</li>
<li>Alan Ramos &lt;<a class="reference external" href="mailto:alan.ramos&#64;jarsa.com.mx">alan.ramos&#64;jarsa.com.mx</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/tree/17.0/stock_secondary_unit">OCA/stock-logistics-warehouse</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

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

View File

@@ -0,0 +1,234 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tests import Form, TransactionCase, tagged
from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT
@tagged("-at_install", "post_install")
class TestProductSecondaryUnit(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT))
# Active multiple units of measure security group for user
cls.env.user.groups_id = [(4, cls.env.ref("uom.group_uom").id)]
cls.StockPicking = cls.env["stock.picking"]
cls.warehouse = cls.env.ref("stock.warehouse0")
cls.location_supplier = cls.env.ref("stock.stock_location_suppliers")
cls.location_stock = cls.env.ref("stock.stock_location_stock")
cls.picking_type_in = cls.env.ref("stock.picking_type_in")
cls.picking_type_out = cls.env.ref("stock.picking_type_out")
cls.picking_type_out.show_operations = True
cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm")
cls.product_uom_ton = cls.env.ref("uom.product_uom_ton")
cls.product_uom_unit = cls.env.ref("uom.product_uom_unit")
ProductAttribute = cls.env["product.attribute"]
ProductAttributeValue = cls.env["product.attribute.value"]
cls.attribute_color = ProductAttribute.create({"name": "test_color"})
cls.attribute_value_white = ProductAttributeValue.create(
{"name": "test_white", "attribute_id": cls.attribute_color.id}
)
cls.attribute_value_black = ProductAttributeValue.create(
{"name": "test_black", "attribute_id": cls.attribute_color.id}
)
cls.product_template = cls.env["product.template"].create(
{
"name": "test",
"uom_id": cls.product_uom_kg.id,
"uom_po_id": cls.product_uom_kg.id,
"type": "product",
"secondary_uom_ids": [
(
0,
0,
{
"code": "A",
"name": "unit-500",
"uom_id": cls.product_uom_unit.id,
"factor": 0.5,
},
),
(
0,
0,
{
"code": "B",
"name": "unit-900",
"uom_id": cls.product_uom_unit.id,
"factor": 0.9,
},
),
(
0,
0,
{
"code": "C",
"name": "box 10",
"uom_id": cls.product_uom_unit.id,
"factor": 10,
},
),
],
"attribute_line_ids": [
(
0,
0,
{
"attribute_id": cls.attribute_color.id,
"value_ids": [
(4, cls.attribute_value_white.id),
(4, cls.attribute_value_black.id),
],
},
)
],
}
)
secondary_unit = cls.env["product.secondary.unit"].search(
[("product_tmpl_id", "=", cls.product_template.id)], limit=1
)
cls.product_template.product_variant_ids.write(
{"stock_secondary_uom_id": secondary_unit.id}
)
StockQuant = cls.env["stock.quant"]
cls.quant_white = StockQuant.create(
{
"product_id": cls.product_template.product_variant_ids[0].id,
"location_id": cls.warehouse.lot_stock_id.id,
"quantity": 10.0,
}
)
cls.quant_black = StockQuant.create(
{
"product_id": cls.product_template.product_variant_ids[1].id,
"location_id": cls.warehouse.lot_stock_id.id,
"quantity": 10.0,
}
)
def test_01_stock_secondary_unit_template(self):
self.assertEqual(self.product_template.secondary_unit_qty_available, 0)
def test_02_stock_secondary_unit_variant(self):
for variant in self.product_template.product_variant_ids.filtered(
"product_template_attribute_value_ids"
):
self.assertEqual(variant.secondary_unit_qty_available, 20)
def test_03_stock_picking_secondary_unit(self):
StockPicking = self.env["stock.picking"]
product1 = self.product_template.product_variant_ids[0]
move_vals = {
"product_id": product1.id,
"name": product1.display_name,
"secondary_uom_id": product1.product_tmpl_id.secondary_uom_ids[0].id,
"product_uom": product1.uom_id.id,
"product_uom_qty": 10.0,
"location_id": self.location_supplier.id,
"location_dest_id": self.location_stock.id,
}
do_vals = {
"location_id": self.location_supplier.id,
"location_dest_id": self.location_stock.id,
"picking_type_id": self.picking_type_in.id,
"move_ids_without_package": [
(0, None, move_vals),
(0, None, move_vals),
], # 2 moves
}
delivery_order = StockPicking.create(do_vals)
delivery_order.action_confirm()
# Move is merged into 1 line for both stock.move and stock.move.line
self.assertEqual(len(delivery_order.move_ids), 1)
self.assertEqual(len(delivery_order.move_line_ids), 1)
# Qty merged to 20, and secondary unit qty is 40line
uom_qty = sum(delivery_order.move_ids.mapped("product_uom_qty"))
secondary_uom_qty = sum(
delivery_order.move_line_ids.mapped("secondary_uom_qty")
)
self.assertEqual(uom_qty, 20.0)
self.assertEqual(secondary_uom_qty, 0.0)
def test_picking_secondary_unit(self):
product = self.product_template.product_variant_ids[0]
with Form(
self.StockPicking.with_context(
planned_picking=True,
default_picking_type_id=self.picking_type_out.id,
)
) as picking_form:
with picking_form.move_ids_without_package.new() as move:
move.product_id = product
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[0]
self.assertEqual(move.product_uom_qty, 0.5)
move.secondary_uom_qty = 2
self.assertEqual(move.product_uom_qty, 1)
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[1]
self.assertEqual(move.product_uom_qty, 1.8)
move.product_uom_qty = 5
self.assertAlmostEqual(move.secondary_uom_qty, 5.56, 2)
# Change uom from stock move line
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[2]
self.assertEqual(move.product_uom_qty, 10)
move.product_uom = self.product_uom_ton
self.assertAlmostEqual(move.secondary_uom_qty, 1000, 2)
picking = picking_form.save()
picking.action_confirm()
stock_move_line = picking.move_line_ids_without_package
stock_move_line.product_id = product
stock_move_line.product_uom_id = stock_move_line.product_id.uom_id.id
stock_move_line.secondary_uom_qty = 1
stock_move_line.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[0]
self.assertEqual(stock_move_line.qty_done, 0.5)
stock_move_line.secondary_uom_qty = 2
self.assertEqual(stock_move_line.qty_done, 1)
stock_move_line.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[1]
self.assertEqual(stock_move_line.qty_done, 1.8)
stock_move_line.qty_done = 5
self.assertAlmostEqual(stock_move_line.secondary_uom_qty, 5.56, 2)
def test_secondary_unit_merge_move_diff_uom(self):
product = self.product_template.product_variant_ids[0]
with Form(
self.StockPicking.with_context(
planned_picking=True,
default_picking_type_id=self.picking_type_out.id,
)
) as picking_form:
with picking_form.move_ids_without_package.new() as move:
move.product_id = product
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[0]
with picking_form.move_ids_without_package.new() as move:
move.product_id = product
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[1]
picking = picking_form.save()
picking.action_confirm()
self.assertEqual(len(picking.move_ids), 2)
def test_secondary_unit_merge_move_same_uom(self):
product = self.product_template.product_variant_ids[0]
with Form(
self.StockPicking.with_context(
planned_picking=True,
default_picking_type_id=self.picking_type_out.id,
)
) as picking_form:
with picking_form.move_ids_without_package.new() as move:
move.product_id = product
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[0]
with picking_form.move_ids_without_package.new() as move:
move.product_id = product
move.secondary_uom_qty = 1
move.secondary_uom_id = product.product_tmpl_id.secondary_uom_ids[0]
picking = picking_form.save()
picking.action_confirm()
self.assertEqual(len(picking.move_ids), 1)
self.assertEqual(picking.move_ids.secondary_uom_qty, 2)

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Tecnativa - Sergio Teruel
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_template_property_form" model="ir.ui.view">
<field name="name">Product template Secondary Unit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="stock.view_template_property_form" />
<field name="arch" type="xml">
<xpath expr="//group[@name='inventory']" position="inside">
<group string="Secondary unit" groups="stock.group_stock_user">
<field
name="stock_secondary_uom_id"
options="{'no_create': True}"
/>
</group>
</xpath>
</field>
</record>
<record id="product_template_form_view_procurement_button" model="ir.ui.view">
<field name="model">product.template</field>
<field
name="inherit_id"
ref="stock.product_template_form_view_procurement_button"
/>
<field name="arch" type="xml">
<xpath
expr="//button[@name='action_view_stock_move_lines']"
position="before"
>
<button
type="object"
name="action_update_quantity_on_hand"
invisible="type != 'product'"
class="oe_stat_button"
icon="fa-building-o"
groups="stock.group_stock_user"
>
<div class="o_form_field o_stat_info">
<span class="o_stat_value">
<field
name="secondary_unit_qty_available"
widget="statinfo"
nolabel="1"
/>
</span>
<span class="o_stat_text">
<field name="stock_secondary_uom_id" readonly="1" />
</span>
</div>
</button>
</xpath>
</field>
</record>
<record id="product_form_view_procurement_button" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.product_form_view_procurement_button" />
<field name="arch" type="xml">
<xpath
expr="//button[@name='action_update_quantity_on_hand']"
position="after"
>
<button
type="object"
name="action_update_quantity_on_hand"
invisible="type != 'product'"
class="oe_stat_button"
icon="fa-building-o"
groups="stock.group_stock_user"
>
<div class="o_form_field o_stat_info">
<span class="o_stat_value">
<field
name="secondary_unit_qty_available"
widget="statinfo"
nolabel="1"
/>
</span>
<span class="o_stat_text">
<field name="stock_secondary_uom_id" />
</span>
</div>
</button>
</xpath>
</field>
</record>
<record id="product_template_tree_view" model="ir.ui.view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_tree_view" />
<field name="arch" type="xml">
<xpath expr="//field[@name='uom_id']" position="after">
<field
name="secondary_unit_qty_available"
groups="stock.group_stock_user"
/>
<field
name="stock_secondary_uom_id"
options="{'no_open': True, 'no_create': True}"
groups="stock.group_stock_user"
/>
</xpath>
</field>
</record>
<record id="product_product_tree_view" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_product_tree_view" />
<field name="arch" type="xml">
<xpath expr="//field[@name='uom_id']" position="after">
<field
name="secondary_unit_qty_available"
groups="stock.group_stock_user"
/>
<field
name="stock_secondary_uom_id"
options="{'no_open': True, 'no_create': True}"
groups="stock.group_stock_user"
/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Tecnativa - Sergio Teruel
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_stock_move_line_operation_tree" model="ir.ui.view">
<field name="name">Stock Move Secondary Unit</field>
<field name="model">stock.move.line</field>
<field name="inherit_id" ref="stock.view_stock_move_line_operation_tree" />
<field name="arch" type="xml">
<field name="quantity" position="before">
<field
name="secondary_uom_qty"
readonly="state in ['done', 'cancel'] and is_locked"
force_save="1"
groups="uom.group_uom"
optional="show"
/>
<field
name="secondary_uom_id"
domain="product_id and ['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)] or [(0, '=', 1)]"
readonly="state != 'draft' and id"
options="{'no_create': True}"
groups="uom.group_uom"
optional="show"
/>
</field>
</field>
</record>
<record id="view_stock_move_line_detailed_operation_tree" model="ir.ui.view">
<field name="name">stock.move.line.operations.tree</field>
<field name="model">stock.move.line</field>
<field
name="inherit_id"
ref="stock.view_stock_move_line_detailed_operation_tree"
/>
<field name="arch" type="xml">
<field name="quantity" position="before">
<field
name="secondary_uom_qty"
readonly="state in ['done', 'cancel'] and is_locked"
force_save="1"
groups="uom.group_uom"
optional="show"
/>
<field
name="secondary_uom_id"
domain="product_id and ['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)] or [(0, '=', 1)]"
readonly="state != 'draft' and id"
options="{'no_create': True}"
groups="uom.group_uom"
optional="show"
/>
</field>
</field>
</record>
<record id="view_stock_move_operations" model="ir.ui.view">
<field name="name">stock.move.operations.form.inherit</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_operations" />
<field name="arch" type="xml">
<xpath expr="//field[@name='product_id']" position="after">
<field name="is_initial_demand_editable" invisible="1" />
<field
name="secondary_uom_qty"
readonly="not is_initial_demand_editable"
groups="uom.group_uom"
/>
<field
name="secondary_uom_id"
domain="product_id and ['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)] or [(0, '=', 1)]"
options="{'no_create': True}"
readonly="not is_initial_demand_editable"
groups="uom.group_uom"
/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Tecnativa - Sergio Teruel
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_picking_form" model="ir.ui.view">
<field name="name">Stock Picking Secondary Unit</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='move_ids_without_package']/tree/field[@name='product_uom_qty']"
position="before"
>
<field name="show_operations" invisible="1" />
<field
name="secondary_uom_qty"
readonly="(not is_initial_demand_editable) or (show_operations and is_locked and not is_initial_demand_editable)"
groups="uom.group_uom"
optional="show"
/>
<field
name="secondary_uom_id"
domain="product_id and ['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)] or [(0, '=', 1)]"
options="{'no_create': True}"
readonly="(not is_initial_demand_editable) or (show_operations and is_locked and not is_initial_demand_editable)"
groups="uom.group_uom"
optional="show"
/>
</xpath>
</field>
</record>
</odoo>