Merge lp:~numerigraphe-team/stock-logistic-warehouse/7.0-add-stock-available into lp:stock-logistic-warehouse

Proposed by Lionel Sausin - Initiatives/Numérigraphe
Status: Rejected
Rejected by: Pedro Manuel Baeza
Proposed branch: lp:~numerigraphe-team/stock-logistic-warehouse/7.0-add-stock-available
Merge into: lp:stock-logistic-warehouse
Diff against target: 549 lines (+299/-129)
10 files modified
configurable_stock_level/product.py (+1/-1)
stock_available/__init__.py (+24/-0)
stock_available/__openerp__.py (+42/-0)
stock_available/product.py (+125/-0)
stock_available/product_view.xml (+15/-13)
stock_available/res_config.py (+34/-0)
stock_available/res_config_view.xml (+25/-0)
stock_available_immediately/__openerp__.py (+18/-13)
stock_available_immediately/product.py (+14/-101)
stock_inventory_existing_lines/stock.py (+1/-1)
To merge this branch: bzr merge lp:~numerigraphe-team/stock-logistic-warehouse/7.0-add-stock-available
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp Needs Resubmitting
Sébastien BEAU - http://www.akretion.com Pending
Guewen Baconnier @ Camptocamp Pending
Laurent Mignon (Acsone) Pending
Review via email: mp+220758@code.launchpad.net

Description of the change

Add a generic module to compute the stock quantity available to promise using several implementations and make stock_available_immediately the first configurable implementation.

stock_available_immediately is rewritten to compute "virtual - incoming" instead of "real - outgoing", which should be mostly the same except for rounding.
The field name "immediately_usable_qty" is unchanged for compatibility, but the field is now called "Available to promise" in the views and help texts (this wording seems more widespread).

By default function fields are not very modular (you need to redefine the whole field to override the method). stock_available takes care of this by making the function fields call the pool instead, so that stock_available_immediately and other future implementations need only override the function _product_available.

The new module also has a context trick that lets it return the value of the stock available to promise in the field "virtual stock". This lets future sub-modules change the behavior of modules that were written to use the virtual stock, to use the new value instead with minimal impact.

Module Co-authored by Loïc Bellier and your humble servant.

To post a comment you must log in.
36. By Numérigraphe

[IMP] Change category to 'warehouse'

37. By Numérigraphe

[MERGE] merge an unrelated fix regarding the UoM precision, to avoid conflicts

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

The source code management for this project has been moved to https://github.com/OCA/stock-logistics-warehouse

Could you resubmit this MP on the new site?

review: Needs Resubmitting
Revision history for this message
Lionel Sausin - Initiatives/Numérigraphe (ls-initiatives) wrote :

I'm migrating this to github, please mark "refused".

Unmerged revisions

37. By Numérigraphe

[MERGE] merge an unrelated fix regarding the UoM precision, to avoid conflicts

36. By Numérigraphe

[IMP] Change category to 'warehouse'

35. By Numérigraphe

