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
=== added directory 'stock_inventory_hierarchical'
=== added file 'stock_inventory_hierarchical/__init__.py'
--- stock_inventory_hierarchical/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/__init__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,28 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21# This package-wide list keeps the names of the field that must be
22# propagated from root inventories to their children.
23# Add field names in the Model's definition.
24PARENT_VALUES = []
25
26import hierarchical_inventory
27# Bring the main exception into the package's scope for easier reuse
28from .exceptions import HierarchicalInventoryException
029
=== added file 'stock_inventory_hierarchical/__openerp__.py'
--- stock_inventory_hierarchical/__openerp__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/__openerp__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21{
22 "name": "Hierarchical Physical Inventory",
23 "version": "1.1",
24 "depends": ["stock"],
25 "author": "Numérigraphe",
26 "category": "Warehouse Management",
27 "description": """
28Hierarchical structure for Physical Inventories and sub-Inventories
29===================================================================
30
31This module adds a parent-child relationship between Physical Inventories, to
32help users manage complex inventories.
33Using several inventories, you can distribute the counting to several persons
34and still keep a clear overview of global Inventory's status.
35
36OpenERP will make sure the status of the Inventory and it's Sub-Inventories are
37consistent.
38""",
39 "data": ["hierarchical_inventory_view.xml"],
40 "test": ["test/hierarchical_inventory_test.yml"],
41 "demo": ["hierarchical_inventory_demo.xml"],
42 "images": [
43 "inventory_form.png",
44 "inventory_form_actions.png",
45 ],
46}
047
=== added file 'stock_inventory_hierarchical/exceptions.py'
--- stock_inventory_hierarchical/exceptions.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/exceptions.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,26 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21from openerp.osv import orm
22
23
24class HierarchicalInventoryException(orm.except_orm):
25 """The operation is not possible for a hierarchical inventory"""
26 pass
027
=== added file 'stock_inventory_hierarchical/hierarchical_inventory.py'
--- stock_inventory_hierarchical/hierarchical_inventory.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/hierarchical_inventory.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,202 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21from openerp.osv import orm, fields
22from openerp.tools.translate import _
23
24from .exceptions import HierarchicalInventoryException
25
26# Add the date to the list of fields we must propagate to children inventories
27from . import PARENT_VALUES
28PARENT_VALUES.append('date')
29
30
31class HierarchicalInventory(orm.Model):
32 _inherit = 'stock.inventory'
33
34 _parent_store = True
35 _parent_order = 'date, name'
36 _order = 'parent_left'
37
38 def name_get(self, cr, uid, ids, context=None):
39 """Show the parent inventory's name in the name of the children
40
41 :param dict context: the ``inventory_display`` key can be
42 used to select the short version of the
43 inventory name (without the direct parent),
44 when set to ``'short'``. The default is
45 the long version."""
46 if context is None:
47 context = {}
48 if context.get('inventory_display') == 'short':
49 # Short name context: just do the usual stuff
50 return super(HierarchicalInventory, self).name_get(
51 cr, uid, ids, context=context)
52 if isinstance(ids, (list, tuple)) and not len(ids):
53 return []
54 if isinstance(ids, (long, int)):
55 ids = [ids]
56 reads = self.read(cr, uid, ids, ['name', 'parent_id'], context=context)
57 res = []
58 for record in reads:
59 name = record['name']
60 if record['parent_id']:
61 name = record['parent_id'][1] + ' / ' + name
62 res.append((record['id'], name))
63 return res
64
65 def name_search(self, cr, uid, name='', args=None, operator='ilike',
66 context=None, limit=100):
67 """Enable search on value returned by name_get ("parent / child")"""
68 if not args:
69 args = []
70 if not context:
71 context = {}
72 if name:
73 # Make sure name_search is symmetric to name_get
74 name = name.split(' / ')[-1]
75 ids = self.search(cr, uid, [('name', operator, name)] + args,
76 limit=limit, context=context)
77 else:
78 ids = self.search(cr, uid, args, limit=limit, context=context)
79 return self.name_get(cr, uid, ids, context=context)
80
81 def _complete_name(self, cr, uid, ids, field_name, arg, context=None):
82 """Function-field wrapper to get the complete name from name_get"""
83 res = self.name_get(cr, uid, ids, context=context)
84 return dict(res)
85
86 def _progress_rate(self, cr, uid, ids, field_name, arg, context=None):
87 """Rate of (sub)inventories done/total"""
88 rates = {}
89 for current_id in ids:
90 nb = self.search(
91 cr, uid, [('parent_id', 'child_of', current_id)],
92 context=context, count=True)
93 if not nb:
94 # No inventory, consider it's 0% done
95 rates[current_id] = 0
96 continue
97 nb_done = self.search(
98 cr, uid, [('parent_id', 'child_of', current_id),
99 ('state', '=', 'done')],
100 context=context, count=True)
101 rates[current_id] = 100 * nb_done / nb
102 return rates
103
104 _columns = {
105 # name_get() only changes the default name of the record, not the
106 # content of the field "name" so we add another field for that
107 'complete_name': fields.function(
108 _complete_name, type="char",
109 string='Complete reference'),
110 'parent_id': fields.many2one(
111 'stock.inventory', 'Parent', ondelete='cascade', readonly=True,
112 states={'draft': [('readonly', False)]}),
113 'inventory_ids': fields.one2many(
114 'stock.inventory', 'parent_id', 'List of Sub-inventories',
115 readonly=True, states={'draft': [('readonly', False)]}),
116 'parent_left': fields.integer('Parent Left', select=1),
117 'parent_right': fields.integer('Parent Right', select=1),
118 'progress_rate': fields.function(
119 _progress_rate, string='Progress', type='float'),
120 }
121
122 _constraints = [
123 (orm.Model._check_recursion,
124 'Error: You can not create recursive inventories.',
125 ['parent_id']),
126 ]
127
128 def create(self, cr, uid, vals, context=None):
129 """Copy selected values from parent to child"""
130 if vals and vals.get('parent_id'):
131 existing_fields = self.fields_get_keys(cr, uid, context=context)
132 parent_values = self.read(cr, uid, [vals['parent_id']],
133 PARENT_VALUES, context=context)
134 vals = vals.copy()
135 vals.update({field: parent_values[0][field]
136 for field in PARENT_VALUES
137 if field in existing_fields})
138 return super(HierarchicalInventory, self).create(
139 cr, uid, vals, context=context)
140
141 def write(self, cr, uid, ids, vals, context=None):
142 """Copy selected values from parent to children"""
143 if context is None:
144 context = {}
145
146 values = super(HierarchicalInventory, self).write(
147 cr, uid, ids, vals, context=context)
148 if not vals or context.get('norecurse', False):
149 return values
150
151 # filter the fields we want to propagate
152 children_values = {
153 field: vals[field] for field in PARENT_VALUES if field in vals
154 }
155 if not children_values:
156 return values
157
158 if not isinstance(ids, list):
159 ids = [ids]
160 # The context disables recursion - children are already included
161 return self.write(
162 cr, uid, self.search(cr, uid, [('parent_id', 'child_of', ids)]),
163 children_values, context=dict(context, norecurse=True))
164
165 def action_cancel_inventory(self, cr, uid, ids, context=None):
166 """Cancel inventory only if all the parents are canceled"""
167 inventories = self.browse(cr, uid, ids, context=context)
168 for inventory in inventories:
169 while inventory.parent_id:
170 inventory = inventory.parent_id
171 if inventory.state != 'cancel':
172 raise HierarchicalInventoryException(
173 _('Warning'),
174 _('One of the parent Inventories is not canceled.'))
175 return super(HierarchicalInventory,
176 self).action_cancel_inventory(cr, uid, ids,
177 context=context)
178
179 def action_confirm(self, cr, uid, ids, context=None):
180 """Confirm inventory only if all the children are confirmed"""
181 children_count = self.search(
182 cr, uid, [('parent_id', 'child_of', ids),
183 ('state', 'not in', ['confirm', 'done'])],
184 context=context, count=True)
185 if children_count > 1:
186 raise HierarchicalInventoryException(
187 _('Warning'),
188 _('Some Sub-inventories are not confirmed.'))
189 return super(HierarchicalInventory, self).action_confirm(
190 cr, uid, ids, context=context)
191
192 def action_done(self, cr, uid, ids, context=None):
193 """Perform validation only if all the children states are 'done'."""
194 children_count = self.search(cr, uid, [('parent_id', 'child_of', ids),
195 ('state', '!=', 'done')],
196 context=context, count=True)
197 if children_count > 1:
198 raise HierarchicalInventoryException(
199 _('Warning'),
200 _('Some Sub-inventories are not validated.'))
201 return super(HierarchicalInventory, self).action_done(
202 cr, uid, ids, context=context)
0203
=== added file 'stock_inventory_hierarchical/hierarchical_inventory_demo.xml'
--- stock_inventory_hierarchical/hierarchical_inventory_demo.xml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/hierarchical_inventory_demo.xml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="0">
4 <!-- Example Inventory with Sub-Inventories. -->
5 <record id="stock_inventory_parent0" model="stock.inventory">
6 <field name="name">Main Inventory</field>
7 </record>
8 <record id="child_1_id" model="stock.inventory">
9 <field name="name">Sub-Inventory 1</field>
10 <field name="parent_id" ref="stock_inventory_parent0" />
11 </record>
12 <record id="child_2_id" model="stock.inventory">
13 <field name="name">Sub-Inventory 2</field>
14 <field name="parent_id" ref="stock_inventory_parent0" />
15 </record>
16 </data>
17</openerp>
018
=== added file 'stock_inventory_hierarchical/hierarchical_inventory_view.xml'
--- stock_inventory_hierarchical/hierarchical_inventory_view.xml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/hierarchical_inventory_view.xml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,78 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <!-- Add parent_id and number of Sub-inventories to form view -->
5 <record model="ir.ui.view" id="stock_inventory_hierarchical_tree_view">
6 <field name="name">hierarchical.inventory.tree</field>
7 <field name="model">stock.inventory</field>
8 <field name="inherit_id" ref="stock.view_inventory_tree" />
9 <field name="field_parent">inventory_ids</field>
10 <field name="arch" type="xml">
11 <xpath expr="//field[@name='name']" position="replace">
12 <field name="complete_name" string="Reference"/>
13 </xpath>
14 <xpath expr="//field[@name='state']" position="after">
15 <field name="progress_rate" widget="progressbar" />
16 </xpath>
17 </field>
18 </record>
19
20 <!-- Add the parent_id filter to search view -->
21 <record model="ir.ui.view" id="view_inventory_subinventories_filter">
22 <field name="name">hierarchical.inventory.filter</field>
23 <field name="model">stock.inventory</field>
24 <field name="inherit_id" ref="stock.view_inventory_filter" />
25 <field name="arch" type="xml">
26 <xpath expr="//field[@name='name']" position="before">
27 <filter icon="terp-check" name="main_inventories" string="Main inventories" domain="[('parent_id', '=', False)]" help="Only select inventories that have no parents." />
28 <separator orientation="vertical"/>
29 </xpath>
30 <xpath expr="//field[@name='date']" position="after">
31 <field name="parent_id" />
32 </xpath>
33 </field>
34 </record>
35 <!-- Show main inventories by default -->
36 <record id="stock.action_inventory_form" model="ir.actions.act_window">
37 <field name="context">{'full':'1', 'search_default_main_inventories':1}</field>
38 </record>
39
40 <record model="ir.ui.view" id="stock_inventory_hierarchical_form_view">
41 <field name="name">hierarchical.inventory.form</field>
42 <field name="model">stock.inventory</field>
43 <field name="inherit_id" ref="stock.view_inventory_form" />
44 <field name="arch" type="xml">
45 <xpath expr="/form//field[@name='name']" position="after">
46 <field name="parent_id"/>
47 </xpath>
48 <xpath expr="/form//field[@name='date']" position="attributes">
49 <attribute name="attrs">{'readonly':[('parent_id', '!=', False)]}</attribute>
50 </xpath>
51 <xpath
52 expr="//page[@string='General Information']"
53 position="after">
54 <page string="Sub-inventories">
55 <field name="inventory_ids" nolabel="1" context="{'default_parent_id': active_id}">
56 <tree>
57 <field name="name" />
58 <field name="state" />
59 <field name="progress_rate" widget="progressbar" />
60 </tree>
61 </field>
62 </page>
63 </xpath>
64 </field>
65 </record>
66
67 <!-- Open the children of the current Inventory in a distinct list
68 to let users work in a normal window instead of a popup -->
69 <act_window id="action_view_sub_inventory"
70 name="View Sub-inventories"
71 res_model="stock.inventory"
72 src_model="stock.inventory"
73 view_mode="tree,form"
74 view_type="form"
75 domain="[('parent_id', 'child_of', active_id),('id', '!=', active_id)]"
76 context="{'full':1, 'search_default_main_inventories':0}"/>
77 </data>
78</openerp>
079
=== added directory 'stock_inventory_hierarchical/i18n'
=== added file 'stock_inventory_hierarchical/i18n/fr.po'
--- stock_inventory_hierarchical/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/i18n/fr.po 2014-06-16 10:01:17 +0000
@@ -0,0 +1,112 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * stock_inventory_hierarchical
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 6.0.4\n"
8"Report-Msgid-Bugs-To: support@openerp.com\n"
9"POT-Creation-Date: 2013-09-25 13:43+0000\n"
10"PO-Revision-Date: 2013-09-25 13:43+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: stock_inventory_hierarchical
19#: field:stock.inventory,complete_name:0
20msgid "Complete reference"
21msgstr "Réference complète"
22
23#. module: stock_inventory_hierarchical
24#: field:stock.inventory,progress_rate:0
25msgid "Done"
26msgstr "Terminé"
27
28#. module: stock_inventory_hierarchical
29#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:108
30#: constraint:stock.inventory:0
31#, python-format
32msgid "Error: You can not create recursive inventories."
33msgstr "Erreur : Vous ne pouvez pas créer d'inventaire récursifs."
34
35#. module: stock_inventory_hierarchical
36#: model:ir.model,name:stock_inventory_hierarchical.model_stock_inventory
37msgid "Gestion des stocks"
38msgstr "Gestion des stocks"
39
40#. module: stock_inventory_hierarchical
41#: field:stock.inventory,inventory_ids:0
42msgid "List of Sub-inventories"
43msgstr "Liste des sous-inventaires"
44
45#. module: stock_inventory_hierarchical
46#: view:stock.inventory:0
47msgid "Main inventories"
48msgstr "Inventaires principaux"
49
50#. module: stock_inventory_hierarchical
51#: view:stock.inventory:0
52msgid "Number of Sub-inventories"
53msgstr "Nombre de sous-inventaires"
54
55#. module: stock_inventory_hierarchical
56#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:180
57#, python-format
58msgid "One of the parent Inventories is not canceled."
59msgstr "Un des inventaires pères n'est pas annulé."
60
61#. module: stock_inventory_hierarchical
62#: constraint:stock.inventory:0
63msgid "Other Physical inventories are being conducted using the same Locations."
64msgstr "Certains emplacements sont déjà dans un autre inventaire."
65
66#. module: stock_inventory_hierarchical
67#: field:stock.inventory,parent_id:0
68msgid "Parent"
69msgstr "Parent"
70
71#. module: stock_inventory_hierarchical
72#: field:stock.inventory,parent_left:0
73msgid "Parent Left"
74msgstr "Parent gauche"
75
76#. module: stock_inventory_hierarchical
77#: field:stock.inventory,parent_right:0
78msgid "Parent Right"
79msgstr "Parent droit"
80
81#. module: stock_inventory_hierarchical
82#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:188
83#, python-format
84msgid "Some Sub-inventories are not confirmed."
85msgstr "Certains sous-inventaires ne sont pas confirmés."
86
87#. module: stock_inventory_hierarchical
88#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:196
89#, python-format
90msgid "Some Sub-inventories are not validated."
91msgstr "Certains sous-inventaires ne sont pas terminés."
92
93#. module: stock_inventory_hierarchical
94#: model:ir.actions.act_window,name:stock_inventory_hierarchical.action_view_sub_inventory
95#: view:stock.inventory:0
96msgid "View Sub-inventories"
97msgstr "Voir les sous-inventaires"
98
99#. module: stock_inventory_hierarchical
100#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:130
101#, python-format
102msgid "Sub-inventory: %s"
103msgstr "Sous-inventaire : %s"
104
105#. module: stock_inventory_hierarchical
106#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:180
107#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:188
108#: code:addons/stock_inventory_hierarchical/hierarchical_inventory.py:196
109#, python-format
110msgid "Warning"
111msgstr "Attention"
112
0113
=== added directory 'stock_inventory_hierarchical/images'
=== added file 'stock_inventory_hierarchical/images/inventory_form.png'
1Binary 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 differ114Binary 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
=== added file 'stock_inventory_hierarchical/images/inventory_form_actions.png'
2Binary 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 differ115Binary 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
=== added directory 'stock_inventory_hierarchical/static'
=== added directory 'stock_inventory_hierarchical/static/src'
=== added directory 'stock_inventory_hierarchical/static/src/img'
=== added file 'stock_inventory_hierarchical/static/src/img/icon.png'
3Binary 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 differ116Binary 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
=== added directory 'stock_inventory_hierarchical/test'
=== added file 'stock_inventory_hierarchical/test/hierarchical_inventory_test.yml'
--- stock_inventory_hierarchical/test/hierarchical_inventory_test.yml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical/test/hierarchical_inventory_test.yml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,96 @@
1-
2 In this file, i check rules about hierarchical inventories.
3 Children date must be the same of parent date for each state,
4 the state of parent and children can change only if conditions are correct.
5-
6 Check if date of children are the same as the parent's.
7-
8 !python {model: stock.inventory}: |
9 parent_date = self.read(
10 cr, uid, [ref('stock_inventory_parent0')], ['date'])[0]['date']
11 child_1_date = self.read(
12 cr, uid, [ref('child_1_id')], ['date'])[0]['date']
13 assert child_1_date == parent_date, "Date are different: %s - %s" % (parent_date, child_1_date)
14
15 child_2_date = self.read(
16 cr, uid, [ref('child_2_id')], ['date'])[0]['date']
17 assert child_2_date == parent_date, "Date are different: %s - %s" % (parent_date, child_2_date)
18
19-
20 Check if children cannot be canceled if the parent was not canceled.
21 I'll try to cancel both children inventory while parent inventory having "draft" state.
22 After, i'll verify the state of each inventory.
23-
24 !python {model: stock.inventory}: |
25 from stock_inventory_hierarchical import HierarchicalInventoryException
26 try:
27 self.action_cancel_inventory(cr, uid, [ref('child_1_id')])
28 except HierarchicalInventoryException as e:
29 log("Good ! The Inventory could not be canceled: %s" % e)
30 try:
31 self.action_cancel_inventory(cr, uid, [ref('child_2_id')])
32 except HierarchicalInventoryException as e:
33 log("Good ! The Inventory could not be canceled: %s" % e)
34 child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
35 assert child_1_state == 'draft', "Child inventory 1 have '%s' state. It should be 'draft'" % child_1_state
36 child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
37 assert child_2_state == 'draft', "Child inventory 2 have '%s' state. It should be 'draft'" % child_2_state
38
39-
40 Check if children inventory have confirm state before confirm parent inventory.
41 To check this, i'll try to confirm parent inventory when children inventory having "draft" state,
42 and i'll check if state is still 'draft'.
43-
44 !python {model: stock.inventory}: |
45 from stock_inventory_hierarchical import HierarchicalInventoryException
46 try:
47 self.action_confirm(cr, uid, [ref('stock_inventory_parent0')])
48 except HierarchicalInventoryException as e:
49 log("Good, the inventory could not be confirmed: %s", e)
50 parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
51 assert parent_state == 'draft', "Parent inventory have '%s' state. It should be 'draft'" % parent_state
52
53-
54 In order, i'll confirm the children inventories, and the parent inventory after.
55-
56 !python {model: stock.inventory}: |
57 self.action_confirm(cr, uid, [ref('child_1_id')])
58 child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
59 assert child_1_state == 'confirm', "Child inventory 1 have '%s' state. It should be 'confirm'" % child_1_state
60
61 self.action_confirm(cr, uid, [ref('child_2_id')])
62 child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
63 assert child_2_state == 'confirm', "Child inventory 2 have '%s' state. It should be 'confirm'" % child_2_state
64
65 self.action_confirm(cr, uid, [ref('stock_inventory_parent0')])
66 parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
67 assert parent_state == 'confirm', "Parent inventory have '%s' state. It should be 'confirm'" % parent_state
68
69-
70 Check if children inventory have done state before validate parent inventory.
71 I'll try to validate parent inventory before children.
72-
73 !python {model: stock.inventory}: |
74 from stock_inventory_hierarchical import HierarchicalInventoryException
75 try:
76 self.action_done(cr, uid, [ref('stock_inventory_parent0')])
77 except HierarchicalInventoryException as e:
78 log("Good, the inventory could not be validated: %s", e)
79 parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
80 assert parent_state == 'confirm', "Parent inventory have '%s' state. It should be 'confirm'" % parent_state
81
82-
83 Now, i'll validate all children inventory before validate the parent.
84-
85 !python {model: stock.inventory}: |
86 self.action_done(cr, uid, [ref('child_1_id')])
87 child_1_state = self.read(cr, uid, [ref('child_1_id')], ['state'])[0]['state']
88 assert child_1_state == 'done', "Child inventory 1 have '%s' state. It should be 'done'" % child_1_state
89
90 self.action_done(cr, uid, [ref('child_2_id')])
91 child_2_state = self.read(cr, uid, [ref('child_2_id')], ['state'])[0]['state']
92 assert child_2_state == 'done', "Child inventory 2 have '%s' state. It should be 'done'" % child_2_state
93
94 self.action_done(cr, uid, [ref('stock_inventory_parent0')])
95 parent_state = self.read(cr, uid, [ref('stock_inventory_parent0')], ['state'])[0]['state']
96 assert parent_state == 'done', "Parent inventory have '%s' state. It should be 'done'" % parent_state
097
=== added directory 'stock_inventory_hierarchical_location'
=== added file 'stock_inventory_hierarchical_location/__init__.py'
--- stock_inventory_hierarchical_location/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/__init__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,22 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21from . import inventory_hierarchical_location
22from . import wizard
023
=== added file 'stock_inventory_hierarchical_location/__openerp__.py'
--- stock_inventory_hierarchical_location/__openerp__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/__openerp__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,48 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21{
22 "name": "Exhaustive and hierarchical Stock Inventories",
23 "version": "1.1",
24 "depends": ["stock_inventory_hierarchical", "stock_inventory_location"],
25 "auto_install": True,
26 "author": u"Numérigraphe",
27 "category": "Hidden",
28 "description": """
29Make exhaustive Inventories aware of their Sub-Inventories.
30===========================================================
31
32This module allows an inventory to contain a general Location,
33and it's sub-inventories to contain some of it's sub-Locations.
34It will prevent you from setting the Inventories and sub-Inventories
35in inconsistent status.
36
37This module will be installed automatically if the modules
38"stock_inventory_location" and "stock_inventory_hierarchical" are both
39installed.
40You must keep this module installed to ensure proper functioning.
41
42 """,
43 "data": [
44 "inventory_hierarchical_location_view.xml",
45 ],
46 "test": ["tests/inventory_hierarchical_location_test.yml"],
47 "demo": ["inventory_hierarchical_location_demo.xml"],
48}
049
=== added directory 'stock_inventory_hierarchical_location/i18n'
=== added file 'stock_inventory_hierarchical_location/i18n/fr.po'
--- stock_inventory_hierarchical_location/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/i18n/fr.po 2014-06-16 10:01:17 +0000
@@ -0,0 +1,127 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * stock_inventory_hierarchical_location
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 6.0.4\n"
8"Report-Msgid-Bugs-To: support@openerp.com\n"
9"POT-Creation-Date: 2013-09-25 13:55+0000\n"
10"PO-Revision-Date: 2013-09-25 13:55+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: stock_inventory_hierarchical_location
19#: model:ir.actions.act_window,name:stock_inventory_hierarchical_location.action_view_stock_inventory_missing_location
20msgid "Confirm missing location"
21msgstr "Confirmer les emplacements manquants"
22
23#. module: stock_inventory_hierarchical_location
24#: view:stock.inventory.missing.location:0
25msgid "Confirm missing locations"
26msgstr "Confirmer les emplacements manquants"
27
28#. module: stock_inventory_hierarchical_location
29#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory_uninventoried_locations
30msgid "Confirm the uninventoried Locations."
31msgstr "Confirmer les emplacements non inventoriés."
32
33#. module: stock_inventory_hierarchical_location
34#: view:stock.inventory.missing.location:0
35msgid "Do you want to continue ?"
36msgstr "Voulez-vous continuer ?"
37
38#. module: stock_inventory_hierarchical_location
39#: constraint:stock.inventory:0
40msgid "Error! You can not create recursive inventories."
41msgstr "Erreur! Vous ne pouvez pas créer un inventaire récursif."
42
43#. module: stock_inventory_hierarchical_location
44#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory
45msgid "Gestion des stocks"
46msgstr "Gestion des stocks"
47
48#. module: stock_inventory_hierarchical_location
49#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:70
50#, python-format
51msgid "Location missing for inventory \"%s\"."
52msgstr "Emplacement manquants dans l'inventaire \"%s\"."
53
54#. module: stock_inventory_hierarchical_location
55#: view:stock.inventory:0
56msgid "Locations"
57msgstr "Emplacements"
58
59#. module: stock_inventory_hierarchical_location
60#: field:stock.inventory.missing.location,location_ids:0
61msgid "Missing location"
62msgstr "Emplacements manquants"
63
64#. module: stock_inventory_hierarchical_location
65#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:41
66#, python-format
67msgid "One of the parent inventories is not open."
68msgstr "Un des inventaire parent n'est pas ouvert."
69
70#. module: stock_inventory_hierarchical_location
71#: view:stock.inventory:0
72msgid "Open Inventory"
73msgstr "Ouvrir l'inventaire"
74
75#. module: stock_inventory_hierarchical_location
76#: constraint:stock.inventory:0
77msgid "Other Physical inventories are being conducted using the same Locations."
78msgstr "Erreur: certains emplacements sont déjà dans un autre inventaire."
79
80#. module: stock_inventory_hierarchical_location
81#: model:ir.model,name:stock_inventory_hierarchical_location.model_stock_inventory_missing_location
82msgid "Search on inventory tree for missing declared locations."
83msgstr "Recherche dans les inventaires les emplacements absents."
84
85#. module: stock_inventory_hierarchical_location
86#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:122
87#, python-format
88msgid "Some Sub-inventories are not confirmed."
89msgstr "Au moins un sous-inventaire n'est pas confirmé."
90
91#. module: stock_inventory_hierarchical_location
92#: view:stock.inventory.missing.location:0
93msgid "This is the list of missing locations."
94msgstr "Voici la liste des emplacements manquants."
95
96#. module: stock_inventory_hierarchical_location
97#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:58
98#, python-format
99msgid "This location is not declared on the parent inventory\n"
100"It cannot be added."
101msgstr "Cet emplacement n'est pas déclaré dans l'inventaire parent\n"
102"Vous ne pouvez pas l'ajouter."
103
104#. module: stock_inventory_hierarchical_location
105#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:41
106#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:70
107#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:122
108#, python-format
109msgid "Warning !"
110msgstr "Attention !"
111
112#. module: stock_inventory_hierarchical_location
113#: code:addons/stock_inventory_hierarchical_location/inventory_hierarchical_location.py:57
114#, python-format
115msgid "Warning: Wrong location"
116msgstr "Attention: mauvais emplacement"
117
118#. module: stock_inventory_hierarchical_location
119#: view:stock.inventory.missing.location:0
120msgid "_Cancel"
121msgstr "_Annuler"
122
123#. module: stock_inventory_hierarchical_location
124#: view:stock.inventory.missing.location:0
125msgid "_Confirm missing locations"
126msgstr "_Confirmer les emplacements manquants"
127
0128
=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location.py'
--- stock_inventory_hierarchical_location/inventory_hierarchical_location.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/inventory_hierarchical_location.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,88 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21from openerp.osv import orm
22from openerp.tools.translate import _
23
24from stock_inventory_hierarchical import HierarchicalInventoryException
25
26# Add the date to the list of fields we must propagate to children inventories
27from stock_inventory_hierarchical import PARENT_VALUES
28PARENT_VALUES.append('exhaustive')
29
30
31class HierarchicalExhInventory(orm.Model):
32 """Add hierarchical structure features to exhaustive Inventories"""
33 _inherit = 'stock.inventory'
34
35 def action_open(self, cr, uid, ids, context=None):
36 """Open only if all the parents are Open."""
37 for inventory in self.browse(cr, uid, ids, context=context):
38 while inventory.parent_id:
39 inventory = inventory.parent_id
40 if inventory.state != 'open':
41 raise HierarchicalInventoryException(
42 _('Warning'),
43 _('One of the parent inventories is not open.'))
44 return super(HierarchicalExhInventory, self).action_open(
45 cr, uid, ids, context=context)
46
47 def get_missing_locations(self, cr, uid, ids, context=None):
48 """Extend the list of inventories with their children"""
49 ids = self.search(
50 cr, uid, [('parent_id', 'child_of', ids)], context=context)
51 return super(HierarchicalExhInventory, self).get_missing_locations(
52 cr, uid, ids, context=context)
53
54 # TODO v8: probably only keep the state "done"
55 def confirm_missing_locations(self, cr, uid, ids, context=None):
56 """Do something only if children state are confirm or done."""
57 children_count = self.search(
58 cr, uid, [('parent_id', 'child_of', ids),
59 ('id', 'not in', ids),
60 ('state', 'not in', ['confirm', 'done'])],
61 context=context, count=True)
62 if children_count > 0:
63 raise HierarchicalInventoryException(
64 _('Warning'),
65 _('Some Sub-inventories are not confirmed.'))
66 return super(HierarchicalExhInventory,
67 self).confirm_missing_locations(
68 cr, uid, ids, context=context)
69
70 def onchange_location_id(self, cr, uid, ids, location_id, context=None):
71 """Check if location is a child of parent inventory location"""
72 loc_obj = self.pool['stock.location']
73 for inventory in self.browse(cr, uid, ids, context=context):
74 if inventory.parent_id:
75 allowed_location_ids = loc_obj.search(
76 cr, uid, [('location_id', 'child_of',
77 inventory.parent_id.location_id.id)],
78 context=context)
79 if location_id not in allowed_location_ids:
80 return {
81 'location_id': False,
82 'warning': {
83 'title': _('Warning: Wrong location'),
84 'message': _("This location is not declared on "
85 "the parent inventory\n"
86 "It cannot be added.")}
87 }
88 return {}
089
=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml'
--- stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="0">
4
5 <!-- Record inventories we can use in the tests. -->
6 <!-- We need them in the demo data because test data is rolled back
7 whenever an exception is raised. -->
8
9 <!-- Record a hierarchical exhaustive inventory -->
10 <record id="parent_inventory" model="stock.inventory">
11 <field name="name">Hierarchical exhaustive inventory</field>
12 <field name="state">draft</field>
13 <field name="date">2020-04-15 00:00:00</field>
14 <field name="exhaustive">True</field>
15 <field name="location_id" model="stock.location" ref="stock.stock_location_stock"/>
16 </record>
17 <record id="child_1_id" model="stock.inventory">
18 <field name="name">Team A</field>
19 <field name="parent_id" ref="parent_inventory"/>
20 <field name="location_id" model="stock.location" ref="stock.stock_location_14"/>
21 </record>
22 <record id="child_2_id" model="stock.inventory">
23 <field name="name">Team B</field>
24 <field name="parent_id" ref="parent_inventory"/>
25 <field name="location_id" model="stock.location" ref="stock.stock_location_components"/>
26 </record>
27 </data>
28</openerp>
029
=== added file 'stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml'
--- stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/inventory_hierarchical_location_view.xml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,37 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record model="ir.ui.view" id="stock_inventory_hierarchical_location_form_view">
5 <field name="name">hierarchical.inventory.location.form</field>
6 <field name="model">stock.inventory</field>
7 <field name="inherit_id" ref="stock.view_inventory_form" />
8 <field name="arch" type="xml">
9
10 <xpath expr="/form//field[@name='exhaustive']" position="attributes">
11 <attribute name="attrs">{'readonly':[('parent_id', '!=', False)]}</attribute>
12 </xpath>
13
14 <xpath expr="/form//field[@name='location_id']" position="attributes">
15 <attribute name="on_change">onchange_location_id(location_id)</attribute>
16 </xpath>
17
18 </field>
19 </record>
20
21 <record model="ir.ui.view" id="stock_ihl_exhautive_form_view">
22 <field name="name">hierarchical.inventory.location.exhautive.form</field>
23 <field name="model">stock.inventory</field>
24 <field name="inherit_id" ref="stock_inventory_hierarchical.stock_inventory_hierarchical_form_view" />
25 <field name="arch" type="xml">
26 <xpath expr="//field[@name='inventory_ids']" position="attributes">
27 <attribute name="context">{'default_parent_id': active_id, 'default_exhaustive': exhaustive}</attribute>
28 </xpath>
29 </field>
30 </record>
31
32 <!-- Show hierarchical exhaustive inventories by default -->
33 <record id="stock.action_inventory_form" model="ir.actions.act_window">
34 <field name="context">{'full':'1', 'search_default_exhaustive':1, 'search_default_main_inventories':1}</field>
35 </record>
36 </data>
37</openerp>
038
=== added directory 'stock_inventory_hierarchical_location/static'
=== added directory 'stock_inventory_hierarchical_location/static/src'
=== added directory 'stock_inventory_hierarchical_location/static/src/img'
=== added file 'stock_inventory_hierarchical_location/static/src/img/icon.png'
1Binary 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 differ39Binary 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
=== added directory 'stock_inventory_hierarchical_location/tests'
=== added file 'stock_inventory_hierarchical_location/tests/__init__.py'
--- stock_inventory_hierarchical_location/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/tests/__init__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,39 @@
1# -*- coding: utf-8 -*-
2#
3#
4# Authors: Laetitia Gangloff
5# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
6# All Rights Reserved
7#
8# WARNING: This program as such is intended to be used by professional
9# programmers who take the whole responsibility of assessing all potential
10# consequences resulting from its eventual inadequacies and bugs.
11# End users who are looking for a ready-to-use solution with commercial
12# guarantees and support are strongly advised to contact a Free Software
13# Service Company.
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU Affero General Public License as
17# published by the Free Software Foundation, either version 3 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU Affero General Public License for more details.
24#
25# You should have received a copy of the GNU Affero General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28#
29
30import fill_inventory_test
31
32fast_suite = [
33]
34
35checks = [
36 fill_inventory_test,
37]
38
39# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
040
=== added file 'stock_inventory_hierarchical_location/tests/fill_inventory_test.py'
--- stock_inventory_hierarchical_location/tests/fill_inventory_test.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/tests/fill_inventory_test.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,118 @@
1# -*- coding: utf-8 -*-
2#
3#
4# Authors: Laetitia Gangloff
5# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
6# All Rights Reserved
7#
8# WARNING: This program as such is intended to be used by professional
9# programmers who take the whole responsibility of assessing all potential
10# consequences resulting from its eventual inadequacies and bugs.
11# End users who are looking for a ready-to-use solution with commercial
12# guarantees and support are strongly advised to contact a Free Software
13# Service Company.
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU Affero General Public License as
17# published by the Free Software Foundation, either version 3 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU Affero General Public License for more details.
24#
25# You should have received a copy of the GNU Affero General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28#
29
30import openerp.tests.common as common
31
32DB = common.DB
33ADMIN_USER_ID = common.ADMIN_USER_ID
34
35
36class fill_inventory_test(common.TransactionCase):
37
38 def setUp(self):
39 super(fill_inventory_test, self).setUp()
40
41 def test_missing_location(self):
42 """
43 Test that when confirm a parent inventory, the child location are not in the confirmation result
44 """
45 parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory')
46 self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id])
47 # confirm shelf 1 inventory
48 inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id')
49 self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
50 missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
51 self.assertEqual(len(missing_location), 1, "1 missing location should be find, because the inventory is empty")
52 wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]})
53 self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
54 missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
55 self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is confirmed")
56 # confirm shelf 2 inventory
57 inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id')
58 self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
59 missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
60 self.assertEqual(len(missing_location), 1, "1 missing location should be fine, because the inventory is empty")
61 self.registry('stock.inventory.line').create(self.cr, self.uid, {'product_id': self.ref('product.product_product_7'),
62 'product_uom': self.ref('product.product_uom_unit'),
63 'company_id': self.ref('base.main_company'),
64 'inventory_id': inventory_id,
65 'product_qty': 18.0,
66 'location_id': self.ref('stock.stock_location_14')})
67 missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id])
68 self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is filled")
69 wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]})
70 wizard = self.registry('stock.inventory.uninventoried.locations').browse(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
71 self.assertEqual(len(wizard.location_ids), 0, "The wizard should not contain any lines but contains %s." % wizard.location_ids)
72 self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]})
73 # confirm parent inventory
74 missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [parent_inventory_id])
75 self.assertEqual(len(missing_location), 1, "Only 1 missing location should be find, because there is some location in child inventory")
76
77 def test_fill_inventory(self):
78 """
79 Test that when fill a parent inventory, the child location are not in the result
80 """
81 parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory')
82 self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id])
83 # confirm shelf 1 inventory
84 inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id')
85 self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
86 wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_components'),
87 'recursive': True,
88 'exhaustive': True,
89 'set_stock_zero': True}, context={'active_ids': [inventory_id]})
90 self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]})
91 inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)])
92 self.assertEqual(len(inventory_line_ids), 12, "12 inventory line is fount after filling inventory")
93 # confirm shelf 2 inventory
94 inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id')
95 self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id])
96 wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_14'),
97 'recursive': True,
98 'exhaustive': True,
99 'set_stock_zero': True}, context={'active_ids': [inventory_id]})
100 self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]})
101 inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)])
102 self.assertEqual(len(inventory_line_ids), 4, "1 inventory line is fount after filling inventory")
103 # confirm parent inventory
104 wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_stock'),
105 'recursive': True,
106 'exhaustive': True,
107 'set_stock_zero': True}, context={'active_ids': [parent_inventory_id]})
108 try:
109 self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [parent_inventory_id]})
110 except Exception, e:
111 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.''")
112 exception_happened = True
113 pass
114 self.assertTrue(exception_happened)
115 inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', parent_inventory_id)])
116 self.assertEqual(len(inventory_line_ids), 0, "No inventory line is fount after filling inventory")
117
118# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0119
=== added file 'stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml'
--- stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/tests/inventory_hierarchical_location_test.yml 2014-06-16 10:01:17 +0000
@@ -0,0 +1,56 @@
1-
2 Check that the exhaustive field of parent inventory has been propagated to children.
3-
4 !python {model: stock.inventory}: |
5 exhaustive = self.read(cr, uid, [ref("child_1_id")], ['exhaustive'])[0]['exhaustive']
6 assert exhaustive, "Exhaustive field not propagated to child inventory"
7
8-
9 Check that I can't open child inventory while parent inventory is open.
10-
11 !python {model: stock.inventory}: |
12 from stock_inventory_hierarchical import HierarchicalInventoryException
13 parent_state = self.read(cr, uid, [ref("parent_inventory")], ['state'])[0]['state']
14 assert parent_state == 'draft', "Parent inventory in state '%s'. It should be 'draft'" % parent_state
15 try:
16 self.action_open(cr, uid, [ref("child_1_id")])
17 except HierarchicalInventoryException as e:
18 log("Good ! The Inventory could not be opened: %s" % e)
19 child_1_state = self.read(cr, uid, [ref("child_1_id")], ['state'])[0]['state']
20 assert child_1_state == 'draft', "Child inventory 1 have '%s' state. It should be 'draft'" % child_1_state
21
22-
23 I will check that the function get_missing_locations return some locations.
24-
25 !python {model: stock.inventory}: |
26 missing_loc_ids = self.get_missing_locations(cr, uid, [ref('parent_inventory')], context=context)
27 assert len(missing_loc_ids)==3, "get_missing_locations did not return any ID."
28
29-
30 I will fill the inventory and check that the function get_missing_locations return no locations.
31 Adding 17” LCD Monitor.
32-
33 !record {model: stock.inventory.line, id: lines_inventory_location_pc1}:
34 product_id: product.product_product_7
35 product_uom: product.product_uom_unit
36 company_id: base.main_company
37 inventory_id: child_1_id
38 product_qty: 18.0
39 location_id: stock.stock_location_14
40
41-
42 Adding USB Keyboard, QWERTY.
43-
44 !record {model: stock.inventory.line, id: lines_inventory_location_pc3}:
45 product_id: product.product_product_8
46 product_uom: product.product_uom_unit
47 company_id: base.main_company
48 inventory_id: child_2_id
49 product_qty: 5.0
50 location_id: stock.stock_location_components
51
52-
53 !python {model: stock.inventory}: |
54
55 missing_loc_ids = self.get_missing_locations(cr, uid, [ref('parent_inventory')], context=context)
56 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)
057
=== added directory 'stock_inventory_hierarchical_location/wizard'
=== added file 'stock_inventory_hierarchical_location/wizard/__init__.py'
--- stock_inventory_hierarchical_location/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/wizard/__init__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,21 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved.
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19##############################################################################
20
21from . import stock_fill_location_inventory
022
=== added file 'stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py'
--- stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,89 @@
1# -*- coding: utf-8 -*-
2#
3#
4# Authors: Laetitia Gangloff
5# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
6# All Rights Reserved
7#
8# WARNING: This program as such is intended to be used by professional
9# programmers who take the whole responsibility of assessing all potential
10# consequences resulting from its eventual inadequacies and bugs.
11# End users who are looking for a ready-to-use solution with commercial
12# guarantees and support are strongly advised to contact a Free Software
13# Service Company.
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU Affero General Public License as
17# published by the Free Software Foundation, either version 3 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU Affero General Public License for more details.
24#
25# You should have received a copy of the GNU Affero General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28#
29
30from openerp.osv import orm
31from openerp.tools.translate import _
32
33
34class FillInventoryWizard(orm.TransientModel):
35 """If inventory as sub inventories, do not fill with sub inventories location"""
36 _inherit = 'stock.fill.inventory'
37
38 def fill_inventory(self, cr, uid, ids, context=None):
39 """ To Import stock inventory according to products available in the location and not already in a sub inventory
40
41 We split fill_inventory on many fill_inventory (one for each location)
42 @param self: The object pointer.
43 @param cr: A database cursor
44 @param uid: ID of the user currently logged in
45 @param ids: the ID or list of IDs if we want more than one
46 @param context: A standard dictionary
47 @return:
48 """
49 if context is None:
50 context = {}
51
52 if ids and len(ids):
53 ids = ids[0]
54 else:
55 return {'type': 'ir.actions.act_window_close'}
56 fill_inventory = self.browse(cr, uid, ids, context=context)
57 if fill_inventory.recursive and fill_inventory.exhaustive:
58 exclude_location_ids = []
59 for i in self.pool['stock.inventory'].browse(cr, uid, context['active_ids']):
60 for sub_inventory in i.inventory_ids:
61 # exclude these location
62 exclude_location_ids.append(sub_inventory.location_id.id)
63 domain = [('location_id', 'child_of', [fill_inventory.location_id.id])]
64 if exclude_location_ids:
65 domain.append('!')
66 domain.append(('location_id', 'child_of', exclude_location_ids))
67 location_ids = self.pool['stock.location'].search(cr, uid, domain,
68 order="id",
69 context=context)
70 all_in_exception = 0
71 for location_id in location_ids:
72 try:
73 super(FillInventoryWizard, self).fill_inventory(cr, uid,
74 [self.copy(cr, uid, ids, {'location_id': location_id,
75 'recursive': False, }, context=context)],
76 context=context)
77 except Exception, e:
78 if e.value == _('No product in this location. Please select a location in the product form.'):
79 all_in_exception = all_in_exception + 1
80 pass
81 else:
82 raise e
83 if all_in_exception == len(location_ids):
84 raise orm.except_orm(_('Warning!'), _('No product in this location. Please select a location in the product form.'))
85 return {'type': 'ir.actions.act_window_close'}
86 else:
87 return super(FillInventoryWizard, self).fill_inventory(cr, uid, [ids], context=context)
88
89# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
090
=== modified file 'stock_inventory_location/__openerp__.py'
--- stock_inventory_location/__openerp__.py 2014-06-16 10:01:17 +0000
+++ stock_inventory_location/__openerp__.py 2014-06-16 10:01:17 +0000
@@ -62,9 +62,9 @@
62 "wizard/stock_fill_location_inventory_view.xml",62 "wizard/stock_fill_location_inventory_view.xml",
63 ],63 ],
64 "test": [64 "test": [
65 "test/inventory_standard_test.yml",65 "tests/inventory_standard_test.yml",
66 "test/inventory_exhaustive_test.yml",66 "tests/inventory_exhaustive_test.yml",
67 "test/inventory_future_test.yml",67 "tests/inventory_future_test.yml",
68 ],68 ],
69 "images": [69 "images": [
70 "images/inventory_form.png",70 "images/inventory_form.png",
7171
=== modified file 'stock_inventory_location/stock_inventory_location.py'
--- stock_inventory_location/stock_inventory_location.py 2014-06-16 10:01:17 +0000
+++ stock_inventory_location/stock_inventory_location.py 2014-06-16 10:01:17 +0000
@@ -27,6 +27,7 @@
27# TODOv8! remove, feature is included upstream27# TODOv8! remove, feature is included upstream
28from openerp.osv import osv28from openerp.osv import osv
29from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT29from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
30from openerp import SUPERUSER_ID
3031
31from .exceptions import ExhaustiveInventoryException32from .exceptions import ExhaustiveInventoryException
3233
@@ -270,7 +271,7 @@
270 """Error if an exhaustive Inventory is being conducted here"""271 """Error if an exhaustive Inventory is being conducted here"""
271 inv_obj = self.pool['stock.inventory']272 inv_obj = self.pool['stock.inventory']
272 location_inventory_open_ids = inv_obj._get_locations_open_inventories(273 location_inventory_open_ids = inv_obj._get_locations_open_inventories(
273 cr, uid, context=context)274 cr, SUPERUSER_ID, context=context)
274 if not isinstance(ids, Iterable):275 if not isinstance(ids, Iterable):
275 ids = [ids]276 ids = [ids]
276 for inv_id in ids:277 for inv_id in ids:
@@ -286,7 +287,7 @@
286 self._check_inventory(cr, uid, ids, context=context)287 self._check_inventory(cr, uid, ids, context=context)
287 if not isinstance(ids, Iterable):288 if not isinstance(ids, Iterable):
288 ids = [ids]289 ids = [ids]
289 ids_to_check = ids290 ids_to_check = list(ids)
290 # If changing the parent, no inventory must conducted there either291 # If changing the parent, no inventory must conducted there either
291 if vals.get('location_id'):292 if vals.get('location_id'):
292 ids_to_check.append(vals['location_id'])293 ids_to_check.append(vals['location_id'])
@@ -326,7 +327,7 @@
326 message = ""327 message = ""
327 inv_obj = self.pool['stock.inventory']328 inv_obj = self.pool['stock.inventory']
328 locked_location_ids = inv_obj._get_locations_open_inventories(329 locked_location_ids = inv_obj._get_locations_open_inventories(
329 cr, uid, context=context)330 cr, SUPERUSER_ID, context=context)
330 if not locked_location_ids:331 if not locked_location_ids:
331 # Nothing to verify332 # Nothing to verify
332 return True333 return True
333334
=== renamed directory 'stock_inventory_location/test' => 'stock_inventory_location/tests'
=== added file 'stock_inventory_location/tests/__init__.py'
--- stock_inventory_location/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_location/tests/__init__.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,39 @@
1# -*- coding: utf-8 -*-
2#
3#
4# Authors: Laetitia Gangloff
5# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
6# All Rights Reserved
7#
8# WARNING: This program as such is intended to be used by professional
9# programmers who take the whole responsibility of assessing all potential
10# consequences resulting from its eventual inadequacies and bugs.
11# End users who are looking for a ready-to-use solution with commercial
12# guarantees and support are strongly advised to contact a Free Software
13# Service Company.
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU Affero General Public License as
17# published by the Free Software Foundation, either version 3 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU Affero General Public License for more details.
24#
25# You should have received a copy of the GNU Affero General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28#
29
30import stock_inventory_location_test
31
32fast_suite = [
33]
34
35checks = [
36 stock_inventory_location_test,
37]
38
39# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
040
=== added file 'stock_inventory_location/tests/stock_inventory_location_test.py'
--- stock_inventory_location/tests/stock_inventory_location_test.py 1970-01-01 00:00:00 +0000
+++ stock_inventory_location/tests/stock_inventory_location_test.py 2014-06-16 10:01:17 +0000
@@ -0,0 +1,47 @@
1# -*- coding: utf-8 -*-
2#
3#
4# Authors: Laetitia Gangloff
5# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
6# All Rights Reserved
7#
8# WARNING: This program as such is intended to be used by professional
9# programmers who take the whole responsibility of assessing all potential
10# consequences resulting from its eventual inadequacies and bugs.
11# End users who are looking for a ready-to-use solution with commercial
12# guarantees and support are strongly advised to contact a Free Software
13# Service Company.
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU Affero General Public License as
17# published by the Free Software Foundation, either version 3 of the
18# License, or (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU Affero General Public License for more details.
24#
25# You should have received a copy of the GNU Affero General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28#
29
30import openerp.tests.common as common
31
32DB = common.DB
33ADMIN_USER_ID = common.ADMIN_USER_ID
34
35
36class stock_inventory_location_test(common.TransactionCase):
37
38 def setUp(self):
39 super(stock_inventory_location_test, self).setUp()
40
41 def test_update_parent_location(self):
42 """
43 Test the update of the parent of a location (no inventory in progress
44 """
45 self.registry('stock.location').write(self.cr, self.uid, self.ref('stock.stock_location_5'), {'location_id': self.ref('stock.stock_location_4')})
46
47# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: