From c1492372fbb3c0065063c6d51b150f27d7e5555b Mon Sep 17 00:00:00 2001 From: "sergio.teruel" Date: Tue, 11 Sep 2018 09:05:52 +0200 Subject: [PATCH 01/17] [ADD] stock_secondary_unit: New module for getting stock in a secondary unit --- stock_secondary_unit/README.rst | 87 ++++++++++++++++++ stock_secondary_unit/__init__.py | 2 + stock_secondary_unit/__manifest__.py | 24 +++++ stock_secondary_unit/i18n/es.po | 75 +++++++++++++++ stock_secondary_unit/models/__init__.py | 4 + .../models/procurement_rule.py | 23 +++++ stock_secondary_unit/models/product.py | 45 +++++++++ stock_secondary_unit/models/stock_move.py | 51 ++++++++++ stock_secondary_unit/readme/CONTRIBUTORS.rst | 2 + stock_secondary_unit/readme/DESCRIPTION.rst | 2 + stock_secondary_unit/readme/USAGE.rst | 8 ++ .../report/report_deliveryslip.xml | 27 ++++++ .../static/description/icon.png | Bin 0 -> 9455 bytes stock_secondary_unit/tests/__init__.py | 2 + .../tests/test_stock_secondary_unit.py | 85 +++++++++++++++++ stock_secondary_unit/views/product_views.xml | 86 +++++++++++++++++ .../views/stock_move_views.xml | 21 +++++ .../views/stock_picking_views.xml | 27 ++++++ 18 files changed, 571 insertions(+) create mode 100644 stock_secondary_unit/README.rst create mode 100644 stock_secondary_unit/__init__.py create mode 100644 stock_secondary_unit/__manifest__.py create mode 100644 stock_secondary_unit/i18n/es.po create mode 100644 stock_secondary_unit/models/__init__.py create mode 100644 stock_secondary_unit/models/procurement_rule.py create mode 100644 stock_secondary_unit/models/product.py create mode 100644 stock_secondary_unit/models/stock_move.py create mode 100644 stock_secondary_unit/readme/CONTRIBUTORS.rst create mode 100644 stock_secondary_unit/readme/DESCRIPTION.rst create mode 100644 stock_secondary_unit/readme/USAGE.rst create mode 100755 stock_secondary_unit/report/report_deliveryslip.xml create mode 100644 stock_secondary_unit/static/description/icon.png create mode 100644 stock_secondary_unit/tests/__init__.py create mode 100644 stock_secondary_unit/tests/test_stock_secondary_unit.py create mode 100755 stock_secondary_unit/views/product_views.xml create mode 100755 stock_secondary_unit/views/stock_move_views.xml create mode 100755 stock_secondary_unit/views/stock_picking_views.xml diff --git a/stock_secondary_unit/README.rst b/stock_secondary_unit/README.rst new file mode 100644 index 000000000..c97b74b79 --- /dev/null +++ b/stock_secondary_unit/README.rst @@ -0,0 +1,87 @@ +==================== +Stock Secondary Unit +==================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |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/11.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-11-0/stock-logistics-warehouse-11-0-stock_secondary_unit + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/153/11.0 + :alt: Try me on Runbot + +|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: + +#. Go to a *Product > General Information tab*. +#. Create any record in "Secondary unit of measure". +#. Set the conversion factor. +#. Go to *Inventory tab* and set a second unit of measure. +#. Push button 'Quantity on hand' and set quantities in stock for this product. +#. Go to product list and you can see the secondary unit value. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* Carlos Dauden +* Sergio Teruel + +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 `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_secondary_unit/__init__.py b/stock_secondary_unit/__init__.py new file mode 100644 index 000000000..3275ac2ad --- /dev/null +++ b/stock_secondary_unit/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/stock_secondary_unit/__manifest__.py b/stock_secondary_unit/__manifest__.py new file mode 100644 index 000000000..5e0d2718b --- /dev/null +++ b/stock_secondary_unit/__manifest__.py @@ -0,0 +1,24 @@ +# 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': '11.0.1.0.0', + 'development_status': 'Beta', + 'category': 'stock', + 'website': 'https://github.com/OCA/stock-logistics-warehouse', + 'author': 'Tecnativa, Odoo Community Association (OCA)', + 'license': 'AGPL-3', + 'application': False, + 'installable': True, + 'depends': [ + 'sale_stock', + 'product_secondary_unit', + ], + 'data': [ + 'views/product_views.xml', + 'views/stock_move_views.xml', + 'views/stock_picking_views.xml', + 'report/report_deliveryslip.xml', + ], +} diff --git a/stock_secondary_unit/i18n/es.po b/stock_secondary_unit/i18n/es.po new file mode 100644 index 000000000..a67559a4e --- /dev/null +++ b/stock_secondary_unit/i18n/es.po @@ -0,0 +1,75 @@ +# 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: 2018-09-11 08:28+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es_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: Poedit 2.0.6\n" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_display_name +msgid "Display Name" +msgstr "Mostrar Nombre" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_id +msgid "ID" +msgstr "ID" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit___last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: stock_secondary_unit +#: model:ir.ui.view,arch_db:stock_secondary_unit.product_form_view_procurement_button +#: model:ir.ui.view,arch_db:stock_secondary_unit.product_template_form_view_procurement_button +msgid "On Hand (2unit)" +msgstr "A mano (2Ud.)" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_product_product +msgid "Product" +msgstr "Producto" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_product_template +msgid "Product Template" +msgstr "Plantilla de producto" + +#. 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_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_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.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_product_secondary_unit +msgid "stock.product.secondary.unit" +msgstr "" + +#~ msgid "Second Unit Quantity On Hand" +#~ msgstr "Segunda unidad de medida por defecto" diff --git a/stock_secondary_unit/models/__init__.py b/stock_secondary_unit/models/__init__.py new file mode 100644 index 000000000..e86540488 --- /dev/null +++ b/stock_secondary_unit/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import procurement_rule +from . import product +from . import stock_move diff --git a/stock_secondary_unit/models/procurement_rule.py b/stock_secondary_unit/models/procurement_rule.py new file mode 100644 index 000000000..1d6ec8133 --- /dev/null +++ b/stock_secondary_unit/models/procurement_rule.py @@ -0,0 +1,23 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import models + + +class ProcurementRule(models.Model): + _inherit = 'procurement.rule' + + def _get_stock_move_values(self, product_id, product_qty, product_uom, + location_id, name, origin, values, group_id): + res = super(ProcurementRule, self)._get_stock_move_values( + product_id, product_qty, product_uom, location_id, name, origin, + values, group_id + ) + if values.get('sale_line_id', False): + sale_line = self.env['sale.order.line'].browse( + values['sale_line_id']) + if sale_line.secondary_uom_id: + res.update({ + 'secondary_uom_id': sale_line.secondary_uom_id.id, + 'secondary_uom_qty': sale_line.secondary_uom_qty, + }) + return res diff --git a/stock_secondary_unit/models/product.py b/stock_secondary_unit/models/product.py new file mode 100644 index 000000000..49efefb03 --- /dev/null +++ b/stock_secondary_unit/models/product.py @@ -0,0 +1,45 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models +from odoo.addons import decimal_precision as dp +from odoo.tools.float_utils import float_round + + +class StockProductSecondaryUnit(models.AbstractModel): + _name = 'stock.product.secondary.unit' + + secondary_unit_qty_available = fields.Float( + string='Quantity On Hand (2Unit)', + compute='_compute_secondary_unit_qty_available', + digits=dp.get_precision('Product Unit of Measure'), + ) + + def _compute_secondary_unit_qty_available(self): + for product in self.filtered('stock_secondary_uom_id'): + 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) + + +class ProductTemplate(models.Model): + _inherit = ['product.template', 'stock.product.secondary.unit'] + _name = 'product.template' + + stock_secondary_uom_id = fields.Many2one( + comodel_name='product.secondary.unit', + string='Second unit for inventory', + ) + + def _compute_quantities(self): + super()._compute_quantities() + self._compute_secondary_unit_qty_available() + + +class ProductProduct(models.Model): + _inherit = ['product.product', 'stock.product.secondary.unit'] + _name = 'product.product' + + def _compute_quantities(self): + super()._compute_quantities() + self._compute_secondary_unit_qty_available() diff --git a/stock_secondary_unit/models/stock_move.py b/stock_secondary_unit/models/stock_move.py new file mode 100644 index 000000000..dcb5d6156 --- /dev/null +++ b/stock_secondary_unit/models/stock_move.py @@ -0,0 +1,51 @@ +# 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.addons import decimal_precision as dp +from odoo.tools.float_utils import float_round + + +class StockSecondaryUnitMixin(models.AbstractModel): + _name = 'stock.secondary.unit.mixin' + + secondary_uom_id = fields.Many2one( + comodel_name='product.secondary.unit', + string='Second unit', + ) + secondary_uom_qty = fields.Float( + string='Secondary Qty', + digits=dp.get_precision('Product Unit of Measure'), + ) + + +class StockMove(models.Model): + _inherit = ['stock.move', 'stock.secondary.unit.mixin'] + _name = 'stock.move' + + def _merge_moves_fields(self): + res = super(StockMove, self)._merge_moves_fields() + res['secondary_uom_qty'] = self[-1:].secondary_uom_qty + return res + + +class StockMoveLine(models.Model): + _inherit = ['stock.move.line', 'stock.secondary.unit.mixin'] + _name = 'stock.move.line' + + @api.model + def create(self, vals): + move = self.env['stock.move'].browse(vals['move_id']) + if move.secondary_uom_id: + uom = self.env['product.uom'].browse(vals['product_uom_id']) + factor = move.secondary_uom_id.factor * uom.factor + move_line_qty = vals.get( + 'product_uom_qty', vals.get('qty_done', 0.0)) + qty = float_round( + move_line_qty / (factor or 1.0), + precision_rounding=move.secondary_uom_id.uom_id.factor + ) + vals.update({ + 'secondary_uom_qty': qty, + 'secondary_uom_id': move.secondary_uom_id.id, + }) + return super().create(vals) diff --git a/stock_secondary_unit/readme/CONTRIBUTORS.rst b/stock_secondary_unit/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..b919cb776 --- /dev/null +++ b/stock_secondary_unit/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Carlos Dauden +* Sergio Teruel diff --git a/stock_secondary_unit/readme/DESCRIPTION.rst b/stock_secondary_unit/readme/DESCRIPTION.rst new file mode 100644 index 000000000..ce69e8533 --- /dev/null +++ b/stock_secondary_unit/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module extends the functionality of stock module to allow define +other units with their conversion factor. diff --git a/stock_secondary_unit/readme/USAGE.rst b/stock_secondary_unit/readme/USAGE.rst new file mode 100644 index 000000000..4d189ae53 --- /dev/null +++ b/stock_secondary_unit/readme/USAGE.rst @@ -0,0 +1,8 @@ +To use this module you need to: + +#. Go to a *Product > General Information tab*. +#. Create any record in "Secondary unit of measure". +#. Set the conversion factor. +#. Go to *Inventory tab* and set a second unit of measure. +#. Push button 'Quantity on hand' and set quantities in stock for this product. +#. Go to product list and you can see the secondary unit value. diff --git a/stock_secondary_unit/report/report_deliveryslip.xml b/stock_secondary_unit/report/report_deliveryslip.xml new file mode 100755 index 000000000..b7c7ee700 --- /dev/null +++ b/stock_secondary_unit/report/report_deliveryslip.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/stock_secondary_unit/static/description/icon.png b/stock_secondary_unit/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/stock_secondary_unit/tests/__init__.py b/stock_secondary_unit/tests/__init__.py new file mode 100644 index 000000000..38c91ad2e --- /dev/null +++ b/stock_secondary_unit/tests/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import test_stock_secondary_unit diff --git a/stock_secondary_unit/tests/test_stock_secondary_unit.py b/stock_secondary_unit/tests/test_stock_secondary_unit.py new file mode 100644 index 000000000..4dfd737d6 --- /dev/null +++ b/stock_secondary_unit/tests/test_stock_secondary_unit.py @@ -0,0 +1,85 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.tests import SavepointCase + + +class TestProductSecondaryUnit(SavepointCase): + at_install = False + post_install = True + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.warehouse = cls.env.ref('stock.warehouse0') + cls.product_uom_kg = cls.env.ref('product.product_uom_kgm') + cls.product_uom_unit = cls.env.ref('product.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, + }) + Product = cls.env['product.product'] + 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-700', + '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, + }), + ], + 'attribute_line_ids': [(0, 0, { + 'attribute_id': cls.attribute_color.id, + })], + }) + cls.product_white = Product.create({ + 'product_tmpl_id': cls.product_template.id, + 'attribute_value_ids': [(6, 0, [cls.attribute_value_white.id])], + }) + cls.product_black = Product.create({ + 'product_tmpl_id': cls.product_template.id, + 'attribute_value_ids': [(6, 0, [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.write({ + 'sale_secondary_uom_id': secondary_unit.id, + 'stock_secondary_uom_id': secondary_unit.id, + }) + StockQuant = cls.env['stock.quant'] + cls.quant_white = StockQuant.create({ + 'product_id': cls.product_white.id, + 'location_id': cls.warehouse.lot_stock_id.id, + 'quantity': 10.0, + }) + cls.quant_black = StockQuant.create({ + 'product_id': cls.product_black.id, + 'location_id': cls.warehouse.lot_stock_id.id, + 'quantity': 10.0, + }) + + def test_stock_secondary_unit_template(self): + self.assertEqual( + self.product_template.secondary_unit_qty_available, 40.0) + + def test_stock_secondary_unit_variant(self): + for variant in self.product_template.product_variant_ids.filtered( + 'attribute_value_ids'): + self.assertEqual(variant.secondary_unit_qty_available, 20) diff --git a/stock_secondary_unit/views/product_views.xml b/stock_secondary_unit/views/product_views.xml new file mode 100755 index 000000000..8b14bc6da --- /dev/null +++ b/stock_secondary_unit/views/product_views.xml @@ -0,0 +1,86 @@ + + + + + + Product template Secondary Unit + product.template + + + + + + + + + + + + + product.template + + + + + + + + + + + product.product + + + + + + + + + + + product.template + + + + + + + + + + + + product.product + + + + + + + + + + + diff --git a/stock_secondary_unit/views/stock_move_views.xml b/stock_secondary_unit/views/stock_move_views.xml new file mode 100755 index 000000000..c130d219b --- /dev/null +++ b/stock_secondary_unit/views/stock_move_views.xml @@ -0,0 +1,21 @@ + + + + + + Stock Move Secondary Unit + stock.move.line + + + + + + + + + + + diff --git a/stock_secondary_unit/views/stock_picking_views.xml b/stock_secondary_unit/views/stock_picking_views.xml new file mode 100755 index 000000000..0c099bff2 --- /dev/null +++ b/stock_secondary_unit/views/stock_picking_views.xml @@ -0,0 +1,27 @@ + + + + + + Stock Picking Secondary Unit + stock.picking + + + + + + + + + + + + + + + From f2c258e5e814edadbdbfeceb01c434273455f729 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sat, 16 Feb 2019 13:28:20 +0000 Subject: [PATCH 02/17] [UPD] README.rst --- .../static/description/index.html | 434 ++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 stock_secondary_unit/static/description/index.html diff --git a/stock_secondary_unit/static/description/index.html b/stock_secondary_unit/static/description/index.html new file mode 100644 index 000000000..65a1255be --- /dev/null +++ b/stock_secondary_unit/static/description/index.html @@ -0,0 +1,434 @@ + + + + + + +Stock Secondary Unit + + + +
+

