From 6469d1b6d8e2d0ec7a5984b1c5a634ed2bcf83ab Mon Sep 17 00:00:00 2001 From: Sergio Teruel Date: Thu, 25 Oct 2018 23:03:04 +0200 Subject: [PATCH 01/49] purchase_order_secondary_unit: New module to allow buy in secondary units --- purchase_order_secondary_unit/README.rst | 85 ++++ purchase_order_secondary_unit/__init__.py | 2 + purchase_order_secondary_unit/__manifest__.py | 23 + purchase_order_secondary_unit/i18n/es.po | 44 ++ .../i18n/purchase_order_secondary_unit.pot | 41 ++ .../models/__init__.py | 3 + .../models/product_template.py | 12 + .../models/purchase_order.py | 65 +++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 2 + .../readme/USAGE.rst | 7 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 432 ++++++++++++++++++ .../tests/__init__.py | 2 + .../test_purchase_order_secondary_unit.py | 84 ++++ .../views/product_views.xml | 20 + .../views/purchase_order_views.xml | 29 ++ 17 files changed, 852 insertions(+) create mode 100644 purchase_order_secondary_unit/README.rst create mode 100644 purchase_order_secondary_unit/__init__.py create mode 100644 purchase_order_secondary_unit/__manifest__.py create mode 100644 purchase_order_secondary_unit/i18n/es.po create mode 100644 purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot create mode 100644 purchase_order_secondary_unit/models/__init__.py create mode 100755 purchase_order_secondary_unit/models/product_template.py create mode 100644 purchase_order_secondary_unit/models/purchase_order.py create mode 100644 purchase_order_secondary_unit/readme/CONTRIBUTORS.rst create mode 100644 purchase_order_secondary_unit/readme/DESCRIPTION.rst create mode 100644 purchase_order_secondary_unit/readme/USAGE.rst create mode 100644 purchase_order_secondary_unit/static/description/icon.png create mode 100644 purchase_order_secondary_unit/static/description/index.html create mode 100644 purchase_order_secondary_unit/tests/__init__.py create mode 100644 purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py create mode 100755 purchase_order_secondary_unit/views/product_views.xml create mode 100755 purchase_order_secondary_unit/views/purchase_order_views.xml diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst new file mode 100644 index 00000000000..d6687078e86 --- /dev/null +++ b/purchase_order_secondary_unit/README.rst @@ -0,0 +1,85 @@ +============================= +Purchase Order 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%2Fpurchase--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/purchase-workflow/tree/11.0/purchase_order_secondary_unit + :alt: OCA/purchase-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/purchase-workflow-11-0/purchase-workflow-11-0-purchase_order_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/142/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of purchase orders to allow buy products +in secondary unit of distinct category. + +**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 *Purchase > Quotation > Create*. +#. Change quantities in line and secondary unit (produc_qty will be change). + +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 +~~~~~~~~~~~~ + +* 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/purchase-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_order_secondary_unit/__init__.py b/purchase_order_secondary_unit/__init__.py new file mode 100644 index 00000000000..3275ac2adf3 --- /dev/null +++ b/purchase_order_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/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py new file mode 100644 index 00000000000..45c6dd339bb --- /dev/null +++ b/purchase_order_secondary_unit/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + 'name': 'Purchase Order Secondary Unit', + 'summary': 'Purchase product in a secondary unit', + 'version': '11.0.1.0.0', + 'development_status': 'Beta', + 'category': 'Purchase', + 'website': 'https://github.com/OCA/purchase-workflow', + 'author': 'Tecnativa, Odoo Community Association (OCA)', + 'license': 'AGPL-3', + 'application': False, + 'installable': True, + 'auto_install': True, + 'depends': [ + 'purchase', + 'product_secondary_unit', + ], + 'data': [ + 'views/product_views.xml', + 'views/purchase_order_views.xml', + ], +} diff --git a/purchase_order_secondary_unit/i18n/es.po b/purchase_order_secondary_unit/i18n/es.po new file mode 100644 index 00000000000..7fd98c49971 --- /dev/null +++ b/purchase_order_secondary_unit/i18n/es.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_secondary_unit +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-10-25 21:04+0000\n" +"PO-Revision-Date: 2018-10-25 23:05+0200\n" +"Last-Translator: \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: Poedit 2.0.6\n" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product_purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template_purchase_secondary_uom_id +msgid "Default unit purchase" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_template +msgid "Product Template" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Línea pedido de compra" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_qty +msgid "Secondary Qty" +msgstr "Cdad. secundaria" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_id +msgid "Secondary uom" +msgstr "UdM Secundaría" diff --git a/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot new file mode 100644 index 00000000000..f911f132928 --- /dev/null +++ b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_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: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product_purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template_purchase_secondary_uom_id +msgid "Default unit purchase" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_template +msgid "Product Template" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_qty +msgid "Secondary Qty" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_id +msgid "Secondary uom" +msgstr "" + diff --git a/purchase_order_secondary_unit/models/__init__.py b/purchase_order_secondary_unit/models/__init__.py new file mode 100644 index 00000000000..1bc2f98dc03 --- /dev/null +++ b/purchase_order_secondary_unit/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import product_template +from . import purchase_order diff --git a/purchase_order_secondary_unit/models/product_template.py b/purchase_order_secondary_unit/models/product_template.py new file mode 100755 index 00000000000..bd0b29e83c5 --- /dev/null +++ b/purchase_order_secondary_unit/models/product_template.py @@ -0,0 +1,12 @@ +# 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' + + purchase_secondary_uom_id = fields.Many2one( + comodel_name='product.secondary.unit', + string='Default unit purchase', + ) diff --git a/purchase_order_secondary_unit/models/purchase_order.py b/purchase_order_secondary_unit/models/purchase_order.py new file mode 100644 index 00000000000..cdc7c378e98 --- /dev/null +++ b/purchase_order_secondary_unit/models/purchase_order.py @@ -0,0 +1,65 @@ +# 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_compare, float_round + + +class PurchaseOrderLine(models.Model): + _inherit = 'purchase.order.line' + + secondary_uom_qty = fields.Float( + string='Secondary Qty', + digits=dp.get_precision('Product Unit of Measure'), + ) + secondary_uom_id = fields.Many2one( + comodel_name='product.secondary.unit', + string='Secondary uom', + ondelete='restrict', + ) + + @api.onchange('secondary_uom_id', 'secondary_uom_qty') + def _onchange_secondary_uom(self): + if not self.secondary_uom_id: + return + factor = self.secondary_uom_id.factor * self.product_uom.factor + qty = float_round( + self.secondary_uom_qty * factor, + precision_rounding=self.product_uom.rounding + ) + if float_compare( + self.product_qty, qty, + precision_rounding=self.product_uom.rounding) != 0: + self.product_qty = qty + + @api.onchange('product_qty') + def _onchange_product_qty_purchase_order_secondary_unit(self): + if not self.secondary_uom_id: + return + factor = self.secondary_uom_id.factor * self.product_uom.factor + qty = float_round( + self.product_qty / (factor or 1.0), + precision_rounding=self.secondary_uom_id.uom_id.rounding + ) + if float_compare( + self.secondary_uom_qty, qty, + precision_rounding=self.secondary_uom_id.uom_id.rounding) != 0: + self.secondary_uom_qty = qty + + @api.onchange('product_uom') + def _onchange_product_uom_purchase_order_secondary_unit(self): + if not self.secondary_uom_id: + return + factor = self.product_uom.factor * self.secondary_uom_id.factor + qty = float_round( + self.product_qty / (factor or 1.0), + precision_rounding=self.product_uom.rounding + ) + if float_compare( + self.secondary_uom_qty, qty, + precision_rounding=self.product_uom.rounding) != 0: + self.secondary_uom_qty = qty + + @api.onchange('product_id') + def _onchange_product_id_purchase_order_secondary_unit(self): + self.secondary_uom_id = self.product_id.purchase_secondary_uom_id diff --git a/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst b/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..f24a0b0dc74 --- /dev/null +++ b/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sergio Teruel diff --git a/purchase_order_secondary_unit/readme/DESCRIPTION.rst b/purchase_order_secondary_unit/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..0d1e023e2d1 --- /dev/null +++ b/purchase_order_secondary_unit/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module extends the functionality of purchase orders to allow buy products +in secondary unit of distinct category. diff --git a/purchase_order_secondary_unit/readme/USAGE.rst b/purchase_order_secondary_unit/readme/USAGE.rst new file mode 100644 index 00000000000..c2aef4ad5bf --- /dev/null +++ b/purchase_order_secondary_unit/readme/USAGE.rst @@ -0,0 +1,7 @@ +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 *Purchase > Quotation > Create*. +#. Change quantities in line and secondary unit (produc_qty will be change). diff --git a/purchase_order_secondary_unit/static/description/icon.png b/purchase_order_secondary_unit/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html new file mode 100644 index 00000000000..ae4bd72d48c --- /dev/null +++ b/purchase_order_secondary_unit/static/description/index.html @@ -0,0 +1,432 @@ + + + + + + +Purchase Order Secondary Unit + + + +
+

Purchase Order Secondary Unit

+ + +

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runbot

+

This module extends the functionality of purchase orders to allow buy products +in secondary unit of distinct category.

+

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 Purchase > Quotation > Create.
  8. +
  9. Change quantities in line and secondary unit (produc_qty will be change).
  10. +
+
+
+

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

+

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

+
+
+
+ + diff --git a/purchase_order_secondary_unit/tests/__init__.py b/purchase_order_secondary_unit/tests/__init__.py new file mode 100644 index 00000000000..6df95cebd79 --- /dev/null +++ b/purchase_order_secondary_unit/tests/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import test_purchase_order_secondary_unit diff --git a/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py new file mode 100644 index 00000000000..d9ea71d6ab1 --- /dev/null +++ b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py @@ -0,0 +1,84 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields +from odoo.tests import SavepointCase + + +class TestPurchaseOrderSecondaryUnit(SavepointCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.product_uom_kg = cls.env.ref('product.product_uom_kgm') + cls.product_uom_gram = cls.env.ref('product.product_uom_gram') + cls.product_uom_unit = cls.env.ref('product.product_uom_unit') + cls.product = cls.env['product.product'].create({ + 'name': 'test', + 'uom_id': cls.product_uom_kg.id, + 'uom_po_id': cls.product_uom_kg.id, + 'secondary_uom_ids': [ + (0, 0, { + 'name': 'unit-700', + 'uom_id': cls.product_uom_unit.id, + 'factor': 0.7, + })], + }) + cls.secondary_unit = cls.env['product.secondary.unit'].search([ + ('product_tmpl_id', '=', cls.product.product_tmpl_id.id), + ]) + cls.product.purchase_secondary_uom_id = cls.secondary_unit.id + cls.partner = cls.env['res.partner'].create({ + 'name': 'test - partner', + 'supplier': True, + }) + po = cls.env['purchase.order'].new({ + 'partner_id': cls.partner.id, + 'company_id': cls.env.user.company_id.id, + 'order_line': [(0, 0, { + 'name': cls.product.name, + 'product_id': cls.product.id, + 'product_qty': 1, + 'product_uom': cls.product.uom_id.id, + 'price_unit': 1000.00, + 'date_planned': fields.Datetime.now(), + })], + }) + po.onchange_partner_id() + cls.order = cls.env['purchase.order'].create( + po._convert_to_write(po._cache)) + + def test_onchange_secondary_uom(self): + self.order.order_line.write({ + 'secondary_uom_id': self.secondary_unit.id, + 'secondary_uom_qty': 5, + }) + self.order.order_line._onchange_secondary_uom() + self.assertEqual( + self.order.order_line.product_qty, 3.5) + + def test_onchange_product_qty_purchase_order_secondary_unit(self): + self.order.order_line.update({ + 'secondary_uom_id': self.secondary_unit.id, + 'product_qty': 3.5, + }) + self.order.order_line.\ + _onchange_product_qty_purchase_order_secondary_unit() + self.assertEqual( + self.order.order_line.secondary_uom_qty, 5.0) + + def test_default_secondary_unit(self): + self.order.order_line.\ + _onchange_product_id_purchase_order_secondary_unit() + self.assertEqual( + self.order.order_line.secondary_uom_id, self.secondary_unit) + + def test_onchange_order_product_uom(self): + self.order.order_line.update({ + 'secondary_uom_id': self.secondary_unit.id, + 'product_uom': self.product_uom_gram.id, + 'product_qty': 3500.00, + }) + self.order.order_line.\ + _onchange_product_uom_purchase_order_secondary_unit() + self.assertEqual( + self.order.order_line.secondary_uom_qty, 5.0) diff --git a/purchase_order_secondary_unit/views/product_views.xml b/purchase_order_secondary_unit/views/product_views.xml new file mode 100755 index 00000000000..552fd225f6a --- /dev/null +++ b/purchase_order_secondary_unit/views/product_views.xml @@ -0,0 +1,20 @@ + + + + + + Product template Secondary Unit + product.template + + + + + + + + + + diff --git a/purchase_order_secondary_unit/views/purchase_order_views.xml b/purchase_order_secondary_unit/views/purchase_order_views.xml new file mode 100755 index 00000000000..d13ae94e257 --- /dev/null +++ b/purchase_order_secondary_unit/views/purchase_order_views.xml @@ -0,0 +1,29 @@ + + + + + + Purchase Order Secondary Unit + purchase.order + + + + + + + + + + + + + + + From 147cd9b10da702fbe5ae78363b951ee885dbd6ef Mon Sep 17 00:00:00 2001 From: Nikul-Chaudhary Date: Sun, 27 Jan 2019 18:27:19 +0530 Subject: [PATCH 02/49] [MIG] purchase_order_secondary_unit v11 to v12 --- purchase_order_secondary_unit/README.rst | 11 ++++---- purchase_order_secondary_unit/__manifest__.py | 2 +- purchase_order_secondary_unit/i18n/es.po | 8 +++--- .../i18n/purchase_order_secondary_unit.pot | 10 +++---- .../readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 9 ++++--- .../test_purchase_order_secondary_unit.py | 27 +++++++++++++------ .../views/product_views.xml | 2 +- .../views/purchase_order_views.xml | 2 +- 9 files changed, 43 insertions(+), 29 deletions(-) diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index d6687078e86..b99a39656ed 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -14,13 +14,13 @@ Purchase Order 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%2Fpurchase--workflow-lightgray.png?logo=github - :target: https://github.com/OCA/purchase-workflow/tree/11.0/purchase_order_secondary_unit + :target: https://github.com/OCA/purchase-workflow/tree/12.0/purchase_order_secondary_unit :alt: OCA/purchase-workflow .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/purchase-workflow-11-0/purchase-workflow-11-0-purchase_order_secondary_unit + :target: https://translation.odoo-community.org/projects/purchase-workflow-12-0/purchase-workflow-12-0-purchase_order_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/142/11.0 + :target: https://runbot.odoo-community.org/runbot/142/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -50,7 +50,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. @@ -66,6 +66,7 @@ Contributors ~~~~~~~~~~~~ * Sergio Teruel +* Nikul Chaudhary Maintainers ~~~~~~~~~~~ @@ -80,6 +81,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/purchase-workflow `_ project on GitHub. +This module is part of the `OCA/purchase-workflow `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index 45c6dd339bb..19817b87c68 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { 'name': 'Purchase Order Secondary Unit', 'summary': 'Purchase product in a secondary unit', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'development_status': 'Beta', 'category': 'Purchase', 'website': 'https://github.com/OCA/purchase-workflow', diff --git a/purchase_order_secondary_unit/i18n/es.po b/purchase_order_secondary_unit/i18n/es.po index 7fd98c49971..fee3bc31acd 100644 --- a/purchase_order_secondary_unit/i18n/es.po +++ b/purchase_order_secondary_unit/i18n/es.po @@ -18,8 +18,8 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product_purchase_secondary_uom_id -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template_purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product__purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template__purchase_secondary_uom_id msgid "Default unit purchase" msgstr "" @@ -34,11 +34,11 @@ msgid "Purchase Order Line" msgstr "Línea pedido de compra" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_qty +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "Cdad. secundaria" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_id msgid "Secondary uom" msgstr "UdM Secundaría" diff --git a/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot index f911f132928..c475356d6f4 100644 --- a/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot +++ b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -14,8 +14,8 @@ msgstr "" "Plural-Forms: \n" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product_purchase_secondary_uom_id -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template_purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product__purchase_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template__purchase_secondary_uom_id msgid "Default unit purchase" msgstr "" @@ -30,12 +30,12 @@ msgid "Purchase Order Line" msgstr "" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_qty +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "" #. module: purchase_order_secondary_unit -#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line_secondary_uom_id +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_id msgid "Secondary uom" msgstr "" diff --git a/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst b/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst index f24a0b0dc74..cbf75168438 100644 --- a/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst +++ b/purchase_order_secondary_unit/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Sergio Teruel +* Nikul Chaudhary diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index ae4bd72d48c..3dc8439d705 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -3,7 +3,7 @@ - + Purchase Order Secondary Unit -
-

Purchase Order Secondary Unit

+
+ + +Odoo Community Association + +
+

Purchase Order Secondary Unit

-

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category.

Table of contents

@@ -386,7 +391,7 @@

Purchase Order Secondary Unit

-

Usage

+

Usage

To use this module you need to:

  1. Go to a Product > General Information tab.
  2. @@ -398,7 +403,7 @@

    Usage

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -406,15 +411,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Tecnativa
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -440,5 +445,6 @@

Maintainers

+
From 25ab52c1ad9a6bf573d8083163e1c1f4ac94dbf9 Mon Sep 17 00:00:00 2001 From: yostashiro Date: Sun, 11 Jan 2026 12:42:37 +0000 Subject: [PATCH 39/49] [IMP] purchase_order_secondary_unit: add vendor pricelist support and report config - Extend product.supplierinfo and purchase.order.line to support secondary unit pricing - Update purchase order/quotation reports to show secondary unit prices according to the configuration --- purchase_order_secondary_unit/README.rst | 53 ++++++++--- purchase_order_secondary_unit/__manifest__.py | 4 +- .../migrations/18.0.1.1.0/pre-migrate.py | 17 ++++ .../models/__init__.py | 1 + .../models/product_supplierinfo.py | 42 ++++++++ .../models/purchase_order.py | 31 ++++++ .../readme/CONFIGURE.md | 2 + .../readme/CONTRIBUTORS.md | 2 + .../readme/DESCRIPTION.md | 6 ++ .../readme/ROADMAP.md | 3 + purchase_order_secondary_unit/readme/USAGE.md | 9 ++ .../reports/purchase_order_templates.xml | 52 +++++++++- .../reports/purchase_quotation_templates.xml | 47 ++++++++- .../static/description/index.html | 72 +++++++++----- .../tests/__init__.py | 2 + purchase_order_secondary_unit/tests/common.py | 33 +++++++ ...est_product_supplierinfo_secondary_unit.py | 76 +++++++++++++++ .../test_purchase_order_secondary_unit.py | 72 +++++++++----- .../views/product_supplierinfo_views.xml | 51 ++++++++++ .../views/purchase_order_portal_templates.xml | 95 +++++++++++++++++++ .../views/purchase_order_views.xml | 10 ++ 21 files changed, 618 insertions(+), 62 deletions(-) create mode 100644 purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py create mode 100644 purchase_order_secondary_unit/models/product_supplierinfo.py create mode 100644 purchase_order_secondary_unit/readme/CONFIGURE.md create mode 100644 purchase_order_secondary_unit/readme/ROADMAP.md create mode 100644 purchase_order_secondary_unit/tests/common.py create mode 100644 purchase_order_secondary_unit/tests/test_product_supplierinfo_secondary_unit.py create mode 100644 purchase_order_secondary_unit/views/product_supplierinfo_views.xml create mode 100644 purchase_order_secondary_unit/views/purchase_order_portal_templates.xml diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index bf295f67a03..ada37484a90 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ============================= Purchase Order Secondary Unit ============================= @@ -17,7 +13,7 @@ Purchase Order Secondary Unit .. |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/license-AGPL--3-blue.png +.. |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%2Fpurchase--workflow-lightgray.png?logo=github @@ -35,11 +31,25 @@ Purchase Order Secondary Unit This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category. +Users can enter quantities and prices in secondary units on purchase +order lines. Vendor pricelist records are also extended to support +secondary unit pricing. + +Purchase reports and the Purchase Order portal are adjusted to display +quantities and prices in secondary units based on company configuration. + **Table of contents** .. contents:: :local: +Configuration +============= + +For configuration of displaying secondary unit information in purchase +reports and the Purchase Order portal, see the guidelines provided in +product_secondary_unit. + Usage ===== @@ -52,6 +62,24 @@ To use this module you need to: 5. Change secondary qty and secondary uom in line, and quantity (product_qty) will be changed (according to the conversion factor). +**Vendor Pricelist Integration** + +- When adding a vendor to a product's pricelist (via *Purchase tab > + Vendors*), the secondary unit of measure is automatically defaulted + from the product variant's purchase secondary UOM, or from the + product template if not set on the variant. +- When a new vendor pricelist record is created from purchase order + confirmation, the secondary UOM from the purchase order line is + automatically stored in the vendor pricelist entry. + +Known issues / Roadmap +====================== + +Updating existing vendor pricelist records from purchase order +confirmation does not currently support secondary UOM or secondary UOM +pricing. This is not included in the current scope and may be considered +in future improvements. + Bug Tracker =========== @@ -73,14 +101,17 @@ Authors Contributors ------------ -- `Tecnativa `__: +- `Tecnativa `__: + + - Sergio Teruel + - Ernesto Tejeda - - Sergio Teruel - - Ernesto Tejeda +- Nikul Chaudhary +- Pimolnat Suntian +- Miguel Ángel Gómez +- `Quartile `__: -- Nikul Chaudhary -- Pimolnat Suntian -- Miguel Ángel Gómez + - Yoshi Tashiro Maintainers ----------- diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index c7fd5dbb492..3dcc7386cf2 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Purchase Order Secondary Unit", "summary": "Purchase product in a secondary unit", - "version": "18.0.1.0.1", + "version": "18.0.1.1.0", "development_status": "Beta", "category": "Purchase", "website": "https://github.com/OCA/purchase-workflow", @@ -15,6 +15,8 @@ "depends": ["purchase", "product_secondary_unit"], "data": [ "views/product_views.xml", + "views/product_supplierinfo_views.xml", + "views/purchase_order_portal_templates.xml", "views/purchase_order_views.xml", "reports/purchase_order_templates.xml", "reports/purchase_quotation_templates.xml", diff --git a/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py b/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py new file mode 100644 index 00000000000..cb6cf693891 --- /dev/null +++ b/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py @@ -0,0 +1,17 @@ +# Copyright 2026 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tools.sql import column_exists + + +def migrate(cr, version): + if not column_exists(cr, "purchase_order_line", "secondary_uom_price"): + cr.execute(""" + ALTER TABLE purchase_order_line + ADD COLUMN secondary_uom_price double precision; + + UPDATE purchase_order_line pol + SET secondary_uom_price = pol.price_unit * su.factor + FROM product_secondary_unit su + WHERE su.id = pol.secondary_uom_id; + """) diff --git a/purchase_order_secondary_unit/models/__init__.py b/purchase_order_secondary_unit/models/__init__.py index a90631ae040..f1f600bd030 100644 --- a/purchase_order_secondary_unit/models/__init__.py +++ b/purchase_order_secondary_unit/models/__init__.py @@ -1,4 +1,5 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import product_product +from . import product_supplierinfo from . import product_template from . import purchase_order diff --git a/purchase_order_secondary_unit/models/product_supplierinfo.py b/purchase_order_secondary_unit/models/product_supplierinfo.py new file mode 100644 index 00000000000..e5c3ad7e781 --- /dev/null +++ b/purchase_order_secondary_unit/models/product_supplierinfo.py @@ -0,0 +1,42 @@ +# Copyright 2026 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ProductSupplierinfo(models.Model): + _inherit = "product.supplierinfo" + + secondary_uom_id = fields.Many2one( + comodel_name="product.secondary.unit", + string="Secondary Unit", + domain="[('product_tmpl_id', '=', product_tmpl_id)]", + ) + secondary_uom_price = fields.Float( + string="Secondary Price", + digits="Product Price", + compute="_compute_secondary_uom_price", + inverse="_inverse_secondary_uom_price", + store=True, + ) + + @api.depends("price", "secondary_uom_id", "secondary_uom_id.factor") + def _compute_secondary_uom_price(self): + for rec in self: + if rec.secondary_uom_id: + rec.secondary_uom_price = rec.price * rec.secondary_uom_id.factor + else: + rec.secondary_uom_price = 0.0 + + @api.onchange("secondary_uom_price") + def _inverse_secondary_uom_price(self): + for rec in self: + if rec.secondary_uom_id: + rec.price = rec.secondary_uom_price / rec.secondary_uom_id.factor + + @api.onchange("product_tmpl_id", "product_id") + def _onchange_product_id_secondary_uom(self): + self.secondary_uom_id = ( + self.product_id.purchase_secondary_uom_id + or self.product_tmpl_id.purchase_secondary_uom_id + ) diff --git a/purchase_order_secondary_unit/models/purchase_order.py b/purchase_order_secondary_unit/models/purchase_order.py index ada6a343b46..58bb8bd9ab4 100644 --- a/purchase_order_secondary_unit/models/purchase_order.py +++ b/purchase_order_secondary_unit/models/purchase_order.py @@ -3,6 +3,15 @@ from odoo import api, fields, models +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + def _prepare_supplier_info(self, partner, line, price, currency): + vals = super()._prepare_supplier_info(partner, line, price, currency) + vals["secondary_uom_id"] = line.secondary_uom_id.id + return vals + + class PurchaseOrderLine(models.Model): _inherit = ["purchase.order.line", "product.secondary.unit.mixin"] _name = "purchase.order.line" @@ -25,12 +34,34 @@ class PurchaseOrderLine(models.Model): product_packaging_id = fields.Many2one( compute="_compute_product_packaging_id", store=True, precompute=True ) + secondary_uom_price = fields.Float( + string="Secondary Price", + digits="Product Price", + aggregator="avg", + compute="_compute_secondary_uom_price", + inverse="_inverse_secondary_uom_price", + store=True, + ) @api.depends("secondary_uom_qty", "secondary_uom_id") def _compute_product_qty(self): self._compute_helper_target_field_qty() return super()._compute_product_qty() + @api.depends("price_unit", "secondary_uom_id", "secondary_uom_id.factor") + def _compute_secondary_uom_price(self): + for rec in self: + if rec.secondary_uom_id: + rec.secondary_uom_price = rec.price_unit * rec.secondary_uom_id.factor + else: + rec.secondary_uom_price = 0.0 + + @api.onchange("secondary_uom_price") + def _inverse_secondary_uom_price(self): + for rec in self: + if rec.secondary_uom_id: + rec.price_unit = rec.secondary_uom_price / rec.secondary_uom_id.factor + @api.onchange("product_uom") def onchange_product_uom_for_secondary(self): self._onchange_helper_product_uom_for_secondary() diff --git a/purchase_order_secondary_unit/readme/CONFIGURE.md b/purchase_order_secondary_unit/readme/CONFIGURE.md new file mode 100644 index 00000000000..2ba195bf886 --- /dev/null +++ b/purchase_order_secondary_unit/readme/CONFIGURE.md @@ -0,0 +1,2 @@ +For configuration of displaying secondary unit information in purchase reports and +the Purchase Order portal, see the guidelines provided in product_secondary_unit. diff --git a/purchase_order_secondary_unit/readme/CONTRIBUTORS.md b/purchase_order_secondary_unit/readme/CONTRIBUTORS.md index 1d97b2c52aa..0eb9326cb63 100644 --- a/purchase_order_secondary_unit/readme/CONTRIBUTORS.md +++ b/purchase_order_secondary_unit/readme/CONTRIBUTORS.md @@ -4,3 +4,5 @@ - Nikul Chaudhary \<\> - Pimolnat Suntian \<\> - Miguel Ángel Gómez \<\> +- [Quartile](https://www.quartile.co): + - Yoshi Tashiro diff --git a/purchase_order_secondary_unit/readme/DESCRIPTION.md b/purchase_order_secondary_unit/readme/DESCRIPTION.md index f81706f581f..bade08f8ea0 100644 --- a/purchase_order_secondary_unit/readme/DESCRIPTION.md +++ b/purchase_order_secondary_unit/readme/DESCRIPTION.md @@ -1,2 +1,8 @@ This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category. + +Users can enter quantities and prices in secondary units on purchase order lines. Vendor +pricelist records are also extended to support secondary unit pricing. + +Purchase reports and the Purchase Order portal are adjusted to display quantities and prices +in secondary units based on company configuration. diff --git a/purchase_order_secondary_unit/readme/ROADMAP.md b/purchase_order_secondary_unit/readme/ROADMAP.md new file mode 100644 index 00000000000..03a36575c9e --- /dev/null +++ b/purchase_order_secondary_unit/readme/ROADMAP.md @@ -0,0 +1,3 @@ +Updating existing vendor pricelist records from purchase order confirmation does not +currently support secondary UOM or secondary UOM pricing. This is not included in the +current scope and may be considered in future improvements. diff --git a/purchase_order_secondary_unit/readme/USAGE.md b/purchase_order_secondary_unit/readme/USAGE.md index 3e7f0e0aed2..f87ccf9b3ae 100644 --- a/purchase_order_secondary_unit/readme/USAGE.md +++ b/purchase_order_secondary_unit/readme/USAGE.md @@ -6,3 +6,12 @@ To use this module you need to: 4. Go to *Purchase \> Quotation \> Create*. 5. Change secondary qty and secondary uom in line, and quantity (product_qty) will be changed (according to the conversion factor). + +**Vendor Pricelist Integration** + +- When adding a vendor to a product's pricelist (via *Purchase tab > Vendors*), the + secondary unit of measure is automatically defaulted from the product variant's + purchase secondary UOM, or from the product template if not set on the variant. +- When a new vendor pricelist record is created from purchase order confirmation, the + secondary UOM from the purchase order line is automatically stored in the vendor + pricelist entry. diff --git a/purchase_order_secondary_unit/reports/purchase_order_templates.xml b/purchase_order_secondary_unit/reports/purchase_order_templates.xml index b79d2fc3b3c..01b9b2340ec 100644 --- a/purchase_order_secondary_unit/reports/purchase_order_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_order_templates.xml @@ -6,16 +6,64 @@ > - + Second Qty - + + + + line.get_secondary_uom_display_mode() != 'secondary' + + + line.get_secondary_uom_display_mode() != 'secondary' + + + + + + + + + + + +
+ + ( + ) + +
+
+ + + line.get_secondary_uom_display_mode() != 'secondary' + + + + diff --git a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml index ef64f13d1a1..1dbae6d6855 100644 --- a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml @@ -4,18 +4,57 @@ id="report_purchasequotation_document" inherit_id="purchase.report_purchasequotation_document" > - + - + Second Qty - + - + + + + order_line.get_secondary_uom_display_mode() != 'secondary' + + + order_line.get_secondary_uom_display_mode() != 'secondary' + + + + + + + + + + + +
+ + ( + ) + +
+
diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index a4e876f5df9..1f7c874044f 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Purchase Order Secondary Unit -
+
+

Purchase Order Secondary Unit

- - -Odoo Community Association - -
-

Purchase Order Secondary Unit

-

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category.

+

Users can enter quantities and prices in secondary units on purchase +order lines. Vendor pricelist records are also extended to support +secondary unit pricing.

+

Purchase reports and the Purchase Order portal are adjusted to display +quantities and prices in secondary units based on company configuration.

Table of contents

+
+

Configuration

+

For configuration of displaying secondary unit information in purchase +reports and the Purchase Order portal, see the guidelines provided in +product_secondary_unit.

+
-

Usage

+

Usage

To use this module you need to:

  1. Go to a Product > General Information tab.
  2. @@ -401,9 +409,26 @@

    Usage

  3. Change secondary qty and secondary uom in line, and quantity (product_qty) will be changed (according to the conversion factor).
+

Vendor Pricelist Integration

+
    +
  • When adding a vendor to a product’s pricelist (via Purchase tab > +Vendors), the secondary unit of measure is automatically defaulted +from the product variant’s purchase secondary UOM, or from the +product template if not set on the variant.
  • +
  • When a new vendor pricelist record is created from purchase order +confirmation, the secondary UOM from the purchase order line is +automatically stored in the vendor pricelist entry.
  • +
+
+
+

Known issues / Roadmap

+

Updating existing vendor pricelist records from purchase order +confirmation does not currently support secondary UOM or secondary UOM +pricing. This is not included in the current scope and may be considered +in future improvements.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -411,15 +436,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Tecnativa
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -445,6 +474,5 @@

Maintainers

-
diff --git a/purchase_order_secondary_unit/tests/__init__.py b/purchase_order_secondary_unit/tests/__init__.py index 6df95cebd79..cee0507553b 100644 --- a/purchase_order_secondary_unit/tests/__init__.py +++ b/purchase_order_secondary_unit/tests/__init__.py @@ -1,2 +1,4 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import common +from . import test_product_supplierinfo_secondary_unit from . import test_purchase_order_secondary_unit diff --git a/purchase_order_secondary_unit/tests/common.py b/purchase_order_secondary_unit/tests/common.py new file mode 100644 index 00000000000..d536d59b67e --- /dev/null +++ b/purchase_order_secondary_unit/tests/common.py @@ -0,0 +1,33 @@ +# Copyright 2018 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import Command + +from odoo.addons.base.tests.common import BaseCommon + + +class TestPurchaseSecondaryUnitCommon(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env.user.groups_id = [Command.link(cls.env.ref("uom.group_uom").id)] + cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm") + cls.product_uom_gram = cls.env.ref("uom.product_uom_gram") + cls.product_uom_unit = cls.env.ref("uom.product_uom_unit") + cls.product = cls.env["product.product"].create( + { + "name": "Test Product", + "uom_id": cls.product_uom_kg.id, + "uom_po_id": cls.product_uom_kg.id, + } + ) + cls.secondary_unit = cls.env["product.secondary.unit"].create( + { + "name": "unit-700", + "uom_id": cls.product_uom_unit.id, + "factor": 0.7, + "product_tmpl_id": cls.product.product_tmpl_id.id, + } + ) + cls.product.purchase_secondary_uom_id = cls.secondary_unit + cls.partner = cls.env["res.partner"].create({"name": "Test Vendor"}) diff --git a/purchase_order_secondary_unit/tests/test_product_supplierinfo_secondary_unit.py b/purchase_order_secondary_unit/tests/test_product_supplierinfo_secondary_unit.py new file mode 100644 index 00000000000..8fc9ef7921c --- /dev/null +++ b/purchase_order_secondary_unit/tests/test_product_supplierinfo_secondary_unit.py @@ -0,0 +1,76 @@ +# Copyright 2026 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests import Form, tagged + +from .common import TestPurchaseSecondaryUnitCommon + + +@tagged("-at_install", "post_install") +class TestProductSupplierinfoSecondaryUnit(TestPurchaseSecondaryUnitCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.supplierinfo = cls.env["product.supplierinfo"].create( + { + "partner_id": cls.partner.id, + "product_tmpl_id": cls.product.product_tmpl_id.id, + "price": 100.0, + } + ) + + def test_supplierinfo_secondary_uom_price_compute(self): + self.supplierinfo.secondary_uom_id = self.secondary_unit + # price = 100, factor = 0.7, secondary_uom_price = 70 + self.assertEqual(self.supplierinfo.secondary_uom_price, 70.0) + + def test_supplierinfo_secondary_uom_price_inverse(self): + self.supplierinfo.secondary_uom_id = self.secondary_unit + self.supplierinfo.secondary_uom_price = 140.0 + # secondary_uom_price = 140, factor = 0.7, price = 200 + self.assertEqual(self.supplierinfo.price, 200.0) + + def test_supplierinfo_no_secondary_unit(self): + self.supplierinfo.secondary_uom_id = False + self.assertEqual(self.supplierinfo.secondary_uom_price, 0.0) + + def test_supplierinfo_onchange_product_tmpl_id_secondary_uom(self): + self.product.product_tmpl_id.purchase_secondary_uom_id = self.secondary_unit + supplierinfo_form = Form( + self.env["product.supplierinfo"].with_context( + default_product_tmpl_id=self.product.product_tmpl_id.id + ) + ) + supplierinfo_form.partner_id = self.partner + self.assertEqual(supplierinfo_form.secondary_uom_id, self.secondary_unit) + + def test_supplierinfo_onchange_product_id_secondary_uom(self): + self.product.purchase_secondary_uom_id = self.secondary_unit + supplierinfo_form = Form( + self.env["product.supplierinfo"].with_context( + default_product_id=self.product.id, + default_product_tmpl_id=self.product.product_tmpl_id.id, + ) + ) + supplierinfo_form.partner_id = self.partner + self.assertEqual(supplierinfo_form.secondary_uom_id, self.secondary_unit) + + def test_supplierinfo_onchange_product_variant_takes_precedence(self): + secondary_unit_2 = self.env["product.secondary.unit"].create( + { + "name": "Pallet", + "uom_id": self.product_uom_unit.id, + "factor": 48.0, + "product_tmpl_id": self.product.product_tmpl_id.id, + } + ) + self.product.product_tmpl_id.purchase_secondary_uom_id = self.secondary_unit + self.product.purchase_secondary_uom_id = secondary_unit_2 + supplierinfo_form = Form( + self.env["product.supplierinfo"].with_context( + default_product_id=self.product.id, + default_product_tmpl_id=self.product.product_tmpl_id.id, + ) + ) + supplierinfo_form.partner_id = self.partner + self.assertEqual(supplierinfo_form.secondary_uom_id, secondary_unit_2) diff --git a/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py index 17c03215ff1..9ff99cfc2b8 100644 --- a/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py +++ b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py @@ -3,34 +3,14 @@ from odoo import Command, fields from odoo.tests import Form, tagged -from odoo.addons.base.tests.common import BaseCommon +from .common import TestPurchaseSecondaryUnitCommon @tagged("-at_install", "post_install") -class TestPurchaseOrderSecondaryUnit(BaseCommon): +class TestPurchaseOrderSecondaryUnit(TestPurchaseSecondaryUnitCommon): @classmethod def setUpClass(cls): super().setUpClass() - # Active multiple units of measure security group for user - cls.env.user.groups_id = [(4, cls.env.ref("uom.group_uom").id)] - cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm") - cls.product_uom_gram = cls.env.ref("uom.product_uom_gram") - cls.product_uom_unit = cls.env.ref("uom.product_uom_unit") - # Create a product - product_form = Form(cls.env["product.product"]) - product_form.name = "Test" - product_form.uom_id = cls.product_uom_kg - product_form.uom_po_id = cls.product_uom_kg - cls.product = product_form.save() - # Set a secondary unit on the template of the previously created product - with Form(cls.product.product_tmpl_id) as template_form: - with template_form.secondary_uom_ids.new() as secondary_uom_form: - secondary_uom_form.name = "unit-700" - secondary_uom_form.uom_id = cls.product_uom_unit - secondary_uom_form.factor = 0.7 - cls.secondary_unit = cls.product.product_tmpl_id.secondary_uom_ids - cls.product.purchase_secondary_uom_id = cls.secondary_unit.id - cls.partner = cls.env["res.partner"].create({"name": "test - partner"}) cls.purchase_order_obj = cls.env["purchase.order"] po_val = { "partner_id": cls.partner.id, @@ -76,3 +56,51 @@ def test_purchase_order_02(self): self.assertAlmostEqual(line_new.product_qty, 0.7, places=2) line_new.product_qty = 1 self.assertEqual(line_new.secondary_uom_qty, 1.43) + + def test_purchase_order_secondary_uom_price(self): + purchase_order = Form(self.order) + with purchase_order.order_line.edit(0) as line: + line.secondary_uom_id = self.secondary_unit + line.price_unit = 100.0 + # price_unit = 100, factor = 0.7, secondary_uom_price = 70 + self.assertEqual(line.secondary_uom_price, 70.0) + + def test_purchase_order_confirm_creates_supplierinfo_with_secondary_uom(self): + new_product = self.env["product.product"].create( + { + "name": "New Product", + "uom_id": self.product_uom_kg.id, + "uom_po_id": self.product_uom_kg.id, + } + ) + secondary_unit = self.env["product.secondary.unit"].create( + { + "name": "Case", + "uom_id": self.product_uom_unit.id, + "factor": 5.0, + "product_tmpl_id": new_product.product_tmpl_id.id, + } + ) + po = self.purchase_order_obj.create( + { + "partner_id": self.partner.id, + "order_line": [ + Command.create( + { + "product_id": new_product.id, + "product_qty": 10, + "product_uom": new_product.uom_id.id, + "price_unit": 50.0, + "secondary_uom_id": secondary_unit.id, + "secondary_uom_qty": 2.0, + } + ) + ], + } + ) + po.button_confirm() + # Check that supplierinfo was created with secondary_uom_id + supplierinfo = new_product.seller_ids + self.assertTrue(supplierinfo) + self.assertEqual(supplierinfo.partner_id, self.partner) + self.assertEqual(supplierinfo.secondary_uom_id, secondary_unit) diff --git a/purchase_order_secondary_unit/views/product_supplierinfo_views.xml b/purchase_order_secondary_unit/views/product_supplierinfo_views.xml new file mode 100644 index 00000000000..16bf9abb2b1 --- /dev/null +++ b/purchase_order_secondary_unit/views/product_supplierinfo_views.xml @@ -0,0 +1,51 @@ + + + + product.supplierinfo.form.view + product.supplierinfo + + + + + + + + + product.supplierinfo.list.view + product.supplierinfo + + + + + + + + + diff --git a/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml b/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml new file mode 100644 index 00000000000..8f2b5c910a6 --- /dev/null +++ b/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml @@ -0,0 +1,95 @@ + + + + + diff --git a/purchase_order_secondary_unit/views/purchase_order_views.xml b/purchase_order_secondary_unit/views/purchase_order_views.xml index 087e71d7ae7..a949d2543a3 100644 --- a/purchase_order_secondary_unit/views/purchase_order_views.xml +++ b/purchase_order_secondary_unit/views/purchase_order_views.xml @@ -27,6 +27,11 @@ readonly="state in ['purchase','done', 'cancel']" required="secondary_uom_qty != 0.0" /> + + From 62d2ec14eb8f535257c5d78ab10dd7c350cd5b00 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Tue, 20 Jan 2026 07:51:45 +0000 Subject: [PATCH 40/49] [IMP] purchase_order_secondary_unit: pass secondary_uom_id to account move line This commit propagates secondary_uom_id from purchase order lines to account move lines when the field exists on account.move.line. This is useful when account_move_secondary_unit is installed, and avoids the need for a glue module. --- purchase_order_secondary_unit/models/purchase_order.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/purchase_order_secondary_unit/models/purchase_order.py b/purchase_order_secondary_unit/models/purchase_order.py index 58bb8bd9ab4..37cece5901e 100644 --- a/purchase_order_secondary_unit/models/purchase_order.py +++ b/purchase_order_secondary_unit/models/purchase_order.py @@ -85,3 +85,12 @@ def onchange_product_id(self): if self.secondary_uom_id: self.secondary_uom_qty = 1.0 return res + + def _prepare_account_move_line(self, move=False): + # Set secondary UoM values only when account_move_secondary_unit is installed + # (i.e., the fields exist on account.move.line). + res = super()._prepare_account_move_line(move) + aml_fields = self.env["account.move.line"]._fields + if "secondary_uom_id" in aml_fields and self.secondary_uom_id: + res["secondary_uom_id"] = self.secondary_uom_id.id + return res From 59b9185f00c002b8a15e6f6103883c30f922c832 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 27 Jan 2026 16:33:07 +0000 Subject: [PATCH 41/49] [UPD] Update purchase_order_secondary_unit.pot --- .../i18n/purchase_order_secondary_unit.pot | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot index 205085b392c..64ee06c9225 100644 --- a/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot +++ b/purchase_order_secondary_unit/i18n/purchase_order_secondary_unit.pot @@ -14,6 +14,7 @@ msgstr "" "Plural-Forms: \n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -52,6 +53,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -67,7 +73,23 @@ msgstr "" msgid "Second unit" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" From 52ba7297546c1629f4267eabc4bb6a10bfac2902 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 27 Jan 2026 16:40:03 +0000 Subject: [PATCH 42/49] [BOT] post-merge updates --- purchase_order_secondary_unit/README.rst | 38 ++++++++++--------- purchase_order_secondary_unit/__manifest__.py | 2 +- .../static/description/index.html | 36 ++++++++++-------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index ada37484a90..d7e40bbc121 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ============================= Purchase Order Secondary Unit ============================= @@ -7,13 +11,13 @@ Purchase Order Secondary Unit !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:0a34065767385f244d70eae9989e494350699f097f52f0b84eaae226217042a1 + !! source digest: sha256:100a7bc4c1b9717279c990ce8ff8967021bd9c1a3f21858fa3fd19ceee8d815e !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |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 +.. |badge2| image:: https://img.shields.io/badge/license-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%2Fpurchase--workflow-lightgray.png?logo=github @@ -64,13 +68,13 @@ To use this module you need to: **Vendor Pricelist Integration** -- When adding a vendor to a product's pricelist (via *Purchase tab > - Vendors*), the secondary unit of measure is automatically defaulted - from the product variant's purchase secondary UOM, or from the - product template if not set on the variant. -- When a new vendor pricelist record is created from purchase order - confirmation, the secondary UOM from the purchase order line is - automatically stored in the vendor pricelist entry. +- When adding a vendor to a product's pricelist (via *Purchase tab > + Vendors*), the secondary unit of measure is automatically defaulted + from the product variant's purchase secondary UOM, or from the product + template if not set on the variant. +- When a new vendor pricelist record is created from purchase order + confirmation, the secondary UOM from the purchase order line is + automatically stored in the vendor pricelist entry. Known issues / Roadmap ====================== @@ -101,17 +105,17 @@ Authors Contributors ------------ -- `Tecnativa `__: +- `Tecnativa `__: - - Sergio Teruel - - Ernesto Tejeda + - Sergio Teruel + - Ernesto Tejeda -- Nikul Chaudhary -- Pimolnat Suntian -- Miguel Ángel Gómez -- `Quartile `__: +- Nikul Chaudhary +- Pimolnat Suntian +- Miguel Ángel Gómez +- `Quartile `__: - - Yoshi Tashiro + - Yoshi Tashiro Maintainers ----------- diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index 3dcc7386cf2..c5edeb2b391 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Purchase Order Secondary Unit", "summary": "Purchase product in a secondary unit", - "version": "18.0.1.1.0", + "version": "18.0.1.2.0", "development_status": "Beta", "category": "Purchase", "website": "https://github.com/OCA/purchase-workflow", diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index 1f7c874044f..1354618de3c 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -3,7 +3,7 @@ -Purchase Order Secondary Unit +README.rst -
-

Purchase Order Secondary Unit

+
+ + +Odoo Community Association + +
+

Purchase Order Secondary Unit

-

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category.

Users can enter quantities and prices in secondary units on purchase @@ -393,13 +398,13 @@

Purchase Order Secondary Unit

-

Configuration

+

Configuration

For configuration of displaying secondary unit information in purchase reports and the Purchase Order portal, see the guidelines provided in product_secondary_unit.

-

Usage

+

Usage

To use this module you need to:

  1. Go to a Product > General Information tab.
  2. @@ -413,22 +418,22 @@

    Usage

    • When adding a vendor to a product’s pricelist (via Purchase tab > Vendors), the secondary unit of measure is automatically defaulted -from the product variant’s purchase secondary UOM, or from the -product template if not set on the variant.
    • +from the product variant’s purchase secondary UOM, or from the product +template if not set on the variant.
    • When a new vendor pricelist record is created from purchase order confirmation, the secondary UOM from the purchase order line is automatically stored in the vendor pricelist entry.
-

Known issues / Roadmap

+

Known issues / Roadmap

Updating existing vendor pricelist records from purchase order confirmation does not currently support secondary UOM or secondary UOM pricing. This is not included in the current scope and may be considered in future improvements.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -436,15 +441,15 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Tecnativa
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -474,5 +479,6 @@

Maintainers

+
From ebc93649f2bdc250405e06d22d2ff39bf258d0d0 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 27 Jan 2026 16:40:13 +0000 Subject: [PATCH 43/49] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: purchase-workflow-18.0/purchase-workflow-18.0-purchase_order_secondary_unit Translate-URL: https://translation.odoo-community.org/projects/purchase-workflow-18-0/purchase-workflow-18-0-purchase_order_secondary_unit/ --- purchase_order_secondary_unit/i18n/de.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/es.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/fr.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/hr.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/it.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/ja.po | 22 +++++++++++++++++++++ purchase_order_secondary_unit/i18n/pt_BR.po | 22 +++++++++++++++++++++ 7 files changed, 154 insertions(+) diff --git a/purchase_order_secondary_unit/i18n/de.po b/purchase_order_secondary_unit/i18n/de.po index c4971114b22..6932ddfb904 100644 --- a/purchase_order_secondary_unit/i18n/de.po +++ b/purchase_order_secondary_unit/i18n/de.po @@ -17,6 +17,7 @@ msgstr "" "X-Generator: Weblate 4.3.2\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -55,6 +56,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -70,11 +76,27 @@ msgstr "Menge" msgid "Second unit" msgstr "2. ME" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "Menge (2. ME)" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" + #~ msgid "Product Template" #~ msgstr "Produktvorlage" diff --git a/purchase_order_secondary_unit/i18n/es.po b/purchase_order_secondary_unit/i18n/es.po index 5addc926016..e34145564c4 100644 --- a/purchase_order_secondary_unit/i18n/es.po +++ b/purchase_order_secondary_unit/i18n/es.po @@ -18,6 +18,7 @@ msgstr "" "X-Generator: Weblate 4.17\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -58,6 +59,11 @@ msgstr "Producto" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -73,10 +79,26 @@ msgstr "Cantidad" msgid "Second unit" msgstr "Unidad secundaria" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "Cdad. secundaria" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" + #~ msgid "Product Template" #~ msgstr "Plantilla de producto" diff --git a/purchase_order_secondary_unit/i18n/fr.po b/purchase_order_secondary_unit/i18n/fr.po index f4b25085296..4ff8e837d48 100644 --- a/purchase_order_secondary_unit/i18n/fr.po +++ b/purchase_order_secondary_unit/i18n/fr.po @@ -15,6 +15,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -53,6 +54,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -68,7 +74,23 @@ msgstr "" msgid "Second unit" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" diff --git a/purchase_order_secondary_unit/i18n/hr.po b/purchase_order_secondary_unit/i18n/hr.po index 73743a4767d..d9285f918f5 100644 --- a/purchase_order_secondary_unit/i18n/hr.po +++ b/purchase_order_secondary_unit/i18n/hr.po @@ -18,6 +18,7 @@ msgstr "" "X-Generator: Weblate 5.10.4\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -58,6 +59,11 @@ msgstr "Proizvod" msgid "Product Variant" msgstr "Varijatna proizvoda" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -73,7 +79,23 @@ msgstr "Količina" msgid "Second unit" msgstr "Alt. jedinica" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "Alt. količina" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" diff --git a/purchase_order_secondary_unit/i18n/it.po b/purchase_order_secondary_unit/i18n/it.po index cf1a76a1336..29aed488fe6 100644 --- a/purchase_order_secondary_unit/i18n/it.po +++ b/purchase_order_secondary_unit/i18n/it.po @@ -17,6 +17,7 @@ msgstr "" "X-Generator: Weblate 5.6.2\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -57,6 +58,11 @@ msgstr "Prodotto" msgid "Product Variant" msgstr "Variante prodotto" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -72,7 +78,23 @@ msgstr "Quantità" msgid "Second unit" msgstr "Unità secondaria" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "Q.tà secondaria" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" diff --git a/purchase_order_secondary_unit/i18n/ja.po b/purchase_order_secondary_unit/i18n/ja.po index c5a2dc114eb..06638707ac1 100644 --- a/purchase_order_secondary_unit/i18n/ja.po +++ b/purchase_order_secondary_unit/i18n/ja.po @@ -15,6 +15,7 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -53,6 +54,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -68,7 +74,23 @@ msgstr "" msgid "Second unit" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" diff --git a/purchase_order_secondary_unit/i18n/pt_BR.po b/purchase_order_secondary_unit/i18n/pt_BR.po index bb3817bd3be..61b282c87c2 100644 --- a/purchase_order_secondary_unit/i18n/pt_BR.po +++ b/purchase_order_secondary_unit/i18n/pt_BR.po @@ -15,6 +15,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n > 1;\n" #. module: purchase_order_secondary_unit +#: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" @@ -53,6 +54,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order +msgid "Purchase Order" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" @@ -68,7 +74,23 @@ msgstr "" msgid "Second unit" msgstr "" +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price +msgid "Secondary Price" +msgstr "" + #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id +msgid "Secondary Unit" +msgstr "" + +#. module: purchase_order_secondary_unit +#: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" From 42c84bb5289d11d1cc074e354829b08bfb5a12b0 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 28 Jan 2026 16:03:53 +0000 Subject: [PATCH 44/49] Translated using Weblate (Italian) Currently translated at 100.0% (15 of 15 strings) Translation: purchase-workflow-18.0/purchase-workflow-18.0-purchase_order_secondary_unit Translate-URL: https://translation.odoo-community.org/projects/purchase-workflow-18-0/purchase-workflow-18-0-purchase_order_secondary_unit/it/ --- purchase_order_secondary_unit/i18n/it.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/purchase_order_secondary_unit/i18n/it.po b/purchase_order_secondary_unit/i18n/it.po index 29aed488fe6..4d3a8dc145f 100644 --- a/purchase_order_secondary_unit/i18n/it.po +++ b/purchase_order_secondary_unit/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-11-14 14:06+0000\n" +"PO-Revision-Date: 2026-01-28 16:11+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -14,7 +14,7 @@ msgstr "" "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" +"X-Generator: Weblate 5.15.2\n" #. module: purchase_order_secondary_unit #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom @@ -61,7 +61,7 @@ msgstr "Variante prodotto" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order msgid "Purchase Order" -msgstr "" +msgstr "Ordine di acquisto" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line @@ -82,7 +82,7 @@ msgstr "Unità secondaria" #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price msgid "Secondary Price" -msgstr "" +msgstr "Prezzo secondario" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty @@ -92,9 +92,9 @@ msgstr "Q.tà secondaria" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id msgid "Secondary Unit" -msgstr "" +msgstr "Unità secondaria" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo msgid "Supplier Pricelist" -msgstr "" +msgstr "Listino prezzi fornitore" From c85bef690640a6fcb250e6ee6331a2efc2709880 Mon Sep 17 00:00:00 2001 From: yostashiro Date: Mon, 16 Feb 2026 13:32:34 +0000 Subject: [PATCH 45/49] [FIX] purchase_order_secondary_unit: revert report features requiring unmerged dependency Partially revert a1eea87f for purchase order and quotation report templates. The reverted portions rely on methods (hide_secondary_uom_column, get_secondary_uom_display_mode) introduced by OCA/product-attribute#2211, which is not yet merged. Without that dependency, the reports would crash when printing. The secondary quantity column is kept but the conditional visibility and display mode logic are removed until the dependency is available. --- .../reports/purchase_order_templates.xml | 52 +------------------ .../reports/purchase_quotation_templates.xml | 47 ++--------------- 2 files changed, 6 insertions(+), 93 deletions(-) diff --git a/purchase_order_secondary_unit/reports/purchase_order_templates.xml b/purchase_order_secondary_unit/reports/purchase_order_templates.xml index 01b9b2340ec..b79d2fc3b3c 100644 --- a/purchase_order_secondary_unit/reports/purchase_order_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_order_templates.xml @@ -6,64 +6,16 @@ > - + Second Qty - + - - - line.get_secondary_uom_display_mode() != 'secondary' - - - line.get_secondary_uom_display_mode() != 'secondary' - - - - - - - - - - - -
- - ( - ) - -
-
- - - line.get_secondary_uom_display_mode() != 'secondary' - - - - diff --git a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml index 1dbae6d6855..ef64f13d1a1 100644 --- a/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml +++ b/purchase_order_secondary_unit/reports/purchase_quotation_templates.xml @@ -4,57 +4,18 @@ id="report_purchasequotation_document" inherit_id="purchase.report_purchasequotation_document" > - + - + Second Qty - + - + - - - order_line.get_secondary_uom_display_mode() != 'secondary' - - - order_line.get_secondary_uom_display_mode() != 'secondary' - - - - - - - - - - - -
- - ( - ) - -
-
From 065b45f8185bd157cb8d1c897d75657aceb7c911 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 16 Feb 2026 14:01:11 +0000 Subject: [PATCH 46/49] [BOT] post-merge updates --- purchase_order_secondary_unit/README.rst | 2 +- purchase_order_secondary_unit/__manifest__.py | 2 +- purchase_order_secondary_unit/static/description/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index d7e40bbc121..217c79ee82a 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -11,7 +11,7 @@ Purchase Order Secondary Unit !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:100a7bc4c1b9717279c990ce8ff8967021bd9c1a3f21858fa3fd19ceee8d815e + !! source digest: sha256:2b71909b287e9e5c437aea172c4c165ed1bee7b3e981d1c44d99c8bfaae5740d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index c5edeb2b391..02f1fcad354 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Purchase Order Secondary Unit", "summary": "Purchase product in a secondary unit", - "version": "18.0.1.2.0", + "version": "18.0.1.2.1", "development_status": "Beta", "category": "Purchase", "website": "https://github.com/OCA/purchase-workflow", diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index 1354618de3c..df304240986 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -372,7 +372,7 @@

Purchase Order Secondary Unit

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:100a7bc4c1b9717279c990ce8ff8967021bd9c1a3f21858fa3fd19ceee8d815e +!! source digest: sha256:2b71909b287e9e5c437aea172c4c165ed1bee7b3e981d1c44d99c8bfaae5740d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy From 96b8acb9b1da0e77d7c751e870f9fc5d7df6d1a0 Mon Sep 17 00:00:00 2001 From: "Toshikimi Shigenobu (Quartile)" Date: Thu, 19 Feb 2026 06:50:43 +0000 Subject: [PATCH 47/49] Translated using Weblate (Japanese) Currently translated at 100.0% (15 of 15 strings) Translation: purchase-workflow-18.0/purchase-workflow-18.0-purchase_order_secondary_unit Translate-URL: https://translation.odoo-community.org/projects/purchase-workflow-18-0/purchase-workflow-18-0-purchase_order_secondary_unit/ja/ --- purchase_order_secondary_unit/i18n/ja.po | 34 +++++++++++++----------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/purchase_order_secondary_unit/i18n/ja.po b/purchase_order_secondary_unit/i18n/ja.po index 06638707ac1..ef1610641b4 100644 --- a/purchase_order_secondary_unit/i18n/ja.po +++ b/purchase_order_secondary_unit/i18n/ja.po @@ -6,91 +6,93 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2026-02-19 07:03+0000\n" +"Last-Translator: \"Toshikimi Shigenobu (Quartile)\" \n" "Language-Team: none\n" "Language: ja\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 5.15.2\n" #. module: purchase_order_secondary_unit #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.purchase_order_portal_content_secondary_uom #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchaseorder_document #: model_terms:ir.ui.view,arch_db:purchase_order_secondary_unit.report_purchasequotation_document msgid "Second Qty" -msgstr "" +msgstr "副数量" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_product__purchase_secondary_uom_id #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_template__purchase_secondary_uom_id msgid "Default secondary unit for purchases" -msgstr "" +msgstr "購買時のデフォルト副単位" #. module: purchase_order_secondary_unit #: model:ir.model.fields,help:purchase_order_secondary_unit.field_product_product__purchase_secondary_uom_id msgid "" "In order to set a value, please first add at least one record in 'Secondary " "Unit of Measure'" -msgstr "" +msgstr "値を設定するには、まず副単位に少なくとも1件のレコードを追加してください" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__product_packaging_id msgid "Packaging" -msgstr "" +msgstr "パッケージング" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__product_packaging_qty msgid "Packaging Quantity" -msgstr "" +msgstr "パッケージング数量" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_product_template msgid "Product" -msgstr "" +msgstr "プロダクト" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_product_product msgid "Product Variant" -msgstr "" +msgstr "プロダクトバリアント" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order msgid "Purchase Order" -msgstr "" +msgstr "購買オーダ" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_purchase_order_line msgid "Purchase Order Line" -msgstr "" +msgstr "購買オーダ明細" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__product_qty msgid "Quantity" -msgstr "" +msgstr "数量" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_id msgid "Second unit" -msgstr "" +msgstr "副単位" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_price #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_price msgid "Secondary Price" -msgstr "" +msgstr "副単価" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_purchase_order_line__secondary_uom_qty msgid "Secondary Qty" -msgstr "" +msgstr "副数量" #. module: purchase_order_secondary_unit #: model:ir.model.fields,field_description:purchase_order_secondary_unit.field_product_supplierinfo__secondary_uom_id msgid "Secondary Unit" -msgstr "" +msgstr "副単位" #. module: purchase_order_secondary_unit #: model:ir.model,name:purchase_order_secondary_unit.model_product_supplierinfo msgid "Supplier Pricelist" -msgstr "" +msgstr "仕入先価格表" From 6904aea0df9f9b115bd040b85182d98983368855 Mon Sep 17 00:00:00 2001 From: Jochen De Bie Date: Thu, 26 Feb 2026 12:10:16 +0100 Subject: [PATCH 48/49] [MIG] purchase_order_secondary_unit: Migration to 19.0 --- purchase_order_secondary_unit/README.rst | 40 ++++---- purchase_order_secondary_unit/__manifest__.py | 3 +- .../migrations/18.0.1.1.0/pre-migrate.py | 17 ---- .../models/purchase_order.py | 17 +--- .../static/description/index.html | 10 +- purchase_order_secondary_unit/tests/common.py | 3 +- .../test_purchase_order_secondary_unit.py | 7 +- .../views/product_views.xml | 4 +- .../views/purchase_order_portal_templates.xml | 95 ------------------- 9 files changed, 35 insertions(+), 161 deletions(-) delete mode 100644 purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py delete mode 100644 purchase_order_secondary_unit/views/purchase_order_portal_templates.xml diff --git a/purchase_order_secondary_unit/README.rst b/purchase_order_secondary_unit/README.rst index 217c79ee82a..0be4f0e69f5 100644 --- a/purchase_order_secondary_unit/README.rst +++ b/purchase_order_secondary_unit/README.rst @@ -21,13 +21,13 @@ Purchase Order 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%2Fpurchase--workflow-lightgray.png?logo=github - :target: https://github.com/OCA/purchase-workflow/tree/18.0/purchase_order_secondary_unit + :target: https://github.com/OCA/purchase-workflow/tree/19.0/purchase_order_secondary_unit :alt: OCA/purchase-workflow .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/purchase-workflow-18-0/purchase-workflow-18-0-purchase_order_secondary_unit + :target: https://translation.odoo-community.org/projects/purchase-workflow-19-0/purchase-workflow-19-0-purchase_order_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/purchase-workflow&target_branch=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/purchase-workflow&target_branch=19.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -68,13 +68,13 @@ To use this module you need to: **Vendor Pricelist Integration** -- When adding a vendor to a product's pricelist (via *Purchase tab > - Vendors*), the secondary unit of measure is automatically defaulted - from the product variant's purchase secondary UOM, or from the product - template if not set on the variant. -- When a new vendor pricelist record is created from purchase order - confirmation, the secondary UOM from the purchase order line is - automatically stored in the vendor pricelist entry. +- When adding a vendor to a product's pricelist (via *Purchase tab > + Vendors*), the secondary unit of measure is automatically defaulted + from the product variant's purchase secondary UOM, or from the + product template if not set on the variant. +- When a new vendor pricelist record is created from purchase order + confirmation, the secondary UOM from the purchase order line is + automatically stored in the vendor pricelist entry. Known issues / Roadmap ====================== @@ -90,7 +90,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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -105,17 +105,17 @@ Authors Contributors ------------ -- `Tecnativa `__: +- `Tecnativa `__: - - Sergio Teruel - - Ernesto Tejeda + - Sergio Teruel + - Ernesto Tejeda -- Nikul Chaudhary -- Pimolnat Suntian -- Miguel Ángel Gómez -- `Quartile `__: +- Nikul Chaudhary +- Pimolnat Suntian +- Miguel Ángel Gómez +- `Quartile `__: - - Yoshi Tashiro + - Yoshi Tashiro Maintainers ----------- @@ -130,6 +130,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/purchase-workflow `_ project on GitHub. +This module is part of the `OCA/purchase-workflow `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_order_secondary_unit/__manifest__.py b/purchase_order_secondary_unit/__manifest__.py index 02f1fcad354..51b653b96a8 100644 --- a/purchase_order_secondary_unit/__manifest__.py +++ b/purchase_order_secondary_unit/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Purchase Order Secondary Unit", "summary": "Purchase product in a secondary unit", - "version": "18.0.1.2.1", + "version": "19.0.1.0.0", "development_status": "Beta", "category": "Purchase", "website": "https://github.com/OCA/purchase-workflow", @@ -16,7 +16,6 @@ "data": [ "views/product_views.xml", "views/product_supplierinfo_views.xml", - "views/purchase_order_portal_templates.xml", "views/purchase_order_views.xml", "reports/purchase_order_templates.xml", "reports/purchase_quotation_templates.xml", diff --git a/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py b/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py deleted file mode 100644 index cb6cf693891..00000000000 --- a/purchase_order_secondary_unit/migrations/18.0.1.1.0/pre-migrate.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 Quartile (https://www.quartile.co) -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo.tools.sql import column_exists - - -def migrate(cr, version): - if not column_exists(cr, "purchase_order_line", "secondary_uom_price"): - cr.execute(""" - ALTER TABLE purchase_order_line - ADD COLUMN secondary_uom_price double precision; - - UPDATE purchase_order_line pol - SET secondary_uom_price = pol.price_unit * su.factor - FROM product_secondary_unit su - WHERE su.id = pol.secondary_uom_id; - """) diff --git a/purchase_order_secondary_unit/models/purchase_order.py b/purchase_order_secondary_unit/models/purchase_order.py index 37cece5901e..de99700e0d9 100644 --- a/purchase_order_secondary_unit/models/purchase_order.py +++ b/purchase_order_secondary_unit/models/purchase_order.py @@ -17,9 +17,9 @@ class PurchaseOrderLine(models.Model): _name = "purchase.order.line" _secondary_unit_fields = { "qty_field": "product_qty", - "uom_field": "product_uom", + "uom_field": "product_uom_id", } - _product_uom_field = "uom_po_id" + _product_uom_field = "uom_id" product_qty = fields.Float( store=True, @@ -28,12 +28,6 @@ class PurchaseOrderLine(models.Model): copy=True, precompute=True, ) - product_packaging_qty = fields.Float( - compute="_compute_product_packaging_qty", store=True, precompute=True - ) - product_packaging_id = fields.Many2one( - compute="_compute_product_packaging_id", store=True, precompute=True - ) secondary_uom_price = fields.Float( string="Secondary Price", digits="Product Price", @@ -43,10 +37,9 @@ class PurchaseOrderLine(models.Model): store=True, ) - @api.depends("secondary_uom_qty", "secondary_uom_id") + @api.depends("secondary_uom_qty", "secondary_uom_id", "product_uom_id") def _compute_product_qty(self): self._compute_helper_target_field_qty() - return super()._compute_product_qty() @api.depends("price_unit", "secondary_uom_id", "secondary_uom_id.factor") def _compute_secondary_uom_price(self): @@ -62,10 +55,6 @@ def _inverse_secondary_uom_price(self): if rec.secondary_uom_id: rec.price_unit = rec.secondary_uom_price / rec.secondary_uom_id.factor - @api.onchange("product_uom") - def onchange_product_uom_for_secondary(self): - self._onchange_helper_product_uom_for_secondary() - @api.onchange("product_id") def onchange_product_id(self): """If default purchases secondary unit set on product, put on secondary diff --git a/purchase_order_secondary_unit/static/description/index.html b/purchase_order_secondary_unit/static/description/index.html index df304240986..53e94b2052a 100644 --- a/purchase_order_secondary_unit/static/description/index.html +++ b/purchase_order_secondary_unit/static/description/index.html @@ -374,7 +374,7 @@

Purchase Order Secondary Unit

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:2b71909b287e9e5c437aea172c4c165ed1bee7b3e981d1c44d99c8bfaae5740d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/purchase-workflow Translate me on Weblate Try me on Runboat

This module extends the functionality of purchase orders to allow buy products in secondary unit of distinct category.

Users can enter quantities and prices in secondary units on purchase @@ -418,8 +418,8 @@

Usage

  • When adding a vendor to a product’s pricelist (via Purchase tab > Vendors), the secondary unit of measure is automatically defaulted -from the product variant’s purchase secondary UOM, or from the product -template if not set on the variant.
  • +from the product variant’s purchase secondary UOM, or from the +product template if not set on the variant.
  • When a new vendor pricelist record is created from purchase order confirmation, the secondary UOM from the purchase order line is automatically stored in the vendor pricelist entry.
  • @@ -437,7 +437,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 to smash it by providing a detailed and welcomed -feedback.

    +feedback.

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

@@ -474,7 +474,7 @@

Maintainers

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

+

This module is part of the OCA/purchase-workflow project on GitHub.

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

diff --git a/purchase_order_secondary_unit/tests/common.py b/purchase_order_secondary_unit/tests/common.py index d536d59b67e..2b4e2d76dc9 100644 --- a/purchase_order_secondary_unit/tests/common.py +++ b/purchase_order_secondary_unit/tests/common.py @@ -10,7 +10,7 @@ class TestPurchaseSecondaryUnitCommon(BaseCommon): @classmethod def setUpClass(cls): super().setUpClass() - cls.env.user.groups_id = [Command.link(cls.env.ref("uom.group_uom").id)] + cls.env.user.group_ids = [Command.link(cls.env.ref("uom.group_uom").id)] cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm") cls.product_uom_gram = cls.env.ref("uom.product_uom_gram") cls.product_uom_unit = cls.env.ref("uom.product_uom_unit") @@ -18,7 +18,6 @@ def setUpClass(cls): { "name": "Test Product", "uom_id": cls.product_uom_kg.id, - "uom_po_id": cls.product_uom_kg.id, } ) cls.secondary_unit = cls.env["product.secondary.unit"].create( diff --git a/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py index 9ff99cfc2b8..70b374b363d 100644 --- a/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py +++ b/purchase_order_secondary_unit/tests/test_purchase_order_secondary_unit.py @@ -21,7 +21,7 @@ def setUpClass(cls): "name": cls.product.name, "product_id": cls.product.id, "product_qty": 1, - "product_uom": cls.product.uom_id.id, + "product_uom_id": cls.product.uom_id.id, "price_unit": 1000.00, "date_planned": fields.Datetime.now(), }, @@ -42,7 +42,7 @@ def test_purchase_order_01(self): # Test onchange product uom line.secondary_uom_qty = 3500.0 self.assertEqual(line.product_qty, 2450.0) - line.product_uom = self.product_uom_gram + line.product_uom_id = self.product_uom_gram self.assertEqual(line.product_qty, 2450000.0) self.assertEqual(line.secondary_uom_qty, 3500.0) @@ -70,7 +70,6 @@ def test_purchase_order_confirm_creates_supplierinfo_with_secondary_uom(self): { "name": "New Product", "uom_id": self.product_uom_kg.id, - "uom_po_id": self.product_uom_kg.id, } ) secondary_unit = self.env["product.secondary.unit"].create( @@ -89,7 +88,7 @@ def test_purchase_order_confirm_creates_supplierinfo_with_secondary_uom(self): { "product_id": new_product.id, "product_qty": 10, - "product_uom": new_product.uom_id.id, + "product_uom_id": new_product.uom_id.id, "price_unit": 50.0, "secondary_uom_id": secondary_unit.id, "secondary_uom_qty": 2.0, diff --git a/purchase_order_secondary_unit/views/product_views.xml b/purchase_order_secondary_unit/views/product_views.xml index 039e3e17e0a..4b089dae646 100644 --- a/purchase_order_secondary_unit/views/product_views.xml +++ b/purchase_order_secondary_unit/views/product_views.xml @@ -7,14 +7,14 @@ product.template - + - + diff --git a/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml b/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml deleted file mode 100644 index 8f2b5c910a6..00000000000 --- a/purchase_order_secondary_unit/views/purchase_order_portal_templates.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - From d579c0513fde294bbff138763de5b4f500f58a93 Mon Sep 17 00:00:00 2001 From: Jochen De Bie Date: Thu, 26 Feb 2026 12:12:07 +0100 Subject: [PATCH 49/49] [DON'T MERGE] test-requirements.txt --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test-requirements.txt diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000000..266b739de11 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-product_secondary_unit @ git+https://github.com/OCA/product-attribute.git@refs/pull/2222/head#subdirectory=product_secondary_unit