[ADD] stock_available: generic module to compute the stock quantity available to promise using several implementations. Make stock_available_immediatly the first configurable implementation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configurable_stock_level/product.py'
2--- configurable_stock_level/product.py 2012-04-04 11:20:48 +0000
3+++ configurable_stock_level/product.py 2014-06-20 09:38:06 +0000
4@@ -48,7 +48,7 @@
5
6 _columns = {'configurable_stock_level': fields.function(_compute_configurable_level,
7 type='float',
8- digits_compute=dp.get_precision('Product UoM'),
9+ digits_compute=dp.get_precision('Product Unit of Measure'),
10 string='Custom level')}
11
12
13
14=== added directory 'stock_available'
15=== added file 'stock_available/__init__.py'
16--- stock_available/__init__.py 1970-01-01 00:00:00 +0000
17+++ stock_available/__init__.py 2014-06-20 09:38:06 +0000
18@@ -0,0 +1,24 @@
19+# -*- coding: utf-8 -*-
20+##############################################################################
21+#
22+# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved.
23+#
24+# This program is free software: you can redistribute it and/or modify
25+# it under the terms of the GNU Affero General Public License as
26+# published by the Free Software Foundation, either version 3 of the
27+# License, or (at your option) any later version.
28+#
29+# This program is distributed in the hope that it will be useful,
30+# but WITHOUT ANY WARRANTY; without even the implied warranty of
31+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32+# GNU Affero General Public License for more details.
33+#
34+# You should have received a copy of the GNU Affero General Public License
35+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36+#
37+##############################################################################
38+
39+from . import product
40+from . import res_config
41+
42+from .product import _product_available_fnct
43
44=== added file 'stock_available/__openerp__.py'
45--- stock_available/__openerp__.py 1970-01-01 00:00:00 +0000
46+++ stock_available/__openerp__.py 2014-06-20 09:38:06 +0000
47@@ -0,0 +1,42 @@
48+# -*- coding: utf-8 -*-
49+##############################################################################
50+#
51+# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved.
52+#
53+# This program is free software: you can redistribute it and/or modify
54+# it under the terms of the GNU Affero General Public License as
55+# published by the Free Software Foundation, either version 3 of the
56+# License, or (at your option) any later version.
57+#
58+# This program is distributed in the hope that it will be useful,
59+# but WITHOUT ANY WARRANTY; without even the implied warranty of
60+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
61+# GNU Affero General Public License for more details.
62+#
63+# You should have received a copy of the GNU Affero General Public License
64+# along with this program. If not, see <http://www.gnu.org/licenses/>.
65+#
66+##############################################################################
67+
68+{
69+ 'name': 'Stock available to promise',
70+ 'version': '2.0',
71+ 'author': u'Numérigraphe',
72+ 'category': 'Warehouse',
73+ 'depends': ['stock'],
74+ 'description': """
75+Stock available to promise
76+==========================
77+This module proposes several options to compute the quantity available to
78+promise for each product.
79+This quantity is based on the projected stock and, depending on the
80+configuration, it can account for various data such as sales quotations or
81+immediate production capacity.
82+This can be configured in the menu Settings > Configuration > Warehouse.
83+""",
84+ 'license': 'AGPL-3',
85+ 'data': [
86+ 'product_view.xml',
87+ 'res_config_view.xml',
88+ ]
89+}
90
91=== added file 'stock_available/product.py'
92--- stock_available/product.py 1970-01-01 00:00:00 +0000
93+++ stock_available/product.py 2014-06-20 09:38:06 +0000
94@@ -0,0 +1,125 @@
95+# -*- coding: utf-8 -*-
96+##############################################################################
97+#
98+# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved.
99+#
100+# This program is free software: you can redistribute it and/or modify
101+# it under the terms of the GNU Affero General Public License as
102+# published by the Free Software Foundation, either version 3 of the
103+# License, or (at your option) any later version.
104+#
105+# This program is distributed in the hope that it will be useful,
106+# but WITHOUT ANY WARRANTY; without even the implied warranty of
107+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108+# GNU Affero General Public License for more details.
109+#
110+# You should have received a copy of the GNU Affero General Public License
111+# along with this program. If not, see <http://www.gnu.org/licenses/>.
112+#
113+##############################################################################
114+
115+from openerp.osv import orm, fields
116+import openerp.addons.decimal_precision as dp
117+
118+
119+# Expose the method as a function, like when the fields are defined,
120+# and use the pool to call the method from the other modules too.
121+def _product_available_fnct(self, cr, uid, ids, field_names=None, arg=False,
122+ context=None):
123+ return self.pool['product.product']._product_available(
124+ cr, uid, ids, field_names=field_names, arg=arg, context=context)
125+
126+
127+class ProductProduct(orm.Model):
128+ """Add a field for the stock available to promise.
129+
130+ Useful implementations need to be installed through the Settings menu or by
131+ installing one of the modules stock_available_*
132+ """
133+ _inherit = 'product.product'
134+
135+ def __init__(self, pool, cr):
136+ """Use _product_available_fnct to compute all the quantities."""
137+ # Doing this lets us change the function and not redefine fields
138+ super(ProductProduct, self).__init__(pool, cr)
139+ for coldef in self._columns.values():
140+ if (isinstance(coldef, fields.function)
141+ and coldef._multi == 'qty_available'):
142+ coldef._fnct = _product_available_fnct
143+
144+ def _product_available(self, cr, uid, ids, field_names=None, arg=False,
145+ context=None):
146+ """Dummy field for the stock available to promise.
147+
148+ Must be overridden by another module that actually implement
149+ computations.
150+ The sub-modules MUST call super()._product_available BEFORE their own
151+ computations with
152+ context['virtual_is_immediately_usable_qty']=False
153+ AND call _update_virtual_available() AFTER their own computations
154+ with the context from the caller.
155+
156+ @param context: see _update_virtual_available()"""
157+ if context is None:
158+ context = {}
159+ if field_names is None:
160+ field_names = []
161+ else:
162+ # We don't want to change the caller's list
163+ field_names = list(field_names)
164+
165+ # Load virtual_available if it's not already asked for
166+ # We need it to compute immediately_usable_qty
167+ if ('virtual_available' not in field_names
168+ and 'immediately_usable_qty' in field_names):
169+ field_names.append('virtual_available')
170+ if context.get('virtual_is_immediately_usable', False):
171+ # _update_virtual_available will get/set these fields
172+ if 'virtual_available' not in field_names:
173+ field_names.append('virtual_available')
174+ if 'immediately_usable_qty' not in field_names:
175+ field_names.append('immediately_usable_qty')
176+
177+ # Compute the core quantities
178+ res = super(ProductProduct, self)._product_available(
179+ cr, uid, ids, field_names=field_names, arg=arg, context=context)
180+
181+ # By default, available to promise = forecasted quantity
182+ if ('immediately_usable_qty' in field_names):
183+ for stock_qty in res.itervalues():
184+ stock_qty['immediately_usable_qty'] = \
185+ stock_qty['virtual_available']
186+
187+ return self.pool['product.product']._update_virtual_available(
188+ cr, uid, res, context=context)
189+
190+ def _update_virtual_available(self, cr, uid, res, context=None):
191+ """Copy immediately_usable_qty to virtual_available if context asks
192+
193+ @param context: If the key virtual_is_immediately_usable is True,
194+ then the virtual stock is computed as the stock
195+ available to promise. This lets existing code base
196+ their computations on the new value with a minimum of
197+ change (i.e.: warn salesmen when the stock available
198+ for sale is insufficient to honor a quotation)"""
199+ if (context is None
200+ or not context.get('virtual_is_immediately_usable', False)):
201+ return res
202+ for stock_qty in res.itervalues():
203+ # _product_available makes sure both fields are loaded
204+ # We're changing the caller's state but it's not be a problem
205+ stock_qty['virtual_available'] = \
206+ stock_qty['immediately_usable_qty']
207+ return res
208+
209+ _columns = {
210+ 'immediately_usable_qty': fields.function(
211+ _product_available_fnct, multi='qty_available',
212+ type='float',
213+ digits_compute=dp.get_precision('Product Unit of Measure'),
214+ string='Available to promise',
215+ help="Stock for this Product that can be safely proposed "
216+ "for sale to Customers.\n"
217+ "The definition of this value can be configured to suit "
218+ "your needs"),
219+ }
220
221=== renamed file 'stock_available_immediately/product_view.xml' => 'stock_available/product_view.xml'
222--- stock_available_immediately/product_view.xml 2014-01-24 17:11:21 +0000
223+++ stock_available/product_view.xml 2014-06-20 09:38:06 +0000
224@@ -1,27 +1,19 @@
225 <?xml version="1.0" encoding="utf-8"?>
226-
227-<!--
228- stock available_immediately for OpenERP
229- Author Guewen Baconnier. Copyright Camptocamp SA
230- Copyright (C) 2011 Akretion Sébastien BEAU <sebastien.beau@akretion.com>
231- The licence is in the file __openerp__.py
232--->
233-
234 <openerp>
235 <data>
236- <record model="ir.ui.view" id="view_normal_stock_active_qty_form">
237- <field name="name">product.normal.stock.active.qty.form.inherit</field>
238+ <record model="ir.ui.view" id="view_stock_available_form">
239+ <field name="name">Stock available to promise (form)</field>
240 <field name="model">product.product</field>
241 <field name="inherit_id" ref="stock.view_normal_procurement_locations_form"/>
242 <field name="arch" type="xml">
243 <field name="virtual_available" position="after">
244 <newline/>
245 <field name="immediately_usable_qty" />
246- </field>
247+ </field>
248 </field>
249 </record>
250
251- <record model="ir.ui.view" id="product_product_tree_view">
252+ <record model="ir.ui.view" id="view_stock_available_tree">
253 <field name="name">product_immediately_usable.product_product_tree_view</field>
254 <field name="model">product.product</field>
255 <field name="inherit_id" ref="product.product_product_tree_view"/>
256@@ -30,12 +22,22 @@
257 <tree position="attributes">
258 <attribute name="colors">red:immediately_usable_qty&lt;0;blue:immediately_usable_qty&gt;=0 and state in ('draft', 'end', 'obsolete');black:immediately_usable_qty&gt;=0 and state not in ('draft', 'end', 'obsolete')</attribute>
259 </tree>
260- <field name="virtual_available" position="replace">
261+ <field name="virtual_available" position="after">
262 <field name="immediately_usable_qty" />
263 </field>
264 </data>
265 </field>
266 </record>
267
268+ <record model="ir.ui.view" id="view_stock_available_kanban">
269+ <field name="name">Product Kanban Stock</field>
270+ <field name="model">product.product</field>
271+ <field name="inherit_id" ref="stock.product_kanban_stock_view"/>
272+ <field name="arch" type="xml">
273+ <xpath expr="//field[@name='virtual_available']/.." position="replace">
274+ <li t-if="record.type.raw_value != 'service'">Available to promise: <field name="immediately_usable_qty"/> <field name="uom_id"/></li>
275+ </xpath>
276+ </field>
277+ </record>
278 </data>
279 </openerp>
280
281=== added file 'stock_available/res_config.py'
282--- stock_available/res_config.py 1970-01-01 00:00:00 +0000
283+++ stock_available/res_config.py 2014-06-20 09:38:06 +0000
284@@ -0,0 +1,34 @@
285+# -*- coding: utf-8 -*-
286+##############################################################################
287+#
288+# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved.
289+#
290+# This program is free software: you can redistribute it and/or modify
291+# it under the terms of the GNU General Public License as published by
292+# the Free Software Foundation, either version 3 of the License, or
293+# (at your option) any later version.
294+#
295+# This program is distributed in the hope that it will be useful,
296+# but WITHOUT ANY WARRANTY; without even the implied warranty of
297+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
298+# GNU General Public License for more details.
299+#
300+# You should have received a copy of the GNU General Public License
301+# along with this program. If not, see <http://www.gnu.org/licenses/>.
302+#
303+##############################################################################
304+
305+from openerp.osv import orm, fields
306+
307+
308+class StockConfig(orm.TransientModel):
309+ """Add options to easily install the submodules"""
310+ _inherit = 'stock.config.settings'
311+
312+ _columns = {
313+ 'module_stock_available_immediately': fields.boolean(
314+ 'Exclude incoming goods',
315+ help="This will subtract incoming quantities from the quantities"
316+ "available to promise.\n"
317+ "This installs the module stock_available_immediately."),
318+ }
319
320=== added file 'stock_available/res_config_view.xml'
321--- stock_available/res_config_view.xml 1970-01-01 00:00:00 +0000
322+++ stock_available/res_config_view.xml 2014-06-20 09:38:06 +0000
323@@ -0,0 +1,25 @@
324+<?xml version="1.0" encoding="utf-8"?>
325+<openerp>
326+ <data>
327+ <record id="view_stock_configuration" model="ir.ui.view">
328+ <field name="name">Stock settings: quantity available to promise</field>
329+ <field name="model">stock.config.settings</field>
330+ <field name="inherit_id" ref="stock.view_stock_config_settings" />
331+ <field name="arch" type="xml">
332+ <data>
333+ <xpath expr="//group[last()]" position="after">
334+ <group>
335+ <label for="id" string="Stock available to promise" />
336+ <div>
337+ <div>
338+ <field name="module_stock_available_immediately" class="oe_inline" />
339+ <label for="module_stock_available_immediately" />
340+ </div>
341+ </div>
342+ </group>
343+ </xpath>
344+ </data>
345+ </field>
346+ </record>
347+ </data>
348+</openerp>
349\ No newline at end of file
350
351=== modified file 'stock_available_immediately/__openerp__.py'
352--- stock_available_immediately/__openerp__.py 2014-01-24 17:11:21 +0000
353+++ stock_available_immediately/__openerp__.py 2014-06-20 09:38:06 +0000
354@@ -20,21 +20,26 @@
355 #
356 #
357
358-
359 {
360- "name": "Immediately Usable Stock Quantity",
361- "version": "1.0",
362- "depends": ["product", "stock", ],
363+ "name": "Ignore planned receptions in quantity available to promise",
364+ "version": "2.0",
365+ "depends": ["stock_available"],
366 "author": "Camptocamp",
367 "license": "AGPL-3",
368- "description": """
369-Compute the immediately usable stock.
370-Immediately usable is computed : Quantity on Hand - Outgoing Stock.
371+ "description": u"""
372+Ignore planned receptions in quantity available to promise
373+----------------------------------------------------------
374+
375+Normally the quantity available to promise is based on the virtual stock,
376+which includes both planned outgoing and incoming goods.
377+This module will subtract the planned receptions from the quantity available to
378+promise.
379+
380+Contributors
381+------------
382+ * Author: Guewen Baconnier (Camptocamp SA)
383+ * Sébastien BEAU (Akretion) <sebastien.beau@akretion.com>
384+ * Lionel Sausin (Numérigraphe) <ls@numerigraphe.com>
385 """,
386- "website": "http://tinyerp.com/module_account.html",
387- "category": "Generic Modules/Stock",
388- "data": ["product_view.xml",
389- ],
390- "active": False,
391- "installable": True
392+ "category": "Hidden",
393 }
394
395=== modified file 'stock_available_immediately/product.py'
396--- stock_available_immediately/product.py 2014-02-19 11:43:35 +0000
397+++ stock_available_immediately/product.py 2014-06-20 09:38:06 +0000
398@@ -19,124 +19,37 @@
399 #
400 ##############################################################################
401
402-from openerp.addons import decimal_precision as dp
403-
404-from openerp.osv import orm, fields
405+from openerp.osv import orm
406
407
408 class product_immediately_usable(orm.Model):
409- """
410- Inherit Product in order to add an "immediately usable quantity"
411- stock field
412- Immediately usable quantity is : real stock - outgoing qty
413- """
414+ """Subtract incoming qty from immediately_usable_qty
415+
416+ We don't need to override the function fields, the module stock_available
417+ takes of it for us."""
418 _inherit = 'product.product'
419
420 def _product_available(self, cr, uid, ids, field_names=None,
421 arg=False, context=None):
422- """
423- Get super() _product_available and compute immediately_usable_qty
424- """
425- # We need available and outgoing quantities to compute
426+ """Ignore the incoming goods in the quantity available to promise"""
427+ # We need available and incoming quantities to compute
428 # immediately usable quantity.
429 # When immediately_usable_qty is displayed but
430- # not qty_available and outgoing_qty,
431+ # not qty_available and incoming_qty,
432 # they are not computed in the super method so we cannot
433 # compute immediately_usable_qty.
434 # To avoid this issue, we add the 2 fields in
435 # field_names to compute them.
436 if 'immediately_usable_qty' in field_names:
437 field_names.append('qty_available')
438- field_names.append('outgoing_qty')
439+ field_names.append('incoming_qty')
440
441 res = super(product_immediately_usable, self)._product_available(
442 cr, uid, ids, field_names, arg, context)
443
444 if 'immediately_usable_qty' in field_names:
445- for product_id, stock_qty in res.iteritems():
446- res[product_id]['immediately_usable_qty'] = \
447- stock_qty['qty_available'] + stock_qty['outgoing_qty']
448-
449- return res
450-
451- _columns = {
452- 'qty_available': fields.function(
453- _product_available,
454- multi='qty_available',
455- type='float',
456- digits_compute=dp.get_precision('Product UoM'),
457- string='Quantity On Hand',
458- help="Current quantity of products.\n"
459- "In a context with a single Stock Location, this includes "
460- "goods stored at this Location, or any of its children.\n"
461- "In a context with a single Warehouse, this includes "
462- "goods stored in the Stock Location of this Warehouse, "
463- "or any "
464- "of its children.\n"
465- "In a context with a single Shop, this includes goods "
466- "stored in the Stock Location of the Warehouse of this Shop, "
467- "or any of its children.\n"
468- "Otherwise, this includes goods stored in any Stock Location "
469- "typed as 'internal'."),
470- 'virtual_available': fields.function(
471- _product_available,
472- multi='qty_available',
473- type='float',
474- digits_compute=dp.get_precision('Product UoM'),
475- string='Quantity Available',
476- help="Forecast quantity (computed as Quantity On Hand "
477- "- Outgoing + Incoming)\n"
478- "In a context with a single Stock Location, this includes "
479- "goods stored at this Location, or any of its children.\n"
480- "In a context with a single Warehouse, this includes "
481- "goods stored in the Stock Location of this Warehouse, "
482- "or any "
483- "of its children.\n"
484- "In a context with a single Shop, this includes goods "
485- "stored in the Stock Location of the Warehouse of this Shop, "
486- "or any of its children.\n"
487- "Otherwise, this includes goods stored in any Stock Location "
488- "typed as 'internal'."),
489- 'incoming_qty': fields.function(
490- _product_available,
491- multi='qty_available',
492- type='float',
493- digits_compute=dp.get_precision('Product UoM'),
494- string='Incoming',
495- help="Quantity of products that are planned to arrive.\n"
496- "In a context with a single Stock Location, this includes "
497- "goods arriving to this Location, or any of its children.\n"
498- "In a context with a single Warehouse, this includes "
499- "goods arriving to the Stock Location of this Warehouse, or "
500- "any of its children.\n"
501- "In a context with a single Shop, this includes goods "
502- "arriving to the Stock Location of the Warehouse of this "
503- "Shop, or any of its children.\n"
504- "Otherwise, this includes goods arriving to any Stock "
505- "Location typed as 'internal'."),
506- 'outgoing_qty': fields.function(
507- _product_available,
508- multi='qty_available',
509- type='float',
510- digits_compute=dp.get_precision('Product UoM'),
511- string='Outgoing',
512- help="Quantity of products that are planned to leave.\n"
513- "In a context with a single Stock Location, this includes "
514- "goods leaving from this Location, or any of its children.\n"
515- "In a context with a single Warehouse, this includes "
516- "goods leaving from the Stock Location of this Warehouse, or "
517- "any of its children.\n"
518- "In a context with a single Shop, this includes goods "
519- "leaving from the Stock Location of the Warehouse of this "
520- "Shop, or any of its children.\n"
521- "Otherwise, this includes goods leaving from any Stock "
522- "Location typed as 'internal'."),
523- 'immediately_usable_qty': fields.function(
524- _product_available,
525- digits_compute=dp.get_precision('Product UoM'),
526- type='float',
527- string='Immediately Usable',
528- multi='qty_available',
529- help="Quantity of products really available for sale." \
530- "Computed as: Quantity On Hand - Outgoing."),
531- }
532+ for stock_qty in res.itervalues():
533+ stock_qty['immediately_usable_qty'] -= \
534+ stock_qty['incoming_qty']
535+
536+ return self._update_virtual_available(cr, uid, res, context=context)
537
538=== modified file 'stock_inventory_existing_lines/stock.py'
539--- stock_inventory_existing_lines/stock.py 2012-03-07 12:56:37 +0000
540+++ stock_inventory_existing_lines/stock.py 2014-06-20 09:38:06 +0000
541@@ -81,7 +81,7 @@
542 'location_id': fields.many2one('stock.location', 'Location', required=True),
543 'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
544 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
545- 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM')),
546+ 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure')),
547 'company_id': fields.related('inventory_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, select=True, readonly=True),
548 'prod_lot_id': fields.many2one('stock.production.lot', 'Production Lot', domain="[('product_id','=',product_id)]"),
549 'state': fields.related('inventory_id', 'state', type='char', string='State',readonly=True),

Subscribers

People subscribed via source and target branches