Stock Secondary Unit

+ + +

Beta License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runbot

+

This module extends the functionality of stock module to allow define +other units with their conversion factor.

+

Table of contents

+ +
+

Usage

+

To use this module you need to:

+
    +
  1. Go to a Product > General Information tab.
  2. +
  3. Create any record in “Secondary unit of measure”.
  4. +
  5. Set the conversion factor.
  6. +
  7. Go to Inventory tab and set a second unit of measure.
  8. +
  9. Push button ‘Quantity on hand’ and set quantities in stock for this product.
  10. +
  11. Go to product list and you can see the secondary unit value.
  12. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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 project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 07f23f037f8c1cab9e32ab28e8ed947fef9e5a36 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Sat, 16 Feb 2019 13:38:59 +0000 Subject: [PATCH 03/17] [UPD] Update stock_secondary_unit.pot --- stock_secondary_unit/i18n/es.po | 50 ++++++++- .../i18n/stock_secondary_unit.pot | 105 ++++++++++++++++++ 2 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 stock_secondary_unit/i18n/stock_secondary_unit.pot diff --git a/stock_secondary_unit/i18n/es.po b/stock_secondary_unit/i18n/es.po index a67559a4e..f1716d95e 100644 --- a/stock_secondary_unit/i18n/es.po +++ b/stock_secondary_unit/i18n/es.po @@ -17,26 +17,38 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.0.6\n" +#. module: stock_secondary_unit +#: model:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document +msgid "Secondary Qty" +msgstr "" + #. module: stock_secondary_unit #: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_display_name +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin_display_name msgid "Display Name" msgstr "Mostrar Nombre" #. module: stock_secondary_unit #: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_id +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin_id msgid "ID" msgstr "ID" #. module: stock_secondary_unit #: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit___last_update +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin___last_update msgid "Last Modified on" msgstr "Última modificación en" #. module: stock_secondary_unit -#: model:ir.ui.view,arch_db:stock_secondary_unit.product_form_view_procurement_button -#: model:ir.ui.view,arch_db:stock_secondary_unit.product_template_form_view_procurement_button -msgid "On Hand (2unit)" -msgstr "A mano (2Ud.)" +#: model:ir.model,name:stock_secondary_unit.model_stock_move_line +msgid "Packing Operation" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_procurement_rule +msgid "Procurement Rule" +msgstr "" #. module: stock_secondary_unit #: model:ir.model,name:stock_secondary_unit.model_product_product @@ -55,21 +67,51 @@ msgstr "Plantilla de producto" 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_line_secondary_uom_id +#: 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_secondary_unit_mixin_secondary_uom_id +#, fuzzy +msgid "Second unit" +msgstr "Unidad Secundaria" + #. 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_line_secondary_uom_qty +#: 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_secondary_unit_mixin_secondary_uom_qty +#, fuzzy +msgid "Secondary Qty" +msgstr "Unidad Secundaria" + #. module: stock_secondary_unit #: model: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 "" + #. module: stock_secondary_unit #: model:ir.model,name:stock_secondary_unit.model_stock_product_secondary_unit msgid "stock.product.secondary.unit" msgstr "" +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_stock_secondary_unit_mixin +#, 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" diff --git a/stock_secondary_unit/i18n/stock_secondary_unit.pot b/stock_secondary_unit/i18n/stock_secondary_unit.pot new file mode 100644 index 000000000..cec48daa5 --- /dev/null +++ b/stock_secondary_unit/i18n/stock_secondary_unit.pot @@ -0,0 +1,105 @@ +# 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" +"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:ir.ui.view,arch_db:stock_secondary_unit.report_delivery_document +msgid "Secondary Qty" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_display_name +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin_display_name +msgid "Display Name" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit_id +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin_id +msgid "ID" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_product_secondary_unit___last_update +#: model:ir.model.fields,field_description:stock_secondary_unit.field_stock_secondary_unit_mixin___last_update +msgid "Last Modified on" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_stock_move_line +msgid "Packing Operation" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_procurement_rule +msgid "Procurement Rule" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_product_product +msgid "Product" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_product_template +msgid "Product Template" +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_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_line_secondary_uom_id +#: 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_secondary_unit_mixin_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_line_secondary_uom_qty +#: 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_secondary_unit_mixin_secondary_uom_qty +msgid "Secondary Qty" +msgstr "" + +#. module: stock_secondary_unit +#: model: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 +msgid "stock.product.secondary.unit" +msgstr "" + +#. module: stock_secondary_unit +#: model:ir.model,name:stock_secondary_unit.model_stock_secondary_unit_mixin +msgid "stock.secondary.unit.mixin" +msgstr "" + From 56d27f003a6f1e5a47752e230cbc069d9640bad3 Mon Sep 17 00:00:00 2001 From: Sergio Teruel Date: Tue, 19 Feb 2019 18:20:36 +0100 Subject: [PATCH 04/17] [11.0][FIX] stock_secondary_unit: Remove procurement_rule move. Fix dependencies --- stock_secondary_unit/__manifest__.py | 2 +- stock_secondary_unit/models/__init__.py | 1 - .../models/procurement_rule.py | 23 ------------------- 3 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 stock_secondary_unit/models/procurement_rule.py diff --git a/stock_secondary_unit/__manifest__.py b/stock_secondary_unit/__manifest__.py index 5e0d2718b..d2d65f53a 100644 --- a/stock_secondary_unit/__manifest__.py +++ b/stock_secondary_unit/__manifest__.py @@ -12,7 +12,7 @@ 'application': False, 'installable': True, 'depends': [ - 'sale_stock', + 'stock', 'product_secondary_unit', ], 'data': [ diff --git a/stock_secondary_unit/models/__init__.py b/stock_secondary_unit/models/__init__.py index e86540488..960afa99e 100644 --- a/stock_secondary_unit/models/__init__.py +++ b/stock_secondary_unit/models/__init__.py @@ -1,4 +1,3 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from . import procurement_rule from . import product from . import stock_move diff --git a/stock_secondary_unit/models/procurement_rule.py b/stock_secondary_unit/models/procurement_rule.py deleted file mode 100644 index 1d6ec8133..000000000 --- a/stock_secondary_unit/models/procurement_rule.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2018 Tecnativa - Sergio Teruel -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import models - - -class ProcurementRule(models.Model): - _inherit = 'procurement.rule' - - def _get_stock_move_values(self, product_id, product_qty, product_uom, - location_id, name, origin, values, group_id): - res = super(ProcurementRule, self)._get_stock_move_values( - product_id, product_qty, product_uom, location_id, name, origin, - values, group_id - ) - if values.get('sale_line_id', False): - sale_line = self.env['sale.order.line'].browse( - values['sale_line_id']) - if sale_line.secondary_uom_id: - res.update({ - 'secondary_uom_id': sale_line.secondary_uom_id.id, - 'secondary_uom_qty': sale_line.secondary_uom_qty, - }) - return res From 6e2dd7e94e55aca6c0cc85dfff69701e2562a9c1 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Wed, 20 Feb 2019 12:59:37 +0000 Subject: [PATCH 05/17] [UPD] Update stock_secondary_unit.pot --- stock_secondary_unit/i18n/stock_secondary_unit.pot | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stock_secondary_unit/i18n/stock_secondary_unit.pot b/stock_secondary_unit/i18n/stock_secondary_unit.pot index cec48daa5..3d970583b 100644 --- a/stock_secondary_unit/i18n/stock_secondary_unit.pot +++ b/stock_secondary_unit/i18n/stock_secondary_unit.pot @@ -41,11 +41,6 @@ msgstr "" msgid "Packing Operation" msgstr "" -#. module: stock_secondary_unit -#: model:ir.model,name:stock_secondary_unit.model_procurement_rule -msgid "Procurement Rule" -msgstr "" - #. module: stock_secondary_unit #: model:ir.model,name:stock_secondary_unit.model_product_product msgid "Product" From 243e8efb87e530af910b5a93c38f22bbf26fd58f Mon Sep 17 00:00:00 2001 From: Kitti U Date: Thu, 4 Apr 2019 10:59:27 +0700 Subject: [PATCH 06/17] [12.0][MIG] stock_secondary_unit --- stock_secondary_unit/README.rst | 11 ++-- stock_secondary_unit/__manifest__.py | 2 +- stock_secondary_unit/models/product.py | 1 + stock_secondary_unit/models/stock_move.py | 3 +- stock_secondary_unit/readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 7 ++- .../tests/test_stock_secondary_unit.py | 57 ++++++++++++++----- stock_secondary_unit/views/product_views.xml | 10 ++-- .../views/stock_move_views.xml | 2 +- .../views/stock_picking_views.xml | 6 +- 10 files changed, 66 insertions(+), 34 deletions(-) diff --git a/stock_secondary_unit/README.rst b/stock_secondary_unit/README.rst index c97b74b79..4fc4c5c55 100644 --- a/stock_secondary_unit/README.rst +++ b/stock_secondary_unit/README.rst @@ -14,13 +14,13 @@ Stock Secondary Unit :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/11.0/stock_secondary_unit + :target: https://github.com/OCA/stock-logistics-warehouse/tree/12.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-11-0/stock-logistics-warehouse-11-0-stock_secondary_unit + :target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-12-0/stock-logistics-warehouse-12-0-stock_secondary_unit :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/153/11.0 + :target: https://runbot.odoo-community.org/runbot/153/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -51,7 +51,7 @@ Bug Tracker Bugs are tracked on `GitHub 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -68,6 +68,7 @@ Contributors * Carlos Dauden * Sergio Teruel +* Kitti Upariphutthiphong Maintainers ~~~~~~~~~~~ @@ -82,6 +83,6 @@ 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 `_ project on GitHub. +This module is part of the `OCA/stock-logistics-warehouse `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_secondary_unit/__manifest__.py b/stock_secondary_unit/__manifest__.py index d2d65f53a..6c6c66b3d 100644 --- a/stock_secondary_unit/__manifest__.py +++ b/stock_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { 'name': 'Stock Secondary Unit', 'summary': 'Get product quantities in a secondary unit', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'development_status': 'Beta', 'category': 'stock', 'website': 'https://github.com/OCA/stock-logistics-warehouse', diff --git a/stock_secondary_unit/models/product.py b/stock_secondary_unit/models/product.py index 49efefb03..46fa07283 100644 --- a/stock_secondary_unit/models/product.py +++ b/stock_secondary_unit/models/product.py @@ -7,6 +7,7 @@ from odoo.tools.float_utils import float_round class StockProductSecondaryUnit(models.AbstractModel): _name = 'stock.product.secondary.unit' + _description = 'Stock Product Secondary Unit' secondary_unit_qty_available = fields.Float( string='Quantity On Hand (2Unit)', diff --git a/stock_secondary_unit/models/stock_move.py b/stock_secondary_unit/models/stock_move.py index dcb5d6156..13b553d97 100644 --- a/stock_secondary_unit/models/stock_move.py +++ b/stock_secondary_unit/models/stock_move.py @@ -7,6 +7,7 @@ from odoo.tools.float_utils import float_round class StockSecondaryUnitMixin(models.AbstractModel): _name = 'stock.secondary.unit.mixin' + _description = 'Stock Secondary Unit Mixin' secondary_uom_id = fields.Many2one( comodel_name='product.secondary.unit', @@ -36,7 +37,7 @@ class StockMoveLine(models.Model): def create(self, vals): move = self.env['stock.move'].browse(vals['move_id']) if move.secondary_uom_id: - uom = self.env['product.uom'].browse(vals['product_uom_id']) + uom = self.env['uom.uom'].browse(vals['product_uom_id']) factor = move.secondary_uom_id.factor * uom.factor move_line_qty = vals.get( 'product_uom_qty', vals.get('qty_done', 0.0)) diff --git a/stock_secondary_unit/readme/CONTRIBUTORS.rst b/stock_secondary_unit/readme/CONTRIBUTORS.rst index b919cb776..3b07d85d5 100644 --- a/stock_secondary_unit/readme/CONTRIBUTORS.rst +++ b/stock_secondary_unit/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Carlos Dauden * Sergio Teruel +* Kitti Upariphutthiphong diff --git a/stock_secondary_unit/static/description/index.html b/stock_secondary_unit/static/description/index.html index 65a1255be..d6d5885d2 100644 --- a/stock_secondary_unit/static/description/index.html +++ b/stock_secondary_unit/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runbot

