Merge lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-hierarchical into lp:stock-logistic-warehouse

Proposed by Loïc Bellier - Numérigraphe
Status: Superseded
Proposed branch: lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-hierarchical
Merge into: lp:stock-logistic-warehouse
Prerequisite: lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-location
Diff against target: 1547 lines (+1371/-6)
23 files modified
stock_inventory_hierarchical/__init__.py (+28/-0)
stock_inventory_hierarchical/__openerp__.py (+46/-0)
stock_inventory_hierarchical/exceptions.py (+26/-0)
stock_inventory_hierarchical/hierarchical_inventory.py (+202/-0)
stock_inventory_hierarchical/hierarchical_inventory_demo.xml (+17/-0)
stock_inventory_hierarchical/hierarchical_inventory_view.xml (+78/-0)
stock_inventory_hierarchical/i18n/fr.po (+112/-0)
stock_inventory_hierarchical/test/hierarchical_inventory_test.yml (+96/-0)
stock_inventory_hierarchical_location/__init__.py (+22/-0)
stock_inventory_hierarchical_location/__openerp__.py (+48/-0)
stock_inventory_hierarchical_location/i18n/fr.po (+127/-0)
stock_inventory_hierarchical_location/inventory_hierarchical_location.py (+88/-0)
stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml (+28/-0)
stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml (+37/-0)
stock_inventory_hierarchical_location/tests/__init__.py (+39/-0)
stock_inventory_hierarchical_location/tests/fill_inventory_test.py (+118/-0)
stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml (+56/-0)
stock_inventory_hierarchical_location/wizard/__init__.py (+21/-0)
stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py (+89/-0)
stock_inventory_location/__openerp__.py (+3/-3)
stock_inventory_location/stock_inventory_location.py (+4/-3)
stock_inventory_location/tests/__init__.py (+39/-0)
stock_inventory_location/tests/stock_inventory_location_test.py (+47/-0)
To merge this branch: bzr merge lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-hierarchical
Reviewer Review Type Date Requested Status
Lionel Sausin - Initiatives/Numérigraphe (community) test pending Needs Resubmitting
Stock and Logistic Core Editors Pending
Review via email: mp+210631@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-20.

Description of the change

This proposal lets users compose inventories with sub-inventories in
a hierarchical tree.

This is useful in medium/large warehouses where
several teams must work in parallel to make inventories.

The module stock_inventory_hierarchical_location depends of stock_inventory_hierarchical and
stock_inventory_location (lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-location).

To post a comment you must log in.
Revision history for this message
Lionel Sausin - Initiatives/Numérigraphe (ls-initiatives) wrote :

Loic and I are improving this proposal WRT the 7.0 coding style and latest v8 updates.

37. By Numérigraphe

[MERGE] code & views cleanup and fixes

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

Loïc and I are still working on this proposal. Good progress was made: we re-aligned the features with v8 in mind, and improved the code style and the views.
Acsone joined in and we're still making tests, and I hope Loïc can make a new proposal in the coming days.

review: Needs Resubmitting (test pending)
38. By Loïc Bellier - Numérigraphe

[FIX]: Extract xpath inventory_ids from stock.inventory_view_form

39. By Loïc Bellier - Numérigraphe

[MERGE]: From dev branch

40. By Loïc Bellier - Numérigraphe

[MERGE]: merge from dev branch

41. By Loïc Bellier - Numérigraphe

[MERGE]: Fix some bugs. Add Merge Proposal of Laetitia Gangloff from ASCONE and thanks to her.

42. By Loïc Bellier - Numérigraphe

[MERGE]: Exception fault fixed by ACSONE.

43. By Numérigraphe

[MERGE] fixes from 7.0-inventory-location

44. By Numérigraphe

[MERGE] take subinventories into account when validating an exhaustive structured inventory

45. By Numérigraphe

[MERGE] no-change commit to close acsone's MP

46. By Laetitia Gangloff (Acsone)

[MERGE] raise the same exception as the standard so the other parts of the code can catch it properly

47. By Numérigraphe

[IMP] add button to open subinventories and progresbar on inventory header.

48. By Numérigraphe

[IMP] French translation

Unmerged revisions

48. By Numérigraphe

[IMP] French translation

47. By Numérigraphe

[IMP] add button to open subinventories and progresbar on inventory header.

46. By Laetitia Gangloff (Acsone)

[MERGE] raise the same exception as the standard so the other parts of the code can catch it properly

45. By Numérigraphe

[MERGE] no-change commit to close acsone's MP

44. By Numérigraphe

[MERGE] take subinventories into account when validating an exhaustive structured inventory

43. By Numérigraphe

[MERGE] fixes from 7.0-inventory-location

42. By Loïc Bellier - Numérigraphe

[MERGE]: Exception fault fixed by ACSONE.

41. By Loïc Bellier - Numérigraphe

[MERGE]: Fix some bugs. Add Merge Proposal of Laetitia Gangloff from ASCONE and thanks to her.

40. By Loïc Bellier - Numérigraphe

[MERGE]: merge from dev branch

39. By Loïc Bellier - Numérigraphe

[MERGE]: From dev branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'stock_inventory_hierarchical'
2=== added file 'stock_inventory_hierarchical/__init__.py'
3--- stock_inventory_hierarchical/__init__.py 1970-01-01 00:00:00 +0000
4+++ stock_inventory_hierarchical/__init__.py 2014-06-16 10:01:17 +0000
5@@ -0,0 +1,28 @@
6+# -*- coding: utf-8 -*-
7+##############################################################################
8+#
9+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
10+#
11+# This program is free software: you can redistribute it and/or modify
12+# it under the terms of the GNU General Public License as published by
13+# the Free Software Foundation, either version 3 of the License, or
14+# (at your option) any later version.
15+#
16+# This program is distributed in the hope that it will be useful,
17+# but WITHOUT ANY WARRANTY; without even the implied warranty of
18+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+# GNU General Public License for more details.
20+#
21+# You should have received a copy of the GNU General Public License
22+# along with this program. If not, see <http://www.gnu.org/licenses/>.
23+#
24+##############################################################################
25+
26+# This package-wide list keeps the names of the field that must be
27+# propagated from root inventories to their children.
28+# Add field names in the Model's definition.
29+PARENT_VALUES = []
30+
31+import hierarchical_inventory
32+# Bring the main exception into the package's scope for easier reuse
33+from .exceptions import HierarchicalInventoryException
34
35=== added file 'stock_inventory_hierarchical/__openerp__.py'
36--- stock_inventory_hierarchical/__openerp__.py 1970-01-01 00:00:00 +0000
37+++ stock_inventory_hierarchical/__openerp__.py 2014-06-16 10:01:17 +0000
38@@ -0,0 +1,46 @@
39+# -*- coding: utf-8 -*-
40+##############################################################################
41+#
42+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
43+#
44+# This program is free software: you can redistribute it and/or modify
45+# it under the terms of the GNU General Public License as published by
46+# the Free Software Foundation, either version 3 of the License, or
47+# (at your option) any later version.
48+#
49+# This program is distributed in the hope that it will be useful,
50+# but WITHOUT ANY WARRANTY; without even the implied warranty of
51+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52+# GNU General Public License for more details.
53+#
54+# You should have received a copy of the GNU General Public License
55+# along with this program. If not, see <http://www.gnu.org/licenses/>.
56+#
57+##############################################################################
58+
59+{
60+ "name": "Hierarchical Physical Inventory",
61+ "version": "1.1",
62+ "depends": ["stock"],
63+ "author": "Numérigraphe",
64+ "category": "Warehouse Management",
65+ "description": """
66+Hierarchical structure for Physical Inventories and sub-Inventories
67+===================================================================
68+
69+This module adds a parent-child relationship between Physical Inventories, to
70+help users manage complex inventories.
71+Using several inventories, you can distribute the counting to several persons
72+and still keep a clear overview of global Inventory's status.
73+
74+OpenERP will make sure the status of the Inventory and it's Sub-Inventories are
75+consistent.
76+""",
77+ "data": ["hierarchical_inventory_view.xml"],
78+ "test": ["test/hierarchical_inventory_test.yml"],
79+ "demo": ["hierarchical_inventory_demo.xml"],
80+ "images": [
81+ "inventory_form.png",
82+ "inventory_form_actions.png",
83+ ],
84+}
85
86=== added file 'stock_inventory_hierarchical/exceptions.py'
87--- stock_inventory_hierarchical/exceptions.py 1970-01-01 00:00:00 +0000
88+++ stock_inventory_hierarchical/exceptions.py 2014-06-16 10:01:17 +0000
89@@ -0,0 +1,26 @@
90+# -*- coding: utf-8 -*-
91+##############################################################################
92+#
93+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
94+#
95+# This program is free software: you can redistribute it and/or modify
96+# it under the terms of the GNU General Public License as published by
97+# the Free Software Foundation, either version 3 of the License, or
98+# (at your option) any later version.
99+#
100+# This program is distributed in the hope that it will be useful,
101+# but WITHOUT ANY WARRANTY; without even the implied warranty of
102+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
103+# GNU General Public License for more details.
104+#
105+# You should have received a copy of the GNU General Public License
106+# along with this program. If not, see <http://www.gnu.org/licenses/>.
107+#
108+##############################################################################
109+
110+from openerp.osv import orm
111+
112+
113+class HierarchicalInventoryException(orm.except_orm):
114+ """The operation is not possible for a hierarchical inventory"""
115+ pass
116
117=== added file 'stock_inventory_hierarchical/hierarchical_inventory.py'
118--- stock_inventory_hierarchical/hierarchical_inventory.py 1970-01-01 00:00:00 +0000
119+++ stock_inventory_hierarchical/hierarchical_inventory.py 2014-06-16 10:01:17 +0000
120@@ -0,0 +1,202 @@
121+# -*- coding: utf-8 -*-
122+##############################################################################
123+#
124+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
125+#
126+# This program is free software: you can redistribute it and/or modify
127+# it under the terms of the GNU General Public License as published by
128+# the Free Software Foundation, either version 3 of the License, or
129+# (at your option) any later version.
130+#
131+# This program is distributed in the hope that it will be useful,
132+# but WITHOUT ANY WARRANTY; without even the implied warranty of
133+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134+# GNU General Public License for more details.
135+#
136+# You should have received a copy of the GNU General Public License
137+# along with this program. If not, see <http://www.gnu.org/licenses/>.
138+#
139+##############################################################################
140+
141+from openerp.osv import orm, fields
142+from openerp.tools.translate import _
143+
144+from .exceptions import HierarchicalInventoryException
145+
146+# Add the date to the list of fields we must propagate to children inventories
147+from . import PARENT_VALUES
148+PARENT_VALUES.append('date')
149+
150+
151+class HierarchicalInventory(orm.Model):
152+ _inherit = 'stock.inventory'
153+
154+ _parent_store = True
155+ _parent_order = 'date, name'
156+ _order = 'parent_left'
157+
158+ def name_get(self, cr, uid, ids, context=None):
159+ """Show the parent inventory's name in the name of the children
160+
161+ :param dict context: the ``inventory_display`` key can be
162+ used to select the short version of the
163+ inventory name (without the direct parent),
164+ when set to ``'short'``. The default is
165+ the long version."""
166+ if context is None:
167+ context = {}
168+ if context.get('inventory_display') == 'short':
169+ # Short name context: just do the usual stuff
170+ return super(HierarchicalInventory, self).name_get(
171+ cr, uid, ids, context=context)
172+ if isinstance(ids, (list, tuple)) and not len(ids):
173+ return []
174+ if isinstance(ids, (long, int)):
175+ ids = [ids]
176+ reads = self.read(cr, uid, ids, ['name', 'parent_id'], context=context)
177+ res = []
178+ for record in reads:
179+ name = record['name']
180+ if record['parent_id']:
181+ name = record['parent_id'][1] + ' / ' + name
182+ res.append((record['id'], name))
183+ return res
184+
185+ def name_search(self, cr, uid, name='', args=None, operator='ilike',
186+ context=None, limit=100):
187+ """Enable search on value returned by name_get ("parent / child")"""
188+ if not args:
189+ args = []
190+ if not context:
191+ context = {}
192+ if name:
193+ # Make sure name_search is symmetric to name_get
194+ name = name.split(' / ')[-1]
195+ ids = self.search(cr, uid, [('name', operator, name)] + args,
196+ limit=limit, context=context)
197+ else:
198+ ids = self.search(cr, uid, args, limit=limit, context=context)
199+ return self.name_get(cr, uid, ids, context=context)
200+
201+ def _complete_name(self, cr, uid, ids, field_name, arg, context=None):
202+ """Function-field wrapper to get the complete name from name_get"""
203+ res = self.name_get(cr, uid, ids, context=context)
204+ return dict(res)
205+
206+ def _progress_rate(self, cr, uid, ids, field_name, arg, context=None):
207+ """Rate of (sub)inventories done/total"""
208+ rates = {}
209+ for current_id in ids:
210+ nb = self.search(
211+ cr, uid, [('parent_id', 'child_of', current_id)],
212+ context=context, count=True)
213+ if not nb:
214+ # No inventory, consider it's 0% done
215+ rates[current_id] = 0
216+ continue
217+ nb_done = self.search(
218+ cr, uid, [('parent_id', 'child_of', current_id),
219+ ('state', '=', 'done')],
220+ context=context, count=True)
221+ rates[current_id] = 100 * nb_done / nb
222+ return rates
223+
224+ _columns = {
225+ # name_get() only changes the default name of the record, not the
226+ # content of the field "name" so we add another field for that
227+ 'complete_name': fields.function(
228+ _complete_name, type="char",
229+ string='Complete reference'),
230+ 'parent_id': fields.many2one(
231+ 'stock.inventory', 'Parent', ondelete='cascade', readonly=True,
232+ states={'draft': [('readonly', False)]}),
233+ 'inventory_ids': fields.one2many(
234+ 'stock.inventory', 'parent_id', 'List of Sub-inventories',
235+ readonly=True, states={'draft': [('readonly', False)]}),
236+ 'parent_left': fields.integer('Parent Left', select=1),
237+ 'parent_right': fields.integer('Parent Right', select=1),
238+ 'progress_rate': fields.function(
239+ _progress_rate, string='Progress', type='float'),
240+ }
241+
242+ _constraints = [
243+ (orm.Model._check_recursion,
244+ 'Error: You can not create recursive inventories.',
245+ ['parent_id']),
246+ ]
247+
248+ def create(self, cr, uid, vals, context=None):
249+ """Copy selected values from parent to child"""
250+ if vals and vals.get('parent_id'):
251+ existing_fields = self.fields_get_keys(cr, uid, context=context)
252+ parent_values = self.read(cr, uid, [vals['parent_id']],
253+ PARENT_VALUES, context=context)
254+ vals = vals.copy()
255+ vals.update({field: parent_values[0][field]
256+ for field in PARENT_VALUES
257+ if field in existing_fields})
258+ return super(HierarchicalInventory, self).create(
259+ cr, uid, vals, context=context)
260+
261+ def write(self, cr, uid, ids, vals, context=None):
262+ """Copy selected values from parent to children"""
263+ if context is None:
264+ context = {}
265+
266+ values = super(HierarchicalInventory, self).write(
267+ cr, uid, ids, vals, context=context)
268+ if not vals or context.get('norecurse', False):
269+ return values
270+
271+ # filter the fields we want to propagate
272+ children_values = {
273+ field: vals[field] for field in PARENT_VALUES if field in vals
274+ }
275+ if not children_values:
276+ return values
277+
278+ if not isinstance(ids, list):
279+ ids = [ids]
280+ # The context disables recursion - children are already included
281+ return self.write(
282+ cr, uid, self.search(cr, uid, [('parent_id', 'child_of', ids)]),
283+ children_values, context=dict(context, norecurse=True))
284+
285+ def action_cancel_inventory(self, cr, uid, ids, context=None):
286+ """Cancel inventory only if all the parents are canceled"""
287+ inventories = self.browse(cr, uid, ids, context=context)
288+ for inventory in inventories:
289+ while inventory.parent_id:
290+ inventory = inventory.parent_id
291+ if inventory.state != 'cancel':
292+ raise HierarchicalInventoryException(
293+ _('Warning'),
294+ _('One of the parent Inventories is not canceled.'))
295+ return super(HierarchicalInventory,
296+ self).action_cancel_inventory(cr, uid, ids,
297+ context=context)
298+
299+ def action_confirm(self, cr, uid, ids, context=None):
300+ """Confirm inventory only if all the children are confirmed"""
301+ children_count = self.search(
302+ cr, uid, [('parent_id', 'child_of', ids),
303+ ('state', 'not in', ['confirm', 'done'])],
304+ context=context, count=True)
305+ if children_count > 1:
306+ raise HierarchicalInventoryException(
307+ _('Warning'),
308+ _('Some Sub-inventories are not confirmed.'))
309+ return super(HierarchicalInventory, self).action_confirm(
310+ cr, uid, ids, context=context)
311+
312+ def action_done(self, cr, uid, ids, context=None):
313+ """Perform validation only if all the children states are 'done'."""
314+ children_count = self.search(cr, uid, [('parent_id', 'child_of', ids),
315+ ('state', '!=', 'done')],
316+ context=context, count=True)
317+ if children_count > 1:
318+ raise HierarchicalInventoryException(
319+ _('Warning'),
320+ _('Some Sub-inventories are not validated.'))
321+ return super(HierarchicalInventory, self).action_done(
322+ cr, uid, ids, context=context)
323
324=== added file 'stock_inventory_hierarchical/hierarchical_inventory_demo.xml'
325--- stock_inventory_hierarchical/hierarchical_inventory_demo.xml 1970-01-01 00:00:00 +0000
326+++ stock_inventory_hierarchical/hierarchical_inventory_demo.xml 2014-06-16 10:01:17 +0000
327@@ -0,0 +1,17 @@
328+<?xml version="1.0" encoding="utf-8"?>
329+<openerp>
330+ <data noupdate="0">
331+ <!-- Example Inventory with Sub-Inventories. -->
332+ <record id="stock_inventory_parent0" model="stock.inventory">
333+ <field name="name">Main Inventory</field>
334+ </record>
335+ <record id="child_1_id" model="stock.inventory">
336+ <field name="name">Sub-Inventory 1</field>
337+ <field name="parent_id" ref="stock_inventory_parent0" />
338+ </record>
339+ <record id="child_2_id" model="stock.inventory">
340+ <field name="name">Sub-Inventory 2</field>
341+ <field name="parent_id" ref="stock_inventory_parent0" />
342+ </record>
343+ </data>
344+</openerp>
345
346=== added file 'stock_inventory_hierarchical/hierarchical_inventory_view.xml'
347--- stock_inventory_hierarchical/hierarchical_inventory_view.xml 1970-01-01 00:00:00 +0000
348+++ stock_inventory_hierarchical/hierarchical_inventory_view.xml 2014-06-16 10:01:17 +0000
349@@ -0,0 +1,78 @@
350+<?xml version="1.0" encoding="utf-8"?>
351+<openerp>
352+ <data>
353+ <!-- Add parent_id and number of Sub-inventories to form view -->
354+ <record model="ir.ui.view" id="stock_inventory_hierarchical_tree_view">
355+ <field name="name">hierarchical.inventory.tree</field>
356+ <field name="model">stock.inventory</field>
357+ <field name="inherit_id" ref="stock.view_inventory_tree" />
358+ <field name="field_parent">inventory_ids</field>
359+ <field name="arch" type="xml">
360+ <xpath expr="//field[@name='name']" position="replace">
361+ <field name="complete_name" string="Reference"/>
362+ </xpath>
363+ <xpath expr="//field[@name='state']" position="after">
364+ <field name="progress_rate" widget="progressbar" />
365+ </xpath>
366+ </field>
367+ </record>
368+
369+ <!-- Add the parent_id filter to search view -->
370+ <record model="ir.ui.view" id="view_inventory_subinventories_filter">
371+ <field name="name">hierarchical.inventory.filter</field>
372+ <field name="model">stock.inventory</field>
373+ <field name="inherit_id" ref="stock.view_inventory_filter" />
374+ <field name="arch" type="xml">
375+ <xpath expr="//field[@name='name']" position="before">
376+ <filter icon="terp-check" name="main_inventories" string="Main inventories" domain="[('parent_id', '=', False)]" help="Only select inventories that have no parents." />
377+ <separator orientation="vertical"/>
378+ </xpath>
379+ <xpath expr="//field[@name='date']" position="after">
380+ <field name="parent_id" />
381+ </xpath>
382+ </field>
383+ </record>
384+ <!-- Show main inventories by default -->
385+ <record id="stock.action_inventory_form" model="ir.actions.act_window">
386+ <field name="context">{'full':'1', 'search_default_main_inventories':1}</field>
387+ </record>
388+
389+ <record model="ir.ui.view" id="stock_inventory_hierarchical_form_view">
390+ <field name="name">hierarchical.inventory.form</field>
391+ <field name="model">stock.inventory</field>
392+ <field name="inherit_id" ref="stock.view_inventory_form" />
393+ <field name="arch" type="xml">
394+ <xpath expr="/form//field[@name='name']" position="after">
395+ <field name="parent_id"/>
396+ </xpath>
397+ <xpath expr="/form//field[@name='date']" position="attributes">
398+ <attribute name="attrs">{'readonly':[('parent_id', '!=', False)]}</attribute>
399+ </xpath>
400+ <xpath
401+ expr="//page[@string='General Information']"
402+ position="after">
403+ <page string="Sub-inventories">
404+ <field name="inventory_ids" nolabel="1" context="{'default_parent_id': active_id}">
405+ <tree>
406+ <field name="name" />
407+ <field name="state" />
408+ <field name="progress_rate" widget="progressbar" />
409+ </tree>
410+ </field>
411+ </page>
412+ </xpath>
413+ </field>
414+ </record>
415+
416+ <!-- Open the children of the current Inventory in a distinct list
417+ to let users work in a normal window instead of a popup -->
418+ <act_window id="action_view_sub_inventory"
419+ name="View Sub-inventories"
420+ res_model="stock.inventory"
421+ src_model="stock.inventory"
422+ view_mode="tree,form"
423+ view_type="form"
424+ domain="[('parent_id', 'child_of', active_id),('id', '!=', active_id)]"
425+ context="{'full':1, 'search_default_main_inventories':0}"/>
426+ </data>
427+</openerp>
428
429=== added directory 'stock_inventory_hierarchical/i18n'
430=== added file 'stock_inventory_hierarchical/i18n/fr.po'
431--- stock_inventory_hierarchical/i18n/fr.po 1970-01-01 00:00:00 +0000
432+++ stock_inventory_hierarchical/i18n/fr.po 2014-06-16 10:01:17 +0000
433@@ -0,0 +1,112 @@
434+# Translation of OpenERP Server.
435+# This file contains the translation of the following modules:
436+# * stock_inventory_hierarchical
437+#
438+msgid ""
439+msgstr ""
440+"Project-Id-Version: OpenERP Server 6.0.4\n"
441+"Report-Msgid-Bugs-To: support@openerp.com\n"
442+"POT-Creation-Date: 2013-09-25 13:43+0000\n"
443+"PO-Revision-Date: 2013-09-25 13:43+0000\n"
444+"Last-Translator: <>\n"
445+"Language-Team: \n"
446+"MIME-Version: 1.0\n"
447+"Content-Type: text/plain; charset=UTF-8\n"
448+"Content-Transfer-Encoding: \n"
449+"Plural-Forms: \n"
450+
451+#. module: stock_inventory_hierarchical
452+#: field:stock.inventory,complete_name:0
453+msgid "Complete reference"
454+msgstr "Réference complète"
455+
456+#. module: stock_inventory_hierarchical
457+#: field:stock.inventory,progress_rate:0
458+msgid "Done"
459+msgstr "Terminé"
460+
461+#. module: stock_inventory_hierarchical
462+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:108
463+#: constraint:stock.inventory:0
464+#, python-format
465+msgid "Error: You can not create recursive inventories."
466+msgstr "Erreur : Vous ne pouvez pas créer d'inventaire récursifs."
467+
468+#. module: stock_inventory_hierarchical
469+#: model:ir.model,name:stock_inventory_hierarchical.model_stock_inventory
470+msgid "Gestion des stocks"
471+msgstr "Gestion des stocks"
472+
473+#. module: stock_inventory_hierarchical
474+#: field:stock.inventory,inventory_ids:0
475+msgid "List of Sub-inventories"
476+msgstr "Liste des sous-inventaires"
477+
478+#. module: stock_inventory_hierarchical
479+#: view:stock.inventory:0
480+msgid "Main inventories"
481+msgstr "Inventaires principaux"
482+
483+#. module: stock_inventory_hierarchical
484+#: view:stock.inventory:0
485+msgid "Number of Sub-inventories"
486+msgstr "Nombre de sous-inventaires"
487+
488+#. module: stock_inventory_hierarchical
489+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:180
490+#, python-format
491+msgid "One of the parent Inventories is not canceled."
492+msgstr "Un des inventaires pères n'est pas annulé."
493+
494+#. module: stock_inventory_hierarchical
495+#: constraint:stock.inventory:0
496+msgid "Other Physical inventories are being conducted using the same Locations."
497+msgstr "Certains emplacements sont déjà dans un autre inventaire."
498+
499+#. module: stock_inventory_hierarchical
500+#: field:stock.inventory,parent_id:0
501+msgid "Parent"
502+msgstr "Parent"
503+
504+#. module: stock_inventory_hierarchical
505+#: field:stock.inventory,parent_left:0
506+msgid "Parent Left"
507+msgstr "Parent gauche"
508+
509+#. module: stock_inventory_hierarchical
510+#: field:stock.inventory,parent_right:0
511+msgid "Parent Right"
512+msgstr "Parent droit"
513+
514+#. module: stock_inventory_hierarchical
515+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:188
516+#, python-format
517+msgid "Some Sub-inventories are not confirmed."
518+msgstr "Certains sous-inventaires ne sont pas confirmés."
519+
520+#. module: stock_inventory_hierarchical
521+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:196
522+#, python-format
523+msgid "Some Sub-inventories are not validated."
524+msgstr "Certains sous-inventaires ne sont pas terminés."
525+
526+#. module: stock_inventory_hierarchical
527+#: model:ir.actions.act_window,name:stock_inventory_hierarchical.action_view_sub_inventory
528+#: view:stock.inventory:0
529+msgid "View Sub-inventories"
530+msgstr "Voir les sous-inventaires"
531+
532+#. module: stock_inventory_hierarchical
533+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:130
534+#, python-format
535+msgid "Sub-inventory: %s"
536+msgstr "Sous-inventaire : %s"
537+
538+#. module: stock_inventory_hierarchical
539+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:180
540+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:188
541+#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:196
542+#, python-format
543+msgid "Warning"
544+msgstr "Attention"
545+
546
547=== added directory 'stock_inventory_hierarchical/images'
548=== added file 'stock_inventory_hierarchical/images/inventory_form.png'
549Binary files stock_inventory_hierarchical/images/inventory_form.png 1970-01-01 00:00:00 +0000 and stock_inventory_hierarchical/images/inventory_form.png 2014-06-16 10:01:17 +0000 differ
550=== added file 'stock_inventory_hierarchical/images/inventory_form_actions.png'
551Binary files stock_inventory_hierarchical/images/inventory_form_actions.png 1970-01-01 00:00:00 +0000 and stock_inventory_hierarchical/images/inventory_form_actions.png 2014-06-16 10:01:17 +0000 differ
552=== added directory 'stock_inventory_hierarchical/static'
553=== added directory 'stock_inventory_hierarchical/static/src'
554=== added directory 'stock_inventory_hierarchical/static/src/img'
555=== added file 'stock_inventory_hierarchical/static/src/img/icon.png'
556Binary files stock_inventory_hierarchical/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and stock_inventory_hierarchical/static/src/img/icon.png 2014-06-16 10:01:17 +0000 differ
557=== added directory 'stock_inventory_hierarchical/test'
558=== added file 'stock_inventory_hierarchical/test/hierarchical_inventory_test.yml'
559--- stock_inventory_hierarchical/test/hierarchical_inventory_test.yml 1970-01-01 00:00:00 +0000
560+++ stock_inventory_hierarchical/test/hierarchical_inventory_test.yml 2014-06-16 10:01:17 +0000
561@@ -0,0 +1,96 @@
562+-
563+ In this file, i check rules about hierarchical inventories.
564+ Children date must be the same of parent date for each state,
565+ the state of parent and children can change only if conditions are correct.
566+-
567+ Check if date of children are the same as the parent's.
568+-
569+ !python {model: stock.inventory}: |
570+ parent_date = self.read(
571+ cr, uid, [ref('stock_inventory_parent0')], ['date'])[0]['date']
572+ child_1_date = self.read(
573+ cr, uid, [ref('child_1_id')], ['date'])[0]['date']
574+ assert child_1_date == parent_date, "Date are different: %s - %s" % (parent_date, child_1_date)
575+
576+ child_2_date = self.read(
577+ cr, uid, [ref('child_2_id')], ['date'])[0]['date']
578+ assert child_2_date == parent_date, "Date are different: %s - %s" % (parent_date, child_2_date)
579+
580+-
581+ Check if children cannot be canceled if the parent was not canceled.
582+ I'll try to cancel both children inventory while parent inventory having "draft" state.
583+ After, i'll verify the state of each inventory.
584+-
585+ !python {model: stock.inventory}: |
586+ from stock_inventory_hierarchical import HierarchicalInventoryException
587+ try:
588+ self.action_cancel_inventory(cr, uid, [ref('child_1_id')])
589+ except HierarchicalInventoryException as e:
590+ log("Good ! The Inventory could not be canceled: %s" % e)
591+ try:
592+ self.action_cancel_inventory(cr, uid, [ref('child_2_id')])
593+ except HierarchicalInventoryException as e:
594+ log("Good ! The Inventory could not be canceled: %s" % e)
595+ child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
596+ assert child_1_state == 'draft', "Child inventory 1 have '%s' state. It should be 'draft'" % child_1_state
597+ child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
598+ assert child_2_state == 'draft', "Child inventory 2 have '%s' state. It should be 'draft'" % child_2_state
599+
600+-
601+ Check if children inventory have confirm state before confirm parent inventory.
602+ To check this, i'll try to confirm parent inventory when children inventory having "draft" state,
603+ and i'll check if state is still 'draft'.
604+-
605+ !python {model: stock.inventory}: |
606+ from stock_inventory_hierarchical import HierarchicalInventoryException
607+ try:
608+ self.action_confirm(cr, uid, [ref('stock_inventory_parent0')])
609+ except HierarchicalInventoryException as e:
610+ log("Good, the inventory could not be confirmed: %s", e)
611+ parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
612+ assert parent_state == 'draft', "Parent inventory have '%s' state. It should be 'draft'" % parent_state
613+
614+-
615+ In order, i'll confirm the children inventories, and the parent inventory after.
616+-
617+ !python {model: stock.inventory}: |
618+ self.action_confirm(cr, uid, [ref('child_1_id')])
619+ child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
620+ assert child_1_state == 'confirm', "Child inventory 1 have '%s' state. It should be 'confirm'" % child_1_state
621+
622+ self.action_confirm(cr, uid, [ref('child_2_id')])
623+ child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
624+ assert child_2_state == 'confirm', "Child inventory 2 have '%s' state. It should be 'confirm'" % child_2_state
625+
626+ self.action_confirm(cr, uid, [ref('stock_inventory_parent0')])
627+ parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
628+ assert parent_state == 'confirm', "Parent inventory have '%s' state. It should be 'confirm'" % parent_state
629+
630+-
631+ Check if children inventory have done state before validate parent inventory.
632+ I'll try to validate parent inventory before children.
633+-
634+ !python {model: stock.inventory}: |
635+ from stock_inventory_hierarchical import HierarchicalInventoryException
636+ try:
637+ self.action_done(cr, uid, [ref('stock_inventory_parent0')])
638+ except HierarchicalInventoryException as e:
639+ log("Good, the inventory could not be validated: %s", e)
640+ parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
641+ assert parent_state == 'confirm', "Parent inventory have '%s' state. It should be 'confirm'" % parent_state
642+
643+-
644+ Now, i'll validate all children inventory before validate the parent.
645+-
646+ !python {model: stock.inventory}: |
647+ self.action_done(cr, uid, [ref('child_1_id')])
648+ child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
649+ assert child_1_state == 'done', "Child inventory 1 have '%s' state. It should be 'done'" % child_1_state
650+
651+ self.action_done(cr, uid, [ref('child_2_id')])
652+ child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
653+ assert child_2_state == 'done', "Child inventory 2 have '%s' state. It should be 'done'" % child_2_state
654+
655+ self.action_done(cr, uid, [ref('stock_inventory_parent0')])
656+ parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
657+ assert parent_state == 'done', "Parent inventory have '%s' state. It should be 'done'" % parent_state
658
659=== added directory 'stock_inventory_hierarchical_location'
660=== added file 'stock_inventory_hierarchical_location/__init__.py'
661--- stock_inventory_hierarchical_location/__init__.py 1970-01-01 00:00:00 +0000
662+++ stock_inventory_hierarchical_location/__init__.py 2014-06-16 10:01:17 +0000
663@@ -0,0 +1,22 @@
664+# -*- coding: utf-8 -*-
665+##############################################################################
666+#
667+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
668+#
669+# This program is free software: you can redistribute it and/or modify
670+# it under the terms of the GNU General Public License as published by
671+# the Free Software Foundation, either version 3 of the License, or
672+# (at your option) any later version.
673+#
674+# This program is distributed in the hope that it will be useful,
675+# but WITHOUT ANY WARRANTY; without even the implied warranty of
676+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677+# GNU General Public License for more details.
678+#
679+# You should have received a copy of the GNU General Public License
680+# along with this program. If not, see <http://www.gnu.org/licenses/>.
681+#
682+##############################################################################
683+
684+from . import inventory_hierarchical_location
685+from . import wizard
686
687=== added file 'stock_inventory_hierarchical_location/__openerp__.py'
688--- stock_inventory_hierarchical_location/__openerp__.py 1970-01-01 00:00:00 +0000
689+++ stock_inventory_hierarchical_location/__openerp__.py 2014-06-16 10:01:17 +0000
690@@ -0,0 +1,48 @@
691+# -*- coding: utf-8 -*-
692+##############################################################################
693+#
694+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
695+#
696+# This program is free software: you can redistribute it and/or modify
697+# it under the terms of the GNU General Public License as published by
698+# the Free Software Foundation, either version 3 of the License, or
699+# (at your option) any later version.
700+#
701+# This program is distributed in the hope that it will be useful,
702+# but WITHOUT ANY WARRANTY; without even the implied warranty of
703+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
704+# GNU General Public License for more details.
705+#
706+# You should have received a copy of the GNU General Public License
707+# along with this program. If not, see <http://www.gnu.org/licenses/>.
708+#
709+##############################################################################
710+
711+{
712+ "name": "Exhaustive and hierarchical Stock Inventories",
713+ "version": "1.1",
714+ "depends": ["stock_inventory_hierarchical", "stock_inventory_location"],
715+ "auto_install": True,
716+ "author": u"Numérigraphe",
717+ "category": "Hidden",
718+ "description": """
719+Make exhaustive Inventories aware of their Sub-Inventories.
720+===========================================================
721+
722+This module allows an inventory to contain a general Location,
723+and it's sub-inventories to contain some of it's sub-Locations.
724+It will prevent you from setting the Inventories and sub-Inventories
725+in inconsistent status.
726+
727+This module will be installed automatically if the modules
728+"stock_inventory_location" and "stock_inventory_hierarchical" are both
729+installed.
730+You must keep this module installed to ensure proper functioning.
731+
732+ """,
733+ "data": [
734+ "inventory_hierarchical_location_view.xml",
735+ ],
736+ "test": ["tests/inventory_hierarchical_location_test.yml"],
737+ "demo": ["inventory_hierarchical_location_demo.xml"],
738+}
739
740=== added directory 'stock_inventory_hierarchical_location/i18n'
741=== added file 'stock_inventory_hierarchical_location/i18n/fr.po'
742--- stock_inventory_hierarchical_location/i18n/fr.po 1970-01-01 00:00:00 +0000
743+++ stock_inventory_hierarchical_location/i18n/fr.po 2014-06-16 10:01:17 +0000
744@@ -0,0 +1,127 @@
745+# Translation of OpenERP Server.
746+# This file contains the translation of the following modules:
747+# * stock_inventory_hierarchical_location
748+#
749+msgid ""
750+msgstr ""
751+"Project-Id-Version: OpenERP Server 6.0.4\n"
752+"Report-Msgid-Bugs-To: support@openerp.com\n"
753+"POT-Creation-Date: 2013-09-25 13:55+0000\n"
754+"PO-Revision-Date: 2013-09-25 13:55+0000\n"
755+"Last-Translator: <>\n"
756+"Language-Team: \n"
757+"MIME-Version: 1.0\n"
758+"Content-Type: text/plain; charset=UTF-8\n"
759+"Content-Transfer-Encoding: \n"
760+"Plural-Forms: \n"
761+
762+#. module: stock_inventory_hierarchical_location
763+#: model:ir.actions.act_window,name:stock_inventory_hierarchical_location.action_view_stock_inventory_missing_location
764+msgid "Confirm missing location"
765+msgstr "Confirmer les emplacements manquants"
766+
767+#. module: stock_inventory_hierarchical_location
768+#: view:stock.inventory.missing.location:0
769+msgid "Confirm missing locations"
770+msgstr "Confirmer les emplacements manquants"
771+
772+#. module: stock_inventory_hierarchical_location
773+#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory_uninventoried_locations
774+msgid "Confirm the uninventoried Locations."
775+msgstr "Confirmer les emplacements non inventoriés."
776+
777+#. module: stock_inventory_hierarchical_location
778+#: view:stock.inventory.missing.location:0
779+msgid "Do you want to continue ?"
780+msgstr "Voulez-vous continuer ?"
781+
782+#. module: stock_inventory_hierarchical_location
783+#: constraint:stock.inventory:0
784+msgid "Error! You can not create recursive inventories."
785+msgstr "Erreur! Vous ne pouvez pas créer un inventaire récursif."
786+
787+#. module: stock_inventory_hierarchical_location
788+#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory
789+msgid "Gestion des stocks"
790+msgstr "Gestion des stocks"
791+
792+#. module: stock_inventory_hierarchical_location
793+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:70
794+#, python-format
795+msgid "Location missing for inventory \"%s\"."
796+msgstr "Emplacement manquants dans l'inventaire \"%s\"."
797+
798+#. module: stock_inventory_hierarchical_location
799+#: view:stock.inventory:0
800+msgid "Locations"
801+msgstr "Emplacements"
802+
803+#. module: stock_inventory_hierarchical_location
804+#: field:stock.inventory.missing.location,location_ids:0
805+msgid "Missing location"
806+msgstr "Emplacements manquants"
807+
808+#. module: stock_inventory_hierarchical_location
809+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:41
810+#, python-format
811+msgid "One of the parent inventories is not open."
812+msgstr "Un des inventaire parent n'est pas ouvert."
813+
814+#. module: stock_inventory_hierarchical_location
815+#: view:stock.inventory:0
816+msgid "Open Inventory"
817+msgstr "Ouvrir l'inventaire"
818+
819+#. module: stock_inventory_hierarchical_location
820+#: constraint:stock.inventory:0
821+msgid "Other Physical inventories are being conducted using the same Locations."
822+msgstr "Erreur: certains emplacements sont déjà dans un autre inventaire."
823+
824+#. module: stock_inventory_hierarchical_location
825+#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory_missing_location
826+msgid "Search on inventory tree for missing declared locations."
827+msgstr "Recherche dans les inventaires les emplacements absents."
828+
829+#. module: stock_inventory_hierarchical_location
830+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:122
831+#, python-format
832+msgid "Some Sub-inventories are not confirmed."
833+msgstr "Au moins un sous-inventaire n'est pas confirmé."
834+
835+#. module: stock_inventory_hierarchical_location
836+#: view:stock.inventory.missing.location:0
837+msgid "This is the list of missing locations."
838+msgstr "Voici la liste des emplacements manquants."
839+
840+#. module: stock_inventory_hierarchical_location
841+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:58
842+#, python-format
843+msgid "This location is not declared on the parent inventory\n"
844+"It cannot be added."
845+msgstr "Cet emplacement n'est pas déclaré dans l'inventaire parent\n"
846+"Vous ne pouvez pas l'ajouter."
847+
848+#. module: stock_inventory_hierarchical_location
849+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:41
850+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:70
851+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:122
852+#, python-format
853+msgid "Warning !"
854+msgstr "Attention !"
855+
856+#. module: stock_inventory_hierarchical_location
857+#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:57
858+#, python-format
859+msgid "Warning: Wrong location"
860+msgstr "Attention: mauvais emplacement"
861+
862+#. module: stock_inventory_hierarchical_location
863+#: view:stock.inventory.missing.location:0
864+msgid "_Cancel"
865+msgstr "_Annuler"
866+
867+#. module: stock_inventory_hierarchical_location
868+#: view:stock.inventory.missing.location:0
869+msgid "_Confirm missing locations"
870+msgstr "_Confirmer les emplacements manquants"
871+
872
873=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location.py'
874--- stock_inventory_hierarchical_location/inventory_hierarchical_location.py 1970-01-01 00:00:00 +0000
875+++ stock_inventory_hierarchical_location/inventory_hierarchical_location.py 2014-06-16 10:01:17 +0000
876@@ -0,0 +1,88 @@
877+# -*- coding: utf-8 -*-
878+##############################################################################
879+#
880+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
881+#
882+# This program is free software: you can redistribute it and/or modify
883+# it under the terms of the GNU General Public License as published by
884+# the Free Software Foundation, either version 3 of the License, or
885+# (at your option) any later version.
886+#
887+# This program is distributed in the hope that it will be useful,
888+# but WITHOUT ANY WARRANTY; without even the implied warranty of
889+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
890+# GNU General Public License for more details.
891+#
892+# You should have received a copy of the GNU General Public License
893+# along with this program. If not, see <http://www.gnu.org/licenses/>.
894+#
895+##############################################################################
896+
897+from openerp.osv import orm
898+from openerp.tools.translate import _
899+
900+from stock_inventory_hierarchical import HierarchicalInventoryException
901+
902+# Add the date to the list of fields we must propagate to children inventories
903+from stock_inventory_hierarchical import PARENT_VALUES
904+PARENT_VALUES.append('exhaustive')
905+
906+
907+class HierarchicalExhInventory(orm.Model):
908+ """Add hierarchical structure features to exhaustive Inventories"""
909+ _inherit = 'stock.inventory'
910+
911+ def action_open(self, cr, uid, ids, context=None):
912+ """Open only if all the parents are Open."""
913+ for inventory in self.browse(cr, uid, ids, context=context):
914+ while inventory.parent_id:
915+ inventory = inventory.parent_id
916+ if inventory.state != 'open':
917+ raise HierarchicalInventoryException(
918+ _('Warning'),
919+ _('One of the parent inventories is not open.'))
920+ return super(HierarchicalExhInventory, self).action_open(
921+ cr, uid, ids, context=context)
922+
923+ def get_missing_locations(self, cr, uid, ids, context=None):
924+ """Extend the list of inventories with their children"""
925+ ids = self.search(
926+ cr, uid, [('parent_id', 'child_of', ids)], context=context)
927+ return super(HierarchicalExhInventory, self).get_missing_locations(
928+ cr, uid, ids, context=context)
929+
930+ # TODO v8: probably only keep the state "done"
931+ def confirm_missing_locations(self, cr, uid, ids, context=None):
932+ """Do something only if children state are confirm or done."""
933+ children_count = self.search(
934+ cr, uid, [('parent_id', 'child_of', ids),
935+ ('id', 'not in', ids),
936+ ('state', 'not in', ['confirm', 'done'])],
937+ context=context, count=True)
938+ if children_count > 0:
939+ raise HierarchicalInventoryException(
940+ _('Warning'),
941+ _('Some Sub-inventories are not confirmed.'))
942+ return super(HierarchicalExhInventory,
943+ self).confirm_missing_locations(
944+ cr, uid, ids, context=context)
945+
946+ def onchange_location_id(self, cr, uid, ids, location_id, context=None):
947+ """Check if location is a child of parent inventory location"""
948+ loc_obj = self.pool['stock.location']
949+ for inventory in self.browse(cr, uid, ids, context=context):
950+ if inventory.parent_id:
951+ allowed_location_ids = loc_obj.search(
952+ cr, uid, [('location_id', 'child_of',
953+ inventory.parent_id.location_id.id)],
954+ context=context)
955+ if location_id not in allowed_location_ids:
956+ return {
957+ 'location_id': False,
958+ 'warning': {
959+ 'title': _('Warning: Wrong location'),
960+ 'message': _("This location is not declared on "
961+ "the parent inventory\n"
962+ "It cannot be added.")}
963+ }
964+ return {}
965
966=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml'
967--- stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 1970-01-01 00:00:00 +0000
968+++ stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 2014-06-16 10:01:17 +0000
969@@ -0,0 +1,28 @@
970+<?xml version="1.0" encoding="utf-8"?>
971+<openerp>
972+ <data noupdate="0">
973+
974+ <!-- Record inventories we can use in the tests. -->
975+ <!-- We need them in the demo data because test data is rolled back
976+ whenever an exception is raised. -->
977+
978+ <!-- Record a hierarchical exhaustive inventory -->
979+ <record id="parent_inventory" model="stock.inventory">
980+ <field name="name">Hierarchical exhaustive inventory</field>
981+ <field name="state">draft</field>
982+ <field name="date">2020-04-15 00:00:00</field>
983+ <field name="exhaustive">True</field>
984+ <field name="location_id" model="stock.location" ref="stock.stock_location_stock"/>
985+ </record>
986+ <record id="child_1_id" model="stock.inventory">
987+ <field name="name">Team A</field>
988+ <field name="parent_id" ref="parent_inventory"/>
989+ <field name="location_id" model="stock.location" ref="stock.stock_location_14"/>
990+ </record>
991+ <record id="child_2_id" model="stock.inventory">
992+ <field name="name">Team B</field>
993+ <field name="parent_id" ref="parent_inventory"/>
994+ <field name="location_id" model="stock.location" ref="stock.stock_location_components"/>
995+ </record>
996+ </data>
997+</openerp>
998
999=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml'
1000--- stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml 1970-01-01 00:00:00 +0000
1001+++ stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml 2014-06-16 10:01:17 +0000
1002@@ -0,0 +1,37 @@
1003+<?xml version="1.0" encoding="utf-8"?>
1004+<openerp>
1005+ <data>
1006+ <record model="ir.ui.view" id="stock_inventory_hierarchical_location_form_view">
1007+ <field name="name">hierarchical.inventory.location.form</field>
1008+ <field name="model">stock.inventory</field>
1009+ <field name="inherit_id" ref="stock.view_inventory_form" />
1010+ <field name="arch" type="xml">
1011+
1012+ <xpath expr="/form//field[@name='exhaustive']" position="attributes">
1013+ <attribute name="attrs">{'readonly':[('parent_id', '!=', False)]}</attribute>
1014+ </xpath>
1015+
1016+ <xpath expr="/form//field[@name='location_id']" position="attributes">
1017+ <attribute name="on_change">onchange_location_id(location_id)</attribute>
1018+ </xpath>
1019+
1020+ </field>
1021+ </record>
1022+
1023+ <record model="ir.ui.view" id="stock_ihl_exhautive_form_view">
1024+ <field name="name">hierarchical.inventory.location.exhautive.form</field>
1025+ <field name="model">stock.inventory</field>
1026+ <field name="inherit_id" ref="stock_inventory_hierarchical.stock_inventory_hierarchical_form_view" />
1027+ <field name="arch" type="xml">
1028+ <xpath expr="//field[@name='inventory_ids']" position="attributes">
1029+ <attribute name="context">{'default_parent_id': active_id, 'default_exhaustive': exhaustive}</attribute>
1030+ </xpath>
1031+ </field>
1032+ </record>
1033+
1034+ <!-- Show hierarchical exhaustive inventories by default -->
1035+ <record id="stock.action_inventory_form" model="ir.actions.act_window">
1036+ <field name="context">{'full':'1', 'search_default_exhaustive':1, 'search_default_main_inventories':1}</field>
1037+ </record>
1038+ </data>
1039+</openerp>
1040
1041=== added directory 'stock_inventory_hierarchical_location/static'
1042=== added directory 'stock_inventory_hierarchical_location/static/src'
1043=== added directory 'stock_inventory_hierarchical_location/static/src/img'
1044=== added file 'stock_inventory_hierarchical_location/static/src/img/icon.png'
1045Binary files stock_inventory_hierarchical_location/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and stock_inventory_hierarchical_location/static/src/img/icon.png 2014-06-16 10:01:17 +0000 differ
1046=== added directory 'stock_inventory_hierarchical_location/tests'
1047=== added file 'stock_inventory_hierarchical_location/tests/__init__.py'
1048--- stock_inventory_hierarchical_location/tests/__init__.py 1970-01-01 00:00:00 +0000
1049+++ stock_inventory_hierarchical_location/tests/__init__.py 2014-06-16 10:01:17 +0000
1050@@ -0,0 +1,39 @@
1051+# -*- coding: utf-8 -*-
1052+#
1053+#
1054+# Authors: Laetitia Gangloff
1055+# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
1056+# All Rights Reserved
1057+#
1058+# WARNING: This program as such is intended to be used by professional
1059+# programmers who take the whole responsibility of assessing all potential
1060+# consequences resulting from its eventual inadequacies and bugs.
1061+# End users who are looking for a ready-to-use solution with commercial
1062+# guarantees and support are strongly advised to contact a Free Software
1063+# Service Company.
1064+#
1065+# This program is free software: you can redistribute it and/or modify
1066+# it under the terms of the GNU Affero General Public License as
1067+# published by the Free Software Foundation, either version 3 of the
1068+# License, or (at your option) any later version.
1069+#
1070+# This program is distributed in the hope that it will be useful,
1071+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1072+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1073+# GNU Affero General Public License for more details.
1074+#
1075+# You should have received a copy of the GNU Affero General Public License
1076+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1077+#
1078+#
1079+
1080+import fill_inventory_test
1081+
1082+fast_suite = [
1083+]
1084+
1085+checks = [
1086+ fill_inventory_test,
1087+]
1088+
1089+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1090
1091=== added file 'stock_inventory_hierarchical_location/tests/fill_inventory_test.py'
1092--- stock_inventory_hierarchical_location/tests/fill_inventory_test.py 1970-01-01 00:00:00 +0000
1093+++ stock_inventory_hierarchical_location/tests/fill_inventory_test.py 2014-06-16 10:01:17 +0000
1094@@ -0,0 +1,118 @@
1095+# -*- coding: utf-8 -*-
1096+#
1097+#
1098+# Authors: Laetitia Gangloff
1099+# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
1100+# All Rights Reserved
1101+#
1102+# WARNING: This program as such is intended to be used by professional
1103+# programmers who take the whole responsibility of assessing all potential
1104+# consequences resulting from its eventual inadequacies and bugs.
1105+# End users who are looking for a ready-to-use solution with commercial
1106+# guarantees and support are strongly advised to contact a Free Software
1107+# Service Company.
1108+#
1109+# This program is free software: you can redistribute it and/or modify
1110+# it under the terms of the GNU Affero General Public License as
1111+# published by the Free Software Foundation, either version 3 of the
1112+# License, or (at your option) any later version.
1113+#
1114+# This program is distributed in the hope that it will be useful,
1115+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1116+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1117+# GNU Affero General Public License for more details.
1118+#
1119+# You should have received a copy of the GNU Affero General Public License
1120+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1121+#
1122+#
1123+
1124+import openerp.tests.common as common
1125+
1126+DB = common.DB
1127+ADMIN_USER_ID = common.ADMIN_USER_ID
1128+
1129+
1130+class fill_inventory_test(common.TransactionCase):
1131+
1132+ def setUp(self):
1133+ super(fill_inventory_test, self).setUp()
1134+
1135+ def test_missing_location(self):
1136+ """
1137+ Test that when confirm a parent inventory, the child location are not in the confirmation result
1138+ """
1139+ parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory')
1140+ self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id])
1141+ # confirm shelf 1 inventory
1142+ inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id')
1143+ self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
1144+ missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
1145+ self.assertEqual(len(missing_location), 1, "1 missing location should be find, because the inventory is empty")
1146+ wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]})
1147+ self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
1148+ missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
1149+ self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is confirmed")
1150+ # confirm shelf 2 inventory
1151+ inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id')
1152+ self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
1153+ missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
1154+ self.assertEqual(len(missing_location), 1, "1 missing location should be fine, because the inventory is empty")
1155+ self.registry('stock.inventory.line').create(self.cr, self.uid, {'product_id': self.ref('product.product_product_7'),
1156+ 'product_uom': self.ref('product.product_uom_unit'),
1157+ 'company_id': self.ref('base.main_company'),
1158+ 'inventory_id': inventory_id,
1159+ 'product_qty': 18.0,
1160+ 'location_id': self.ref('stock.stock_location_14')})
1161+ missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
1162+ self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is filled")
1163+ wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]})
1164+ wizard = self.registry('stock.inventory.uninventoried.locations').browse(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
1165+ self.assertEqual(len(wizard.location_ids), 0, "The wizard should not contain any lines but contains %s." % wizard.location_ids)
1166+ self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
1167+ # confirm parent inventory
1168+ missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [parent_inventory_id])
1169+ self.assertEqual(len(missing_location), 1, "Only 1 missing location should be find, because there is some location in child inventory")
1170+
1171+ def test_fill_inventory(self):
1172+ """
1173+ Test that when fill a parent inventory, the child location are not in the result
1174+ """
1175+ parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory')
1176+ self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id])
1177+ # confirm shelf 1 inventory
1178+ inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id')
1179+ self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
1180+ wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_components'),
1181+ 'recursive': True,
1182+ 'exhaustive': True,
1183+ 'set_stock_zero': True}, context={'active_ids': [inventory_id]})
1184+ self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]})
1185+ inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)])
1186+ self.assertEqual(len(inventory_line_ids), 12, "12 inventory line is fount after filling inventory")
1187+ # confirm shelf 2 inventory
1188+ inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id')
1189+ self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
1190+ wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_14'),
1191+ 'recursive': True,
1192+ 'exhaustive': True,
1193+ 'set_stock_zero': True}, context={'active_ids': [inventory_id]})
1194+ self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]})
1195+ inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)])
1196+ self.assertEqual(len(inventory_line_ids), 4, "1 inventory line is fount after filling inventory")
1197+ # confirm parent inventory
1198+ wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_stock'),
1199+ 'recursive': True,
1200+ 'exhaustive': True,
1201+ 'set_stock_zero': True}, context={'active_ids': [parent_inventory_id]})
1202+ try:
1203+ self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [parent_inventory_id]})
1204+ except Exception, e:
1205+ self.assertEqual(e.value, 'No product in this location. Please select a location in the product form.', "The message should be ''No product in this location. Please select a location in the product form.''")
1206+ exception_happened = True
1207+ pass
1208+ self.assertTrue(exception_happened)
1209+ inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', parent_inventory_id)])
1210+ self.assertEqual(len(inventory_line_ids), 0, "No inventory line is fount after filling inventory")
1211+
1212+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1213
1214=== added file 'stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml'
1215--- stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml 1970-01-01 00:00:00 +0000
1216+++ stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml 2014-06-16 10:01:17 +0000
1217@@ -0,0 +1,56 @@
1218+-
1219+ Check that the exhaustive field of parent inventory has been propagated to children.
1220+-
1221+ !python {model: stock.inventory}: |
1222+ exhaustive = self.read(cr, uid, [ref("child_1_id")], ['exhaustive'])[0]['exhaustive']
1223+ assert exhaustive, "Exhaustive field not propagated to child inventory"
1224+
1225+-
1226+ Check that I can't open child inventory while parent inventory is open.
1227+-
1228+ !python {model: stock.inventory}: |
1229+ from stock_inventory_hierarchical import HierarchicalInventoryException
1230+ parent_state = self.read(cr, uid, [ref("parent_inventory")], ['state'])[0]['state']
1231+ assert parent_state == 'draft', "Parent inventory in state '%s'. It should be 'draft'" % parent_state
1232+ try:
1233+ self.action_open(cr, uid, [ref("child_1_id")])
1234+ except HierarchicalInventoryException as e:
1235+ log("Good ! The Inventory could not be opened: %s" % e)
1236+ child_1_state = self.read(cr, uid, [ref("child_1_id")], ['state'])[0]['state']
1237+ assert child_1_state == 'draft', "Child inventory 1 have '%s' state. It should be 'draft'" % child_1_state
1238+
1239+-
1240+ I will check that the function get_missing_locations return some locations.
1241+-
1242+ !python {model: stock.inventory}: |
1243+ missing_loc_ids = self.get_missing_locations(cr, uid, [ref('parent_inventory')], context=context)
1244+ assert len(missing_loc_ids)==3, "get_missing_locations did not return any ID."
1245+
1246+-
1247+ I will fill the inventory and check that the function get_missing_locations return no locations.
1248+ Adding 17” LCD Monitor.
1249+-
1250+ !record {model: stock.inventory.line, id: lines_inventory_location_pc1}:
1251+ product_id: product.product_product_7
1252+ product_uom: product.product_uom_unit
1253+ company_id: base.main_company
1254+ inventory_id: child_1_id
1255+ product_qty: 18.0
1256+ location_id: stock.stock_location_14
1257+
1258+-
1259+ Adding USB Keyboard, QWERTY.
1260+-
1261+ !record {model: stock.inventory.line, id: lines_inventory_location_pc3}:
1262+ product_id: product.product_product_8
1263+ product_uom: product.product_uom_unit
1264+ company_id: base.main_company
1265+ inventory_id: child_2_id
1266+ product_qty: 5.0
1267+ location_id: stock.stock_location_components
1268+
1269+-
1270+ !python {model: stock.inventory}: |
1271+
1272+ missing_loc_ids = self.get_missing_locations(cr, uid, [ref('parent_inventory')], context=context)
1273+ assert set(missing_loc_ids)==set([ref('stock.stock_location_stock')]), "get_missing_locations should return only %s but returned %s" % ([ref('stock.stock_location_stock')], missing_loc_ids)
1274
1275=== added directory 'stock_inventory_hierarchical_location/wizard'
1276=== added file 'stock_inventory_hierarchical_location/wizard/__init__.py'
1277--- stock_inventory_hierarchical_location/wizard/__init__.py 1970-01-01 00:00:00 +0000
1278+++ stock_inventory_hierarchical_location/wizard/__init__.py 2014-06-16 10:01:17 +0000
1279@@ -0,0 +1,21 @@
1280+# -*- coding: utf-8 -*-
1281+##############################################################################
1282+#
1283+# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
1284+#
1285+# This program is free software: you can redistribute it and/or modify
1286+# it under the terms of the GNU General Public License as published by
1287+# the Free Software Foundation, either version 3 of the License, or
1288+# (at your option) any later version.
1289+#
1290+# This program is distributed in the hope that it will be useful,
1291+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1292+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1293+# GNU General Public License for more details.
1294+#
1295+# You should have received a copy of the GNU General Public License
1296+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1297+#
1298+##############################################################################
1299+
1300+from . import stock_fill_location_inventory
1301
1302=== added file 'stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py'
1303--- stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 1970-01-01 00:00:00 +0000
1304+++ stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 2014-06-16 10:01:17 +0000
1305@@ -0,0 +1,89 @@
1306+# -*- coding: utf-8 -*-
1307+#
1308+#
1309+# Authors: Laetitia Gangloff
1310+# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
1311+# All Rights Reserved
1312+#
1313+# WARNING: This program as such is intended to be used by professional
1314+# programmers who take the whole responsibility of assessing all potential
1315+# consequences resulting from its eventual inadequacies and bugs.
1316+# End users who are looking for a ready-to-use solution with commercial
1317+# guarantees and support are strongly advised to contact a Free Software
1318+# Service Company.
1319+#
1320+# This program is free software: you can redistribute it and/or modify
1321+# it under the terms of the GNU Affero General Public License as
1322+# published by the Free Software Foundation, either version 3 of the
1323+# License, or (at your option) any later version.
1324+#
1325+# This program is distributed in the hope that it will be useful,
1326+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1327+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1328+# GNU Affero General Public License for more details.
1329+#
1330+# You should have received a copy of the GNU Affero General Public License
1331+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1332+#
1333+#
1334+
1335+from openerp.osv import orm
1336+from openerp.tools.translate import _
1337+
1338+
1339+class FillInventoryWizard(orm.TransientModel):
1340+ """If inventory as sub inventories, do not fill with sub inventories location"""
1341+ _inherit = 'stock.fill.inventory'
1342+
1343+ def fill_inventory(self, cr, uid, ids, context=None):
1344+ """ To Import stock inventory according to products available in the location and not already in a sub inventory
1345+
1346+ We split fill_inventory on many fill_inventory (one for each location)
1347+ @param self: The object pointer.
1348+ @param cr: A database cursor
1349+ @param uid: ID of the user currently logged in
1350+ @param ids: the ID or list of IDs if we want more than one
1351+ @param context: A standard dictionary
1352+ @return:
1353+ """
1354+ if context is None:
1355+ context = {}
1356+
1357+ if ids and len(ids):
1358+ ids = ids[0]
1359+ else:
1360+ return {'type': 'ir.actions.act_window_close'}
1361+ fill_inventory = self.browse(cr, uid, ids, context=context)
1362+ if fill_inventory.recursive and fill_inventory.exhaustive:
1363+ exclude_location_ids = []
1364+ for i in self.pool['stock.inventory'].browse(cr, uid, context['active_ids']):
1365+ for sub_inventory in i.inventory_ids:
1366+ # exclude these location
1367+ exclude_location_ids.append(sub_inventory.location_id.id)
1368+ domain = [('location_id', 'child_of', [fill_inventory.location_id.id])]
1369+ if exclude_location_ids:
1370+ domain.append('!')
1371+ domain.append(('location_id', 'child_of', exclude_location_ids))
1372+ location_ids = self.pool['stock.location'].search(cr, uid, domain,
1373+ order="id",
1374+ context=context)
1375+ all_in_exception = 0
1376+ for location_id in location_ids:
1377+ try:
1378+ super(FillInventoryWizard, self).fill_inventory(cr, uid,
1379+ [self.copy(cr, uid, ids, {'location_id': location_id,
1380+ 'recursive': False, }, context=context)],
1381+ context=context)
1382+ except Exception, e:
1383+ if e.value == _('No product in this location. Please select a location in the product form.'):
1384+ all_in_exception = all_in_exception + 1
1385+ pass
1386+ else:
1387+ raise e
1388+ if all_in_exception == len(location_ids):
1389+ raise orm.except_orm(_('Warning!'), _('No product in this location. Please select a location in the product form.'))
1390+ return {'type': 'ir.actions.act_window_close'}
1391+ else:
1392+ return super(FillInventoryWizard, self).fill_inventory(cr, uid, [ids], context=context)
1393+
1394+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1395
1396=== modified file 'stock_inventory_location/__openerp__.py'
1397--- stock_inventory_location/__openerp__.py 2014-06-16 10:01:17 +0000
1398+++ stock_inventory_location/__openerp__.py 2014-06-16 10:01:17 +0000
1399@@ -62,9 +62,9 @@
1400 "wizard/stock_fill_location_inventory_view.xml",
1401 ],
1402 "test": [
1403- "test/inventory_standard_test.yml",
1404- "test/inventory_exhaustive_test.yml",
1405- "test/inventory_future_test.yml",
1406+ "tests/inventory_standard_test.yml",
1407+ "tests/inventory_exhaustive_test.yml",
1408+ "tests/inventory_future_test.yml",
1409 ],
1410 "images": [
1411 "images/inventory_form.png",
1412
1413=== modified file 'stock_inventory_location/stock_inventory_location.py'
1414--- stock_inventory_location/stock_inventory_location.py 2014-06-16 10:01:17 +0000
1415+++ stock_inventory_location/stock_inventory_location.py 2014-06-16 10:01:17 +0000
1416@@ -27,6 +27,7 @@
1417 # TODOv8! remove, feature is included upstream
1418 from openerp.osv import osv
1419 from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
1420+from openerp import SUPERUSER_ID
1421
1422 from .exceptions import ExhaustiveInventoryException
1423
1424@@ -270,7 +271,7 @@
1425 """Error if an exhaustive Inventory is being conducted here"""
1426 inv_obj = self.pool['stock.inventory']
1427 location_inventory_open_ids = inv_obj._get_locations_open_inventories(
1428- cr, uid, context=context)
1429+ cr, SUPERUSER_ID, context=context)
1430 if not isinstance(ids, Iterable):
1431 ids = [ids]
1432 for inv_id in ids:
1433@@ -286,7 +287,7 @@
1434 self._check_inventory(cr, uid, ids, context=context)
1435 if not isinstance(ids, Iterable):
1436 ids = [ids]
1437- ids_to_check = ids
1438+ ids_to_check = list(ids)
1439 # If changing the parent, no inventory must conducted there either
1440 if vals.get('location_id'):
1441 ids_to_check.append(vals['location_id'])
1442@@ -326,7 +327,7 @@
1443 message = ""
1444 inv_obj = self.pool['stock.inventory']
1445 locked_location_ids = inv_obj._get_locations_open_inventories(
1446- cr, uid, context=context)
1447+ cr, SUPERUSER_ID, context=context)
1448 if not locked_location_ids:
1449 # Nothing to verify
1450 return True
1451
1452=== renamed directory 'stock_inventory_location/test' => 'stock_inventory_location/tests'
1453=== added file 'stock_inventory_location/tests/__init__.py'
1454--- stock_inventory_location/tests/__init__.py 1970-01-01 00:00:00 +0000
1455+++ stock_inventory_location/tests/__init__.py 2014-06-16 10:01:17 +0000
1456@@ -0,0 +1,39 @@
1457+# -*- coding: utf-8 -*-
1458+#
1459+#
1460+# Authors: Laetitia Gangloff
1461+# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
1462+# All Rights Reserved
1463+#
1464+# WARNING: This program as such is intended to be used by professional
1465+# programmers who take the whole responsibility of assessing all potential
1466+# consequences resulting from its eventual inadequacies and bugs.
1467+# End users who are looking for a ready-to-use solution with commercial
1468+# guarantees and support are strongly advised to contact a Free Software
1469+# Service Company.
1470+#
1471+# This program is free software: you can redistribute it and/or modify
1472+# it under the terms of the GNU Affero General Public License as
1473+# published by the Free Software Foundation, either version 3 of the
1474+# License, or (at your option) any later version.
1475+#
1476+# This program is distributed in the hope that it will be useful,
1477+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1478+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1479+# GNU Affero General Public License for more details.
1480+#
1481+# You should have received a copy of the GNU Affero General Public License
1482+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1483+#
1484+#
1485+
1486+import stock_inventory_location_test
1487+
1488+fast_suite = [
1489+]
1490+
1491+checks = [
1492+ stock_inventory_location_test,
1493+]
1494+
1495+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1496
1497=== added file 'stock_inventory_location/tests/stock_inventory_location_test.py'
1498--- stock_inventory_location/tests/stock_inventory_location_test.py 1970-01-01 00:00:00 +0000
1499+++ stock_inventory_location/tests/stock_inventory_location_test.py 2014-06-16 10:01:17 +0000
1500@@ -0,0 +1,47 @@
1501+# -*- coding: utf-8 -*-
1502+#
1503+#
1504+# Authors: Laetitia Gangloff
1505+# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
1506+# All Rights Reserved
1507+#
1508+# WARNING: This program as such is intended to be used by professional
1509+# programmers who take the whole responsibility of assessing all potential
1510+# consequences resulting from its eventual inadequacies and bugs.
1511+# End users who are looking for a ready-to-use solution with commercial
1512+# guarantees and support are strongly advised to contact a Free Software
1513+# Service Company.
1514+#
1515+# This program is free software: you can redistribute it and/or modify
1516+# it under the terms of the GNU Affero General Public License as
1517+# published by the Free Software Foundation, either version 3 of the
1518+# License, or (at your option) any later version.
1519+#
1520+# This program is distributed in the hope that it will be useful,
1521+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1522+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1523+# GNU Affero General Public License for more details.
1524+#
1525+# You should have received a copy of the GNU Affero General Public License
1526+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1527+#
1528+#
1529+
1530+import openerp.tests.common as common
1531+
1532+DB = common.DB
1533+ADMIN_USER_ID = common.ADMIN_USER_ID
1534+
1535+
1536+class stock_inventory_location_test(common.TransactionCase):
1537+
1538+ def setUp(self):
1539+ super(stock_inventory_location_test, self).setUp()
1540+
1541+ def test_update_parent_location(self):
1542+ """
1543+ Test the update of the parent of a location (no inventory in progress
1544+ """
1545+ self.registry('stock.location').write(self.cr, self.uid, self.ref('stock.stock_location_5'), {'location_id': self.ref('stock.stock_location_4')})
1546+
1547+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: