Merge lp:~acsone-openerp/stock-logistic-warehouse/7.0-inventory-hierarchical-fill2-lga into lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-hierarchical
- 7.0-inventory-hierarchical-fill2-lga
- Merge into 7.0-inventory-hierarchical
Status: | Merged |
---|---|
Approved by: | Loïc Bellier - Numérigraphe |
Approved revision: | 44 |
Merged at revision: | 41 |
Proposed branch: | lp:~acsone-openerp/stock-logistic-warehouse/7.0-inventory-hierarchical-fill2-lga |
Merge into: | lp:~numerigraphe-team/stock-logistic-warehouse/7.0-inventory-hierarchical |
Diff against target: |
493 lines (+363/-18) 12 files modified
stock_inventory_hierarchical_location/__init__.py (+1/-0) stock_inventory_hierarchical_location/__openerp__.py (+1/-1) stock_inventory_hierarchical_location/inventory_hierarchical_location.py (+0/-10) stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml (+1/-1) stock_inventory_hierarchical_location/tests/__init__.py (+39/-0) stock_inventory_hierarchical_location/tests/fill_inventory_test.py (+118/-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:~acsone-openerp/stock-logistic-warehouse/7.0-inventory-hierarchical-fill2-lga |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Loïc Bellier - Numérigraphe | code review, testing | Approve | |
Lionel Sausin - Initiatives/Numérigraphe | has conflicts | Pending | |
Review via email: mp+222984@code.launchpad.net |
This proposal supersedes a proposal from 2014-06-12.
Commit message
Description of the change
I make some change in the module stock_inventory
The goal is to take account of sub-inventories in case of an exhaustive inventory in two case :
-fill inventory
I also correct a little mistake in demo data of this module.
Lionel Sausin - Initiatives/Numérigraphe (ls-initiatives) wrote : Posted in a previous version of this proposal | # |
Lionel Sausin - Initiatives/Numérigraphe (ls-initiatives) : Posted in a previous version of this proposal | # |
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
I redo a branch based on your last version (38).
So this one contains change for fill inventory. The fill inventory, is used when confirm inventory or when click on button.
In case of confirm inventory, the sub-inventory are already confirmed -> no missing lines.
In case of click on button, it is true that we can have some missing lines, but the confirmation, is not possible (sub-inventories are not confirmed). I think it is 'dangerous' if lines are added, because the confirmation on sub-inventory will also add these lines !
Maybe can we prevent this action when sub-inventories are not confirmed ? (like confirm)
- 40. By Laetitia Gangloff (Acsone)
-
stock_inventory
_location : use SUPERUSER for check in stock.location and stock.move
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
I complete this mp, with the user of SUPERUSER for check on stock.location and stock.move.
It is in the module stock_inventory
A user with no access to stock.inventory, have acl error with these check. And record rules can give wrong result.
- 41. By Laetitia Gangloff (Acsone)
-
stock_inventory
_location : avoid recursive write on stock.location
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
I resolve another problem on the write of stock_location.
There is a "RuntimeError: maximum recursion depth exceeded" when change location_id. ids was just assigned in ids_to_check so, when ids_to_check change, ids change too and the write is not done with right parameter.
- 42. By Laetitia Gangloff (Acsone)
-
stock_inventory
_hierarchical_ location : in fill inventory, if exclude location is empty do not add it in domain
Laetitia Gangloff (Acsone) (laetitia-gangloff) wrote : | # |
Following Loïc's test, in fill inventory I remove the exclude clause when location list to exclude is empty.
- 43. By Laetitia Gangloff (Acsone)
-
stock_inventory
_hierarchical_ location : remove unused method _fill_location_ lines - 44. By Laetitia Gangloff (Acsone)
-
stock_inventory
_hierarchical_ location: fill_inventory ignore no product exception in case of an exhaustive inventory
Loïc Bellier - Numérigraphe (lb-b) wrote : | # |
After lot's of test, your module seems to work !
Preview Diff
1 | === modified file 'stock_inventory_hierarchical_location/__init__.py' | |||
2 | --- stock_inventory_hierarchical_location/__init__.py 2014-06-12 12:48:28 +0000 | |||
3 | +++ stock_inventory_hierarchical_location/__init__.py 2014-06-13 13:19:05 +0000 | |||
4 | @@ -19,3 +19,4 @@ | |||
5 | 19 | ############################################################################## | 19 | ############################################################################## |
6 | 20 | 20 | ||
7 | 21 | from . import inventory_hierarchical_location | 21 | from . import inventory_hierarchical_location |
8 | 22 | from . import wizard | ||
9 | 22 | 23 | ||
10 | === modified file 'stock_inventory_hierarchical_location/__openerp__.py' | |||
11 | --- stock_inventory_hierarchical_location/__openerp__.py 2014-06-10 14:04:38 +0000 | |||
12 | +++ stock_inventory_hierarchical_location/__openerp__.py 2014-06-13 13:19:05 +0000 | |||
13 | @@ -43,6 +43,6 @@ | |||
14 | 43 | "data": [ | 43 | "data": [ |
15 | 44 | "inventory_hierarchical_location_view.xml", | 44 | "inventory_hierarchical_location_view.xml", |
16 | 45 | ], | 45 | ], |
18 | 46 | "test": ["test/inventory_hierarchical_location_test.yml"], | 46 | "test": ["tests/inventory_hierarchical_location_test.yml"], |
19 | 47 | "demo": ["inventory_hierarchical_location_demo.xml"], | 47 | "demo": ["inventory_hierarchical_location_demo.xml"], |
20 | 48 | } | 48 | } |
21 | 49 | 49 | ||
22 | === modified file 'stock_inventory_hierarchical_location/inventory_hierarchical_location.py' | |||
23 | --- stock_inventory_hierarchical_location/inventory_hierarchical_location.py 2014-06-12 12:48:28 +0000 | |||
24 | +++ stock_inventory_hierarchical_location/inventory_hierarchical_location.py 2014-06-13 13:19:05 +0000 | |||
25 | @@ -86,13 +86,3 @@ | |||
26 | 86 | "It cannot be added.")} | 86 | "It cannot be added.")} |
27 | 87 | } | 87 | } |
28 | 88 | return {} | 88 | return {} |
29 | 89 | |||
30 | 90 | def _fill_location_lines(self, cr, uid, inventory_id, location_ids, | ||
31 | 91 | set_stock_zero, context=None): | ||
32 | 92 | """Add ids of children inventory into list """ | ||
33 | 93 | children_inventory_ids = self.search( | ||
34 | 94 | cr, uid, [('parent_id', 'child_of', inventory_id)]) | ||
35 | 95 | context['children_inventory_ids'] = children_inventory_ids | ||
36 | 96 | return super(HierarchicalExhInventory, self)._fill_location_lines( | ||
37 | 97 | cr, uid, inventory_id, location_ids, set_stock_zero, | ||
38 | 98 | context=context) | ||
39 | 99 | 89 | ||
40 | === modified file 'stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml' | |||
41 | --- stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 2014-06-12 16:40:46 +0000 | |||
42 | +++ stock_inventory_hierarchical_location/inventory_hierarchical_location_demo.xml 2014-06-13 13:19:05 +0000 | |||
43 | @@ -22,7 +22,7 @@ | |||
44 | 22 | <record id="child_2_id" model="stock.inventory"> | 22 | <record id="child_2_id" model="stock.inventory"> |
45 | 23 | <field name="name">Team B</field> | 23 | <field name="name">Team B</field> |
46 | 24 | <field name="parent_id" ref="parent_inventory"/> | 24 | <field name="parent_id" ref="parent_inventory"/> |
48 | 25 | <field name="location_id" model="stock.location" search="stock.stock_location_components"/> | 25 | <field name="location_id" model="stock.location" ref="stock.stock_location_components"/> |
49 | 26 | </record> | 26 | </record> |
50 | 27 | </data> | 27 | </data> |
51 | 28 | </openerp> | 28 | </openerp> |
52 | 29 | 29 | ||
53 | === renamed directory 'stock_inventory_hierarchical_location/test' => 'stock_inventory_hierarchical_location/tests' | |||
54 | === added file 'stock_inventory_hierarchical_location/tests/__init__.py' | |||
55 | --- stock_inventory_hierarchical_location/tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
56 | +++ stock_inventory_hierarchical_location/tests/__init__.py 2014-06-13 13:19:05 +0000 | |||
57 | @@ -0,0 +1,39 @@ | |||
58 | 1 | # -*- coding: utf-8 -*- | ||
59 | 2 | # | ||
60 | 3 | # | ||
61 | 4 | # Authors: Laetitia Gangloff | ||
62 | 5 | # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) | ||
63 | 6 | # All Rights Reserved | ||
64 | 7 | # | ||
65 | 8 | # WARNING: This program as such is intended to be used by professional | ||
66 | 9 | # programmers who take the whole responsibility of assessing all potential | ||
67 | 10 | # consequences resulting from its eventual inadequacies and bugs. | ||
68 | 11 | # End users who are looking for a ready-to-use solution with commercial | ||
69 | 12 | # guarantees and support are strongly advised to contact a Free Software | ||
70 | 13 | # Service Company. | ||
71 | 14 | # | ||
72 | 15 | # This program is free software: you can redistribute it and/or modify | ||
73 | 16 | # it under the terms of the GNU Affero General Public License as | ||
74 | 17 | # published by the Free Software Foundation, either version 3 of the | ||
75 | 18 | # License, or (at your option) any later version. | ||
76 | 19 | # | ||
77 | 20 | # This program is distributed in the hope that it will be useful, | ||
78 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
79 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
80 | 23 | # GNU Affero General Public License for more details. | ||
81 | 24 | # | ||
82 | 25 | # You should have received a copy of the GNU Affero General Public License | ||
83 | 26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
84 | 27 | # | ||
85 | 28 | # | ||
86 | 29 | |||
87 | 30 | import fill_inventory_test | ||
88 | 31 | |||
89 | 32 | fast_suite = [ | ||
90 | 33 | ] | ||
91 | 34 | |||
92 | 35 | checks = [ | ||
93 | 36 | fill_inventory_test, | ||
94 | 37 | ] | ||
95 | 38 | |||
96 | 39 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
97 | 0 | 40 | ||
98 | === added file 'stock_inventory_hierarchical_location/tests/fill_inventory_test.py' | |||
99 | --- stock_inventory_hierarchical_location/tests/fill_inventory_test.py 1970-01-01 00:00:00 +0000 | |||
100 | +++ stock_inventory_hierarchical_location/tests/fill_inventory_test.py 2014-06-13 13:19:05 +0000 | |||
101 | @@ -0,0 +1,118 @@ | |||
102 | 1 | # -*- coding: utf-8 -*- | ||
103 | 2 | # | ||
104 | 3 | # | ||
105 | 4 | # Authors: Laetitia Gangloff | ||
106 | 5 | # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) | ||
107 | 6 | # All Rights Reserved | ||
108 | 7 | # | ||
109 | 8 | # WARNING: This program as such is intended to be used by professional | ||
110 | 9 | # programmers who take the whole responsibility of assessing all potential | ||
111 | 10 | # consequences resulting from its eventual inadequacies and bugs. | ||
112 | 11 | # End users who are looking for a ready-to-use solution with commercial | ||
113 | 12 | # guarantees and support are strongly advised to contact a Free Software | ||
114 | 13 | # Service Company. | ||
115 | 14 | # | ||
116 | 15 | # This program is free software: you can redistribute it and/or modify | ||
117 | 16 | # it under the terms of the GNU Affero General Public License as | ||
118 | 17 | # published by the Free Software Foundation, either version 3 of the | ||
119 | 18 | # License, or (at your option) any later version. | ||
120 | 19 | # | ||
121 | 20 | # This program is distributed in the hope that it will be useful, | ||
122 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
123 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
124 | 23 | # GNU Affero General Public License for more details. | ||
125 | 24 | # | ||
126 | 25 | # You should have received a copy of the GNU Affero General Public License | ||
127 | 26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
128 | 27 | # | ||
129 | 28 | # | ||
130 | 29 | |||
131 | 30 | import openerp.tests.common as common | ||
132 | 31 | |||
133 | 32 | DB = common.DB | ||
134 | 33 | ADMIN_USER_ID = common.ADMIN_USER_ID | ||
135 | 34 | |||
136 | 35 | |||
137 | 36 | class fill_inventory_test(common.TransactionCase): | ||
138 | 37 | |||
139 | 38 | def setUp(self): | ||
140 | 39 | super(fill_inventory_test, self).setUp() | ||
141 | 40 | |||
142 | 41 | def test_missing_location(self): | ||
143 | 42 | """ | ||
144 | 43 | Test that when confirm a parent inventory, the child location are not in the confirmation result | ||
145 | 44 | """ | ||
146 | 45 | parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory') | ||
147 | 46 | self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id]) | ||
148 | 47 | # confirm shelf 1 inventory | ||
149 | 48 | inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id') | ||
150 | 49 | self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id]) | ||
151 | 50 | missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id]) | ||
152 | 51 | self.assertEqual(len(missing_location), 1, "1 missing location should be find, because the inventory is empty") | ||
153 | 52 | wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]}) | ||
154 | 53 | self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]}) | ||
155 | 54 | missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id]) | ||
156 | 55 | self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is confirmed") | ||
157 | 56 | # confirm shelf 2 inventory | ||
158 | 57 | inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id') | ||
159 | 58 | self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id]) | ||
160 | 59 | missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id]) | ||
161 | 60 | self.assertEqual(len(missing_location), 1, "1 missing location should be fine, because the inventory is empty") | ||
162 | 61 | self.registry('stock.inventory.line').create(self.cr, self.uid, {'product_id': self.ref('product.product_product_7'), | ||
163 | 62 | 'product_uom': self.ref('product.product_uom_unit'), | ||
164 | 63 | 'company_id': self.ref('base.main_company'), | ||
165 | 64 | 'inventory_id': inventory_id, | ||
166 | 65 | 'product_qty': 18.0, | ||
167 | 66 | 'location_id': self.ref('stock.stock_location_14')}) | ||
168 | 67 | missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [inventory_id]) | ||
169 | 68 | self.assertEqual(len(missing_location), 0, "No missing location should be find, because the inventory is filled") | ||
170 | 69 | wizard_id = self.registry('stock.inventory.uninventoried.locations').create(self.cr, self.uid, {}, context={'active_ids': [inventory_id]}) | ||
171 | 70 | wizard = self.registry('stock.inventory.uninventoried.locations').browse(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]}) | ||
172 | 71 | self.assertEqual(len(wizard.location_ids), 0, "The wizard should not contain any lines but contains %s." % wizard.location_ids) | ||
173 | 72 | self.registry('stock.inventory.uninventoried.locations').confirm_uninventoried_locations(self.cr, self.uid, wizard_id, context={'active_ids': [inventory_id]}) | ||
174 | 73 | # confirm parent inventory | ||
175 | 74 | missing_location = self.registry('stock.inventory').get_missing_locations(self.cr, self.uid, [parent_inventory_id]) | ||
176 | 75 | self.assertEqual(len(missing_location), 1, "Only 1 missing location should be find, because there is some location in child inventory") | ||
177 | 76 | |||
178 | 77 | def test_fill_inventory(self): | ||
179 | 78 | """ | ||
180 | 79 | Test that when fill a parent inventory, the child location are not in the result | ||
181 | 80 | """ | ||
182 | 81 | parent_inventory_id = self.ref('stock_inventory_hierarchical_location.parent_inventory') | ||
183 | 82 | self.registry('stock.inventory').action_open(self.cr, self.uid, [parent_inventory_id]) | ||
184 | 83 | # confirm shelf 1 inventory | ||
185 | 84 | inventory_id = self.ref('stock_inventory_hierarchical_location.child_2_id') | ||
186 | 85 | self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id]) | ||
187 | 86 | wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_components'), | ||
188 | 87 | 'recursive': True, | ||
189 | 88 | 'exhaustive': True, | ||
190 | 89 | 'set_stock_zero': True}, context={'active_ids': [inventory_id]}) | ||
191 | 90 | self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]}) | ||
192 | 91 | inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)]) | ||
193 | 92 | self.assertEqual(len(inventory_line_ids), 12, "12 inventory line is fount after filling inventory") | ||
194 | 93 | # confirm shelf 2 inventory | ||
195 | 94 | inventory_id = self.ref('stock_inventory_hierarchical_location.child_1_id') | ||
196 | 95 | self.registry('stock.inventory').action_open(self.cr, self.uid, [inventory_id]) | ||
197 | 96 | wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_14'), | ||
198 | 97 | 'recursive': True, | ||
199 | 98 | 'exhaustive': True, | ||
200 | 99 | 'set_stock_zero': True}, context={'active_ids': [inventory_id]}) | ||
201 | 100 | self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [inventory_id]}) | ||
202 | 101 | inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', inventory_id)]) | ||
203 | 102 | self.assertEqual(len(inventory_line_ids), 4, "1 inventory line is fount after filling inventory") | ||
204 | 103 | # confirm parent inventory | ||
205 | 104 | wizard_id = self.registry('stock.fill.inventory').create(self.cr, self.uid, {'location_id': self.ref('stock.stock_location_stock'), | ||
206 | 105 | 'recursive': True, | ||
207 | 106 | 'exhaustive': True, | ||
208 | 107 | 'set_stock_zero': True}, context={'active_ids': [parent_inventory_id]}) | ||
209 | 108 | try: | ||
210 | 109 | self.registry('stock.fill.inventory').fill_inventory(self.cr, self.uid, [wizard_id], context={'active_ids': [parent_inventory_id]}) | ||
211 | 110 | except Exception, e: | ||
212 | 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.''") | ||
213 | 112 | exception_happened = True | ||
214 | 113 | pass | ||
215 | 114 | self.assertTrue(exception_happened) | ||
216 | 115 | inventory_line_ids = self.registry('stock.inventory.line').search(self.cr, self.uid, [('inventory_id', '=', parent_inventory_id)]) | ||
217 | 116 | self.assertEqual(len(inventory_line_ids), 0, "No inventory line is fount after filling inventory") | ||
218 | 117 | |||
219 | 118 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
220 | 0 | 119 | ||
221 | === added directory 'stock_inventory_hierarchical_location/wizard' | |||
222 | === added file 'stock_inventory_hierarchical_location/wizard/__init__.py' | |||
223 | --- stock_inventory_hierarchical_location/wizard/__init__.py 1970-01-01 00:00:00 +0000 | |||
224 | +++ stock_inventory_hierarchical_location/wizard/__init__.py 2014-06-13 13:19:05 +0000 | |||
225 | @@ -0,0 +1,21 @@ | |||
226 | 1 | # -*- coding: utf-8 -*- | ||
227 | 2 | ############################################################################## | ||
228 | 3 | # | ||
229 | 4 | # This module is copyright (C) 2013 Numérigraphe SARL. All Rights Reserved. | ||
230 | 5 | # | ||
231 | 6 | # This program is free software: you can redistribute it and/or modify | ||
232 | 7 | # it under the terms of the GNU General Public License as published by | ||
233 | 8 | # the Free Software Foundation, either version 3 of the License, or | ||
234 | 9 | # (at your option) any later version. | ||
235 | 10 | # | ||
236 | 11 | # This program is distributed in the hope that it will be useful, | ||
237 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
238 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
239 | 14 | # GNU General Public License for more details. | ||
240 | 15 | # | ||
241 | 16 | # You should have received a copy of the GNU General Public License | ||
242 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
243 | 18 | # | ||
244 | 19 | ############################################################################## | ||
245 | 20 | |||
246 | 21 | from . import stock_fill_location_inventory | ||
247 | 0 | 22 | ||
248 | === added file 'stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py' | |||
249 | --- stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 1970-01-01 00:00:00 +0000 | |||
250 | +++ stock_inventory_hierarchical_location/wizard/stock_fill_location_inventory.py 2014-06-13 13:19:05 +0000 | |||
251 | @@ -0,0 +1,89 @@ | |||
252 | 1 | # -*- coding: utf-8 -*- | ||
253 | 2 | # | ||
254 | 3 | # | ||
255 | 4 | # Authors: Laetitia Gangloff | ||
256 | 5 | # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) | ||
257 | 6 | # All Rights Reserved | ||
258 | 7 | # | ||
259 | 8 | # WARNING: This program as such is intended to be used by professional | ||
260 | 9 | # programmers who take the whole responsibility of assessing all potential | ||
261 | 10 | # consequences resulting from its eventual inadequacies and bugs. | ||
262 | 11 | # End users who are looking for a ready-to-use solution with commercial | ||
263 | 12 | # guarantees and support are strongly advised to contact a Free Software | ||
264 | 13 | # Service Company. | ||
265 | 14 | # | ||
266 | 15 | # This program is free software: you can redistribute it and/or modify | ||
267 | 16 | # it under the terms of the GNU Affero General Public License as | ||
268 | 17 | # published by the Free Software Foundation, either version 3 of the | ||
269 | 18 | # License, or (at your option) any later version. | ||
270 | 19 | # | ||
271 | 20 | # This program is distributed in the hope that it will be useful, | ||
272 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
273 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
274 | 23 | # GNU Affero General Public License for more details. | ||
275 | 24 | # | ||
276 | 25 | # You should have received a copy of the GNU Affero General Public License | ||
277 | 26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
278 | 27 | # | ||
279 | 28 | # | ||
280 | 29 | |||
281 | 30 | from openerp.osv import orm | ||
282 | 31 | from openerp.tools.translate import _ | ||
283 | 32 | |||
284 | 33 | |||
285 | 34 | class FillInventoryWizard(orm.TransientModel): | ||
286 | 35 | """If inventory as sub inventories, do not fill with sub inventories location""" | ||
287 | 36 | _inherit = 'stock.fill.inventory' | ||
288 | 37 | |||
289 | 38 | def fill_inventory(self, cr, uid, ids, context=None): | ||
290 | 39 | """ To Import stock inventory according to products available in the location and not already in a sub inventory | ||
291 | 40 | |||
292 | 41 | We split fill_inventory on many fill_inventory (one for each location) | ||
293 | 42 | @param self: The object pointer. | ||
294 | 43 | @param cr: A database cursor | ||
295 | 44 | @param uid: ID of the user currently logged in | ||
296 | 45 | @param ids: the ID or list of IDs if we want more than one | ||
297 | 46 | @param context: A standard dictionary | ||
298 | 47 | @return: | ||
299 | 48 | """ | ||
300 | 49 | if context is None: | ||
301 | 50 | context = {} | ||
302 | 51 | |||
303 | 52 | if ids and len(ids): | ||
304 | 53 | ids = ids[0] | ||
305 | 54 | else: | ||
306 | 55 | return {'type': 'ir.actions.act_window_close'} | ||
307 | 56 | fill_inventory = self.browse(cr, uid, ids, context=context) | ||
308 | 57 | if fill_inventory.recursive and fill_inventory.exhaustive: | ||
309 | 58 | exclude_location_ids = [] | ||
310 | 59 | for i in self.pool['stock.inventory'].browse(cr, uid, context['active_ids']): | ||
311 | 60 | for sub_inventory in i.inventory_ids: | ||
312 | 61 | # exclude these location | ||
313 | 62 | exclude_location_ids.append(sub_inventory.location_id.id) | ||
314 | 63 | domain = [('location_id', 'child_of', [fill_inventory.location_id.id])] | ||
315 | 64 | if exclude_location_ids: | ||
316 | 65 | domain.append('!') | ||
317 | 66 | domain.append(('location_id', 'child_of', exclude_location_ids)) | ||
318 | 67 | location_ids = self.pool['stock.location'].search(cr, uid, domain, | ||
319 | 68 | order="id", | ||
320 | 69 | context=context) | ||
321 | 70 | all_in_exception = 0 | ||
322 | 71 | for location_id in location_ids: | ||
323 | 72 | try: | ||
324 | 73 | super(FillInventoryWizard, self).fill_inventory(cr, uid, | ||
325 | 74 | [self.copy(cr, uid, ids, {'location_id': location_id, | ||
326 | 75 | 'recursive': False, }, context=context)], | ||
327 | 76 | context=context) | ||
328 | 77 | except Exception, e: | ||
329 | 78 | if e.value == _('No product in this location. Please select a location in the product form.'): | ||
330 | 79 | all_in_exception = all_in_exception + 1 | ||
331 | 80 | pass | ||
332 | 81 | else: | ||
333 | 82 | raise e | ||
334 | 83 | if all_in_exception == len(location_ids): | ||
335 | 84 | raise orm.except_orm(_('Warning!'), _('No product in this location. Please select a location in the product form.')) | ||
336 | 85 | return {'type': 'ir.actions.act_window_close'} | ||
337 | 86 | else: | ||
338 | 87 | return super(FillInventoryWizard, self).fill_inventory(cr, uid, [ids], context=context) | ||
339 | 88 | |||
340 | 89 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
341 | 0 | 90 | ||
342 | === modified file 'stock_inventory_location/__openerp__.py' | |||
343 | --- stock_inventory_location/__openerp__.py 2014-06-10 16:02:09 +0000 | |||
344 | +++ stock_inventory_location/__openerp__.py 2014-06-13 13:19:05 +0000 | |||
345 | @@ -62,9 +62,9 @@ | |||
346 | 62 | "wizard/stock_fill_location_inventory_view.xml", | 62 | "wizard/stock_fill_location_inventory_view.xml", |
347 | 63 | ], | 63 | ], |
348 | 64 | "test": [ | 64 | "test": [ |
352 | 65 | "test/inventory_standard_test.yml", | 65 | "tests/inventory_standard_test.yml", |
353 | 66 | "test/inventory_exhaustive_test.yml", | 66 | "tests/inventory_exhaustive_test.yml", |
354 | 67 | "test/inventory_future_test.yml", | 67 | "tests/inventory_future_test.yml", |
355 | 68 | ], | 68 | ], |
356 | 69 | "images": [ | 69 | "images": [ |
357 | 70 | "images/inventory_form.png", | 70 | "images/inventory_form.png", |
358 | 71 | 71 | ||
359 | === modified file 'stock_inventory_location/stock_inventory_location.py' | |||
360 | --- stock_inventory_location/stock_inventory_location.py 2014-06-12 16:49:28 +0000 | |||
361 | +++ stock_inventory_location/stock_inventory_location.py 2014-06-13 13:19:05 +0000 | |||
362 | @@ -27,6 +27,7 @@ | |||
363 | 27 | # TODOv8! remove, feature is included upstream | 27 | # TODOv8! remove, feature is included upstream |
364 | 28 | from openerp.osv import osv | 28 | from openerp.osv import osv |
365 | 29 | from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT | 29 | from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT |
366 | 30 | from openerp import SUPERUSER_ID | ||
367 | 30 | 31 | ||
368 | 31 | from .exceptions import ExhaustiveInventoryException | 32 | from .exceptions import ExhaustiveInventoryException |
369 | 32 | 33 | ||
370 | @@ -270,7 +271,7 @@ | |||
371 | 270 | """Error if an exhaustive Inventory is being conducted here""" | 271 | """Error if an exhaustive Inventory is being conducted here""" |
372 | 271 | inv_obj = self.pool['stock.inventory'] | 272 | inv_obj = self.pool['stock.inventory'] |
373 | 272 | location_inventory_open_ids = inv_obj._get_locations_open_inventories( | 273 | location_inventory_open_ids = inv_obj._get_locations_open_inventories( |
375 | 273 | cr, uid, context=context) | 274 | cr, SUPERUSER_ID, context=context) |
376 | 274 | if not isinstance(ids, Iterable): | 275 | if not isinstance(ids, Iterable): |
377 | 275 | ids = [ids] | 276 | ids = [ids] |
378 | 276 | for inv_id in ids: | 277 | for inv_id in ids: |
379 | @@ -286,7 +287,7 @@ | |||
380 | 286 | self._check_inventory(cr, uid, ids, context=context) | 287 | self._check_inventory(cr, uid, ids, context=context) |
381 | 287 | if not isinstance(ids, Iterable): | 288 | if not isinstance(ids, Iterable): |
382 | 288 | ids = [ids] | 289 | ids = [ids] |
384 | 289 | ids_to_check = ids | 290 | ids_to_check = list(ids) |
385 | 290 | # If changing the parent, no inventory must conducted there either | 291 | # If changing the parent, no inventory must conducted there either |
386 | 291 | if vals.get('location_id'): | 292 | if vals.get('location_id'): |
387 | 292 | ids_to_check.append(vals['location_id']) | 293 | ids_to_check.append(vals['location_id']) |
388 | @@ -326,7 +327,7 @@ | |||
389 | 326 | message = "" | 327 | message = "" |
390 | 327 | inv_obj = self.pool['stock.inventory'] | 328 | inv_obj = self.pool['stock.inventory'] |
391 | 328 | locked_location_ids = inv_obj._get_locations_open_inventories( | 329 | locked_location_ids = inv_obj._get_locations_open_inventories( |
393 | 329 | cr, uid, context=context) | 330 | cr, SUPERUSER_ID, context=context) |
394 | 330 | if not locked_location_ids: | 331 | if not locked_location_ids: |
395 | 331 | # Nothing to verify | 332 | # Nothing to verify |
396 | 332 | return True | 333 | return True |
397 | 333 | 334 | ||
398 | === renamed directory 'stock_inventory_location/test' => 'stock_inventory_location/tests' | |||
399 | === added file 'stock_inventory_location/tests/__init__.py' | |||
400 | --- stock_inventory_location/tests/__init__.py 1970-01-01 00:00:00 +0000 | |||
401 | +++ stock_inventory_location/tests/__init__.py 2014-06-13 13:19:05 +0000 | |||
402 | @@ -0,0 +1,39 @@ | |||
403 | 1 | # -*- coding: utf-8 -*- | ||
404 | 2 | # | ||
405 | 3 | # | ||
406 | 4 | # Authors: Laetitia Gangloff | ||
407 | 5 | # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) | ||
408 | 6 | # All Rights Reserved | ||
409 | 7 | # | ||
410 | 8 | # WARNING: This program as such is intended to be used by professional | ||
411 | 9 | # programmers who take the whole responsibility of assessing all potential | ||
412 | 10 | # consequences resulting from its eventual inadequacies and bugs. | ||
413 | 11 | # End users who are looking for a ready-to-use solution with commercial | ||
414 | 12 | # guarantees and support are strongly advised to contact a Free Software | ||
415 | 13 | # Service Company. | ||
416 | 14 | # | ||
417 | 15 | # This program is free software: you can redistribute it and/or modify | ||
418 | 16 | # it under the terms of the GNU Affero General Public License as | ||
419 | 17 | # published by the Free Software Foundation, either version 3 of the | ||
420 | 18 | # License, or (at your option) any later version. | ||
421 | 19 | # | ||
422 | 20 | # This program is distributed in the hope that it will be useful, | ||
423 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
424 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
425 | 23 | # GNU Affero General Public License for more details. | ||
426 | 24 | # | ||
427 | 25 | # You should have received a copy of the GNU Affero General Public License | ||
428 | 26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
429 | 27 | # | ||
430 | 28 | # | ||
431 | 29 | |||
432 | 30 | import stock_inventory_location_test | ||
433 | 31 | |||
434 | 32 | fast_suite = [ | ||
435 | 33 | ] | ||
436 | 34 | |||
437 | 35 | checks = [ | ||
438 | 36 | stock_inventory_location_test, | ||
439 | 37 | ] | ||
440 | 38 | |||
441 | 39 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
442 | 0 | 40 | ||
443 | === added file 'stock_inventory_location/tests/stock_inventory_location_test.py' | |||
444 | --- stock_inventory_location/tests/stock_inventory_location_test.py 1970-01-01 00:00:00 +0000 | |||
445 | +++ stock_inventory_location/tests/stock_inventory_location_test.py 2014-06-13 13:19:05 +0000 | |||
446 | @@ -0,0 +1,47 @@ | |||
447 | 1 | # -*- coding: utf-8 -*- | ||
448 | 2 | # | ||
449 | 3 | # | ||
450 | 4 | # Authors: Laetitia Gangloff | ||
451 | 5 | # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) | ||
452 | 6 | # All Rights Reserved | ||
453 | 7 | # | ||
454 | 8 | # WARNING: This program as such is intended to be used by professional | ||
455 | 9 | # programmers who take the whole responsibility of assessing all potential | ||
456 | 10 | # consequences resulting from its eventual inadequacies and bugs. | ||
457 | 11 | # End users who are looking for a ready-to-use solution with commercial | ||
458 | 12 | # guarantees and support are strongly advised to contact a Free Software | ||
459 | 13 | # Service Company. | ||
460 | 14 | # | ||
461 | 15 | # This program is free software: you can redistribute it and/or modify | ||
462 | 16 | # it under the terms of the GNU Affero General Public License as | ||
463 | 17 | # published by the Free Software Foundation, either version 3 of the | ||
464 | 18 | # License, or (at your option) any later version. | ||
465 | 19 | # | ||
466 | 20 | # This program is distributed in the hope that it will be useful, | ||
467 | 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
468 | 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
469 | 23 | # GNU Affero General Public License for more details. | ||
470 | 24 | # | ||
471 | 25 | # You should have received a copy of the GNU Affero General Public License | ||
472 | 26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
473 | 27 | # | ||
474 | 28 | # | ||
475 | 29 | |||
476 | 30 | import openerp.tests.common as common | ||
477 | 31 | |||
478 | 32 | DB = common.DB | ||
479 | 33 | ADMIN_USER_ID = common.ADMIN_USER_ID | ||
480 | 34 | |||
481 | 35 | |||
482 | 36 | class stock_inventory_location_test(common.TransactionCase): | ||
483 | 37 | |||
484 | 38 | def setUp(self): | ||
485 | 39 | super(stock_inventory_location_test, self).setUp() | ||
486 | 40 | |||
487 | 41 | def test_update_parent_location(self): | ||
488 | 42 | """ | ||
489 | 43 | Test the update of the parent of a location (no inventory in progress | ||
490 | 44 | """ | ||
491 | 45 | self.registry('stock.location').write(self.cr, self.uid, self.ref('stock.stock_location_5'), {'location_id': self.ref('stock.stock_location_4')}) | ||
492 | 46 | |||
493 | 47 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
Thanks for your help.
I've just merged our own fixes of the day, will you please merge them to avoid conflicts ?
I think I understand what you're trying to do in fill_inventory and it's not exactly how we had it in v6 - which is broken right now in v7, and would require a patch on the code addons.
Your patch completely excludes the locations of sub-inventories, whereas we used to only exclude the generated inventory lines. That would allow us to "catch" the lines that could have been missing from sub-inventories, but since they're exhaustive anyway there should not be any.
So I guess your approach is correct.
I'll let Loïc decide, he's working on the problem too.