This module extends the functionality of stock module to allow define other units with their conversion factor.

Table of contents

@@ -400,7 +400,7 @@ other units with their conversion factor.

Bugs are tracked on GitHub 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.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -416,6 +416,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
@@ -425,7 +426,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

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 project on GitHub.

+

This module is part of the OCA/stock-logistics-warehouse project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/stock_secondary_unit/tests/test_stock_secondary_unit.py b/stock_secondary_unit/tests/test_stock_secondary_unit.py index 4dfd737d6..d62b553f9 100644 --- a/stock_secondary_unit/tests/test_stock_secondary_unit.py +++ b/stock_secondary_unit/tests/test_stock_secondary_unit.py @@ -11,8 +11,8 @@ class TestProductSecondaryUnit(SavepointCase): def setUpClass(cls): super().setUpClass() cls.warehouse = cls.env.ref('stock.warehouse0') - cls.product_uom_kg = cls.env.ref('product.product_uom_kgm') - cls.product_uom_unit = cls.env.ref('product.product_uom_unit') + cls.product_uom_kg = cls.env.ref('uom.product_uom_kgm') + 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'}) @@ -24,7 +24,6 @@ class TestProductSecondaryUnit(SavepointCase): 'name': 'test_black', 'attribute_id': cls.attribute_color.id, }) - Product = cls.env['product.product'] cls.product_template = cls.env['product.template'].create({ 'name': 'test', 'uom_id': cls.product_uom_kg.id, @@ -46,16 +45,10 @@ class TestProductSecondaryUnit(SavepointCase): ], '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)], })], }) - cls.product_white = Product.create({ - 'product_tmpl_id': cls.product_template.id, - 'attribute_value_ids': [(6, 0, [cls.attribute_value_white.id])], - }) - cls.product_black = Product.create({ - 'product_tmpl_id': cls.product_template.id, - 'attribute_value_ids': [(6, 0, [cls.attribute_value_black.id])], - }) secondary_unit = cls.env['product.secondary.unit'].search([ ('product_tmpl_id', '=', cls.product_template.id), ], limit=1) @@ -65,21 +58,55 @@ class TestProductSecondaryUnit(SavepointCase): }) StockQuant = cls.env['stock.quant'] cls.quant_white = StockQuant.create({ - 'product_id': cls.product_white.id, + '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_black.id, + 'product_id': cls.product_template.product_variant_ids[1].id, 'location_id': cls.warehouse.lot_stock_id.id, 'quantity': 10.0, }) - def test_stock_secondary_unit_template(self): + def test_01_stock_secondary_unit_template(self): self.assertEqual( self.product_template.secondary_unit_qty_available, 40.0) - def test_stock_secondary_unit_variant(self): + def test_02_stock_secondary_unit_variant(self): for variant in self.product_template.product_variant_ids.filtered( '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] + location = self.env.ref('stock.stock_location_suppliers') + location_dest = self.env.ref('stock.stock_location_stock') + picking_type = self.env.ref('stock.picking_type_in') + move_vals = { + 'product_id': product1.id, + 'name': product1.display_name, + 'secondary_uom_id': product1.secondary_uom_ids[0].id, + 'product_uom': product1.uom_id.id, + 'product_uom_qty': 10.0, + 'location_id': location.id, + 'location_dest_id': location_dest.id, + } + do_vals = { + 'location_id': location.id, + 'location_dest_id': location_dest.id, + 'picking_type_id': picking_type.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.assertEquals(len(delivery_order.move_lines), 1) + self.assertEquals(len(delivery_order.move_line_ids), 1) + # Qty merged to 20, and secondary unit qty is 40line + uom_qty = sum(delivery_order.move_lines.mapped('product_uom_qty')) + secondary_uom_qty = \ + sum(delivery_order.move_line_ids.mapped('secondary_uom_qty')) + self.assertEquals(uom_qty, 20.0) + self.assertEquals(secondary_uom_qty, 40.0) diff --git a/stock_secondary_unit/views/product_views.xml b/stock_secondary_unit/views/product_views.xml index 8b14bc6da..fc24552f0 100755 --- a/stock_secondary_unit/views/product_views.xml +++ b/stock_secondary_unit/views/product_views.xml @@ -7,7 +7,7 @@ Product template Secondary Unit product.template - + @@ -23,7 +23,7 @@ product.template - +