~unifield-team/unifield-wm/us-826

431.10.5 by qt-tempo-consulting
UF-697 [ADD] Added the msf_config_locations which allows user to configure the optionnal locations of his instance.
1
# -*- coding: utf-8 -*-
2
##############################################################################
3
#
4
#    OpenERP, Open Source Management Solution
5
#    Copyright (C) 2011 TeMPO Consulting, MSF
6
#
7
#    This program is free software: you can redistribute it and/or modify
8
#    it under the terms of the GNU Affero General Public License as
9
#    published by the Free Software Foundation, either version 3 of the
10
#    License, or (at your option) any later version.
11
#
12
#    This program is distributed in the hope that it will be useful,
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
#    GNU Affero General Public License for more details.
16
#
17
#    You should have received a copy of the GNU Affero General Public License
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
# 
20
##############################################################################
21
22
from osv import osv
23
from osv import fields
24
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
25
from tools.translate import _
26
1041.1.19 by Quentin THEURET
Forgot imports
27
import logging
28
from os import path
29
import math
30
import re
31
import tools
32
431.10.6 by qt-tempo-consulting
UF-697 [IMP] Moved location data from msf_profile into msf_config_locations
33
class stock_location(osv.osv):
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
34
    '''
35
    Change the order and parent_order field.
36
    '''
431.10.6 by qt-tempo-consulting
UF-697 [IMP] Moved location data from msf_profile into msf_config_locations
37
    _name = "stock.location"
38
    _inherit = 'stock.location'
431.10.16 by Quentin THEURET
UF-697 [FIX] MSF Outgoing : Converted to standard doesn't create chaining
39
    _parent_order = 'location_id, posz'
40
    _order = 'location_id, posz'
1041.1.18 by Quentin THEURET
UF-1040 [FIX] Load locations before run msf_config_locations
41
1638.7.1 by Quentin THEURET
UF-2002 [IMP] Name of the instance warehouse should be consistent with Instance name and optional stock locations shouldn't exist by default
42
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
43
    def _get_input_output(self, cr, uid, ids, field_name, args, context=None):
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
44
        '''
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
45
        Return True if the location is the input/output location of a warehouse or a children of it
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
46
        '''
47
        res = {}
48
        wh_ids = self.pool.get('stock.warehouse').search(cr, uid, [])
49
        output_loc = []
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
50
        input_loc = []
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
51
        for wh in self.pool.get('stock.warehouse').browse(cr, uid, wh_ids):
52
            output_loc.extend(self.search(cr, uid, [('location_id', 'child_of', wh.lot_output_id.id)]))
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
53
            input_loc.extend(self.search(cr, uid, [('location_id', 'child_of', wh.lot_input_id.id)]))
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
54
            
55
        for id in ids:
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
56
            if field_name == 'output_ok':
57
                res[id] = id in output_loc
58
            elif field_name == 'input_ok':
59
                res[id] = id in input_loc
60
            else:
61
                res[id] = False
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
62
            
63
        return res
64
    
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
65
    def _src_input_output(self, cr, uid, obj, name, args, context=None):
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
66
        '''
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
67
        Return all input/output locations
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
68
        '''
69
        res = []
70
        wh_ids = self.pool.get('stock.warehouse').search(cr, uid, [])
71
        output_loc = []
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
72
        input_loc = []
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
73
        for wh in self.pool.get('stock.warehouse').browse(cr, uid, wh_ids):
74
            output_loc.extend(self.search(cr, uid, [('location_id', 'child_of', wh.lot_output_id.id)]))
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
75
            input_loc.extend(self.search(cr, uid, [('location_id', 'child of', wh.lot_input_id.id)]))
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
76
            
1041.1.6 by Quentin THEURET
UF-1040 [FIX] Fix some bugs
77
        operator = 'in'
78
        if (args[0][1] == '=' and args[0][2] == False) or (args[0][1] and '!=' and args[0][2] == True):
79
            operator = 'not in'
80
            
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
81
        if args[0][0] == 'output_ok':
82
            return [('id', operator, output_loc)]
83
        elif args[0][0] == 'input_ok':
84
            return [('id', operator, input_loc)]
85
        
86
        return res
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
87
    
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
88
    def _get_virtual(self, cr, uid, ids, field_name, args, context=None):
89
        '''
90
        Return True if the location is under the Virtual locations view
91
        '''
92
        res = {}
1041.1.21 by Quentin THEURET
UF-1040 [IMP] Fix issue on first installation
93
        try:
94
            virtual_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_locations_virtual')[1]
95
            virtual_ids = self.search(cr, uid, [('location_id', 'child_of', virtual_id)], context=context)
96
        except:
97
            virtual_ids = []
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
98
        for id in ids:
99
            res[id] = False
100
            if id in virtual_ids:
101
                res[id] = True
102
                
103
        return res
104
    
105
    def _src_virtual(self, cr, uid, obj, name, args, context=None):
106
        '''
107
        Returns all virtual locations
108
        '''
109
        res = []
1041.1.21 by Quentin THEURET
UF-1040 [IMP] Fix issue on first installation
110
        try:
111
            virtual_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_locations_virtual')[1]
112
            virtual_ids = self.search(cr, uid, [('location_id', 'child_of', virtual_id)], context=context)
113
        except:
114
            return res
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
115
        
116
        operator = 'in'
117
        if (args[0][1] == '=' and args[0][2] == False) or (args[0][1] and '!=' and args[0][2] == True):
118
            operator = 'not in'
119
            
120
        return [('id', operator, virtual_ids)]
121
    
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
122
    def _get_dummy(self, cr, uid, ids, field_name, args, context=None):
123
        '''
124
        Set all object to true
125
        '''
126
        res = {}
127
        for id in ids:
128
            res[id] = True
129
        return res
130
    
131
    def _src_pick_src(self, cr, uid, obj, name, args, context=None):
132
        '''
133
        Returns the available locations for source location of a picking ticket according to the product.
134
        '''
1041.1.6 by Quentin THEURET
UF-1040 [FIX] Fix some bugs
135
        res = [('usage', '=', 'internal')]
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
136
        for arg in args:
137
            if arg[0] == 'picking_ticket_src' and arg[1] == '=':
1041.1.6 by Quentin THEURET
UF-1040 [FIX] Fix some bugs
138
                if arg[2] == False:
139
                    break
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
140
                if type(arg[2]) != type(1):
141
                    raise osv.except_osv(_('Error'), _('Bad operand'))
142
                product = self.pool.get('product.product').browse(cr, uid, arg[2])
1282.7.12 by Quentin THEURET
UF-1515 [FIX] Add possibility to choose service products on stock moves
143
                if product.type in ('service_recep', 'consu'):
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
144
                    res = [('cross_docking_location_ok', '=', True)]
145
                else:
1041.1.6 by Quentin THEURET
UF-1040 [FIX] Fix some bugs
146
                    res = [('usage', '=', 'internal'), ('quarantine_location', '=', False), ('output_ok', '=', False)]
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
147
                    
148
        return res
149
    
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
150
    def _dest_inc_ship(self, cr, uid, obj, name, args, context=None):
151
        '''
152
        Returns the available locations for destination location of an incoming shipment according to the product.
153
        '''
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
154
        res = ['|', '|', '|', '|', ('usage', '=', 'internal'), ('service_location', '=', True), ('non_stockable_ok', '=', True), ('cross_docking_location_ok', '=', True), ('virtual_ok', '=', True)]
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
155
        for arg in args:
156
            if arg[0] == 'incoming_dest' and arg[1] == '=':
157
                if arg[2] == False:
158
                    break
159
                if type(arg[2]) != type(1):
160
                    raise osv.except_osv(_('Error'), _('Bad operand'))
161
                product = self.pool.get('product.product').browse(cr, uid, arg[2])
162
                if product.type in ('service', 'service_recep'):
1282.7.12 by Quentin THEURET
UF-1515 [FIX] Add possibility to choose service products on stock moves
163
                    res = ['|', ('cross_docking_location_ok', '=', True), ('service_location', '=', True)]
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
164
                elif product.type == 'consu':
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
165
                    res = ['|', '|', ('cross_docking_location_ok', '=', True), ('non_stockable_ok', '=', True), ('virtual_ok', '=', True)]
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
166
                else:
1041.1.15 by Quentin THEURET
UF-1040 [IMP] Set locations by default
167
                    res = [('non_stockable_ok', '=', False), '|', ('usage', '=', 'internal'), ('virtual_ok', '=', True)]
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
168
                    
169
        return res
170
    
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
171
    def _src_out(self, cr, uid, obj, name, args, context=None):
172
        '''
173
        Returns the available locations for source location of an outgoing delivery according to the product
174
        '''
175
        res = ['|', ('cross_docking_location_ok', '=', True), ('usage', '=', 'internal'), ('quarantine_location', '=', False), ('output_ok', '=', False), ('input_ok', '=', False)]
176
        for arg in args:
177
            # TODO: Refactorize this
178
            if arg[0] == 'outgoing_src' and arg[1] == '=':
179
                if arg[2] == False:
180
                    break
181
                if type(arg[2]) != type(1):
182
                    raise osv.except_osv(_('Error'), _('Bad operand'))
183
                product = self.pool.get('product.product').browse(cr, uid, arg[2])
1282.7.12 by Quentin THEURET
UF-1515 [FIX] Add possibility to choose service products on stock moves
184
                if product.type in ('service_recep', 'consu'):
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
185
                    # Cross-docking locations
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
186
                    res = [('cross_docking_location_ok', '=' ,True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
187
                else:
188
                    # All internal locations except Quarantine (both), Output (& children) and Input locations
189
                    res = [('usage', '=', 'internal'), ('quarantine_location', '=', False), ('output_ok', '=', False), ('input_ok', '=', False)]
190
                    
191
        return res
192
    
193
    def _src_int(self, cr, uid, obj, name, args, context=None):
194
        '''
195
        Return the available locations for source location of an internal picking according to the product
196
        '''
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
197
        res = [('service_location', '=', False), '|', '|', '|', ('cross_docking_location_ok', '=', True), ('quarantine_location', '=', True), ('usage', '=', 'internal'), ('virtual_ok', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
198
        for arg in args:
199
            if arg[0] == 'internal_src' and arg[1] == '=':
200
                if arg[2] == False:
201
                    break
202
                if type(arg[2]) != type(1):
203
                    raise osv.except_osv(_('Error'), _('Bad operand'))
204
                product = self.pool.get('product.product').browse(cr, uid, arg[2])
205
                if product.type == 'consu':
206
                    # Cross docking and quarantine locations
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
207
                    res = [('service_location', '=', False), '|', ('cross_docking_location_ok', '=', True), ('quarantine_location', '=', True)]
1282.7.12 by Quentin THEURET
UF-1515 [FIX] Add possibility to choose service products on stock moves
208
                elif product.type == 'service_recep':
209
                    # Cross docking locations
210
                    res = [('cross_docking_location_ok', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
211
                else:
212
                    # All internal and virtual locations
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
213
                    res = [('non_stockable_ok', '=', False), ('service_location', '=', False), '|', ('usage', '=', 'internal'), ('virtual_ok', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
214
                    
215
        return res
216
    
217
    def _dest_int(self, cr, uid, obj, name, args, context=None):
218
        '''
219
        Returns the available locations for destination location of an internal picking according to the product
220
        '''
221
        # Inventory, destruction, quarantine and all internal and virtual locations
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
222
        res = [('service_location', '=', False), '|', '|', '|', ('usage', 'in', ('internal', 'inventory')), ('destruction_location', '=', True), ('quarantine_location', '=', True), ('virtual_ok', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
223
        for arg in args:
224
            if arg[0] == 'internal_dest' and arg[1] == '=':
225
                if arg[2] == False:
226
                    break
227
                if type(arg[2]) != type(1):
228
                    raise osv.except_osv(_('Error'), _('Bad operand'))
229
                product = self.pool.get('product.product').browse(cr, uid, arg[2])
230
                if product.type == 'consu':
231
                    # Inventory, destruction and quarantine location
1242.4.1 by Quentin THEURET
UF-1500 [FIX] Add the possibility to move (internal move) a non-stockable product from Cross-docking to Non-stockable
232
                    res = [('service_location', '=', False), '|', '|', ('usage', '=', 'inventory'), ('destruction_location', '=', True), ('quarantine_location', '=', True)]
1282.7.12 by Quentin THEURET
UF-1515 [FIX] Add possibility to choose service products on stock moves
233
                elif product.type == 'service_recep':
234
                    # Service location
235
                    res = [('service_location', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
236
                else:
237
                    # All internal and virtual locations
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
238
                    res = [('non_stockable_ok', '=', False), ('service_location', '=', False), '|', ('usage', '=', 'internal'), ('virtual_ok', '=', True)]
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
239
                    
240
        return res
241
    
1041.1.25 by Quentin THEURET
UF-1040 [FIX] FIx the domain on outgoing delivery for location_dest_di
242
    def _get_warehouse_input(self, cr, uid, ids, context=None):
243
        res = []
244
        for wh in self.browse(cr, uid, ids, context=context):
245
            res.append(wh.lot_input_id.id)
1041.1.26 by Quentin THEURET
FU-1040 [IMP] Recompute the input/output when the input/output location of the warehouse is changed
246
            
247
        input_ids = self.pool.get('stock.location').search(cr, uid, [('input_ok', '=', True), ('active', 'in', ('t', 'f'))])
248
        res.extend(input_ids)
1041.1.25 by Quentin THEURET
UF-1040 [FIX] FIx the domain on outgoing delivery for location_dest_di
249
                    
250
        return res
251
    
252
    def _get_warehouse_output(self, cr, uid, ids, context=None):
253
        res = []
254
        for wh in self.browse(cr, uid, ids, context=context):
255
            res.append(wh.lot_output_id.id)
1041.1.26 by Quentin THEURET
FU-1040 [IMP] Recompute the input/output when the input/output location of the warehouse is changed
256
            
257
        output_ids = self.pool.get('stock.location').search(cr, uid, [('output_ok', '=', True), ('active', 'in', ('t', 'f'))])
258
        res.extend(output_ids)
1041.1.25 by Quentin THEURET
UF-1040 [FIX] FIx the domain on outgoing delivery for location_dest_di
259
                    
260
        return res
261
    
841.1.2 by Quentin THEURET
UF-1065 [IMP] Mission stock : Add the report for non full view instances
262
    _columns = {
263
        'central_location_ok': fields.boolean(string='If check, all products in this location are unallocated.'),
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
264
        'non_stockable_ok': fields.boolean(string='Non-stockable', help="If checked, the location will be used to store non-stockable products"),
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
265
        'output_ok': fields.function(_get_input_output, method=True, string='Output Location', type='boolean',
1041.1.25 by Quentin THEURET
UF-1040 [FIX] FIx the domain on outgoing delivery for location_dest_di
266
                                     store={'stock.location': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 20),
267
                                            'stock.warehouse': (_get_warehouse_output, ['lot_input_id'], 10)},
1041.1.6 by Quentin THEURET
UF-1040 [FIX] Fix some bugs
268
                                     help='If checked, the location is the output location of a warehouse or a children.'),
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
269
        'input_ok': fields.function(_get_input_output,  method=True, string='Input Location', type='boolean',
1041.1.25 by Quentin THEURET
UF-1040 [FIX] FIx the domain on outgoing delivery for location_dest_di
270
                                    store={'stock.location': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 20),
271
                                           'stock.warehouse': (_get_warehouse_input, ['lot_input_id'], 10)},
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
272
                                     help='If checked, the location is the input location of a warehouse or a children.'),
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
273
        'virtual_ok': fields.function(_get_virtual,  method=True, string='Virtual Location', type='boolean',
274
                                      store={'stock.location': (lambda self, cr, uid, ids, c={}: ids, ['location_id'], 20)},
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
275
                                     help='If checked, the location is a virtual location.'),
1041.1.5 by Quentin THEURET
UF-1040 [IMP] Replace the domain for source location on picking ticket moves by a fields.function
276
        'picking_ticket_src': fields.function(_get_dummy, fnct_search=_src_pick_src, method=True, string='Picking Ticket Src. Loc.', type='boolean',
1041.1.7 by Quentin THEURET
UF-1040 [IMP] Replace the domain for location_dest_id on incoming shipment by a fields.function
277
                                              help='Returns the available locations for source location of a picking ticket according to the product.'),
278
        'incoming_dest': fields.function(_get_dummy, fnct_search=_dest_inc_ship, method=True, string='Incoming shipment Dest. Loc.', type='boolean',
279
                                         help="Returns the available locations for destination location of an incoming shipment according to the product."),
1041.1.10 by Quentin THEURET
UF-1040 [IMP] Rework the change of a product on stock moves
280
        'outgoing_src': fields.function(_get_dummy, fnct_search=_src_out, method=True, string='Outgoing delivery Src. Loc.', type='boolean',
1041.1.9 by Quentin THEURET
UF-1040 [IMP] Stock picking : Change the domain of stock picking src/dest locations according to picking type and product type
281
                                        help='Returns the available locations for source location of an outgoing delivery according to the product.'),
282
        'internal_src': fields.function(_get_dummy, fnct_search=_src_int, method=True, string='Internal Picking Src. Loc.', type='boolean',
283
                                        help='Returns the available locations form source loctaion of an internal picking according to the product.'),
284
        'internal_dest': fields.function(_get_dummy, fnct_search=_dest_int, method=True, string='Internal Picking Dest. Loc.', type='boolean',
285
                                         help='Returns the available locations for destination location of an internal picking according to the product.'),
841.1.2 by Quentin THEURET
UF-1065 [IMP] Mission stock : Add the report for non full view instances
286
    }
287
    
431.10.6 by qt-tempo-consulting
UF-697 [IMP] Moved location data from msf_profile into msf_config_locations
288
stock_location()
289
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
290
291
class stock_location_configuration_wizard(osv.osv_memory):
292
    _name = 'stock.location.configuration.wizard'
850.4.9 by Quentin THEURET
UF-1071 [IMP] Stock locations configuration : Add the optionnal stock locations configuration wizard
293
    _inherit = 'res.config'
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
294
    
295
    _columns = {
296
        'location_name': fields.char(size=64, string='Location name', required=True),
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
297
        'location_usage': fields.selection([('stock', 'Stock'), ('consumption_unit', 'Consumption Unit'), ('eprep', 'EPREP')],
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
298
                                          string='Location usage'),
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
299
        'location_type': fields.selection([('internal', 'Internal'), ('customer', 'External')], string='Location type'),
300
        'location_id': fields.many2one('stock.location', string='Inactive location to re-activate'),
301
        'reactivate': fields.boolean(string='Reactivate location ?'),
302
    }
303
    
304
    _defaults = {
305
        'reactivate': lambda *a: False,
306
    }
307
    
850.4.9 by Quentin THEURET
UF-1071 [IMP] Stock locations configuration : Add the optionnal stock locations configuration wizard
308
    def action_add(self, cr, uid, ids, context=None):
309
        self.confirm_creation(cr, uid, ids[0], context=context)
310
        return {
311
            'view_type': 'form',
312
            "view_mode": 'form',
313
            'res_model': 'stock.location.configuration.wizard',
314
            'view_id':self.pool.get('ir.ui.view')\
315
                .search(cr,uid,[('name','=','Configurable Locations Configuration')]),
316
            'type': 'ir.actions.act_window',
317
            'target':'new',
318
            }
319
        
320
    def action_stop(self, cr, uid, ids, context=None):
321
        if isinstance(ids, (int, long)):
322
            ids = [ids]
323
        self.confirm_creation(cr, uid, ids, context=context)
324
        return self.action_next(cr, uid, ids, context=context)
325
    
326
    def execute(self, cr, uid, ids, context=None):
327
        pass
328
    
734 by jf
UF-846 [DEV] Stock refactoring
329
    def name_on_change(self, cr, uid, ids, location_name, usage, type, context=None):
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
330
        '''
331
        Check if a location with the same parameter exists on
332
        the instance warehouse
333
        '''
334
        res = {}
335
        warning = {}
336
        location_obj = self.pool.get('stock.location')
337
        
338
        if location_name:
339
            inactive_location_ids = location_obj.search(cr, uid, [('name', '=', location_name),
340
                                                                  ('active', '=', False), 
341
                                                                  ('usage', '=', usage or 'internal'),
342
                                                                  ('location_category', '=', type)], context=context)
343
            active_location_ids = location_obj.search(cr, uid, [('name', '=', location_name), 
344
                                                                ('usage', '=', usage or 'internal'),
345
                                                                ('location_category', '=', type)], context=context)
346
            
347
            if inactive_location_ids:
348
                warning.update({'title': _('Warning !'),
349
                                'message': _('An existing but inactive location already exists with the same parameters ! '\
350
                                           'Please, change the name of the new location, or re-activate the existing location '\
351
                                           'by clicking on \'Re-activate\' button.')})
352
                res.update({'reactivate': True, 'location_id': inactive_location_ids[0]})
353
            elif active_location_ids:
354
                warning.update({'title': _('Error !'),
355
                                'message': _('A location with the same name and the parameters already exists and is active. '\
356
                                           'You cannot have two locations with the same name and parameters. ' \
357
                                           'Please change the name of the new location before create it.')})
358
                res.update({'reactivate': False, 'loc_exists': True})
359
            else:
360
                res.update({'reactivate': False, 'location_id': False})
361
        
362
        return {'value': res,
363
                'warning': warning}
364
        
734 by jf
UF-846 [DEV] Stock refactoring
365
    def confirm_creation2(self, cr, uid, ids, context=None):
366
        if context is None:
367
            context = {}
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
368
        context.update({'reactivate_loc': True})
369
        return self.confirm_creation(cr, uid, ids, context=context)
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
370
734 by jf
UF-846 [DEV] Stock refactoring
371
    def confirm_creation(self, cr, uid, ids, context=None):
372
        if context is None:
373
            context = {}
850.4.9 by Quentin THEURET
UF-1071 [IMP] Stock locations configuration : Add the optionnal stock locations configuration wizard
374
        if isinstance(ids, (int, long)):
375
            ids = [ids]
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
376
        data_obj = self.pool.get('ir.model.data')
377
        location_obj = self.pool.get('stock.location')
378
        parent_location_id = False
379
        location_category = False
380
        location_usage = False
381
        location_name = False
382
        chained_location_type = 'none'
383
        chained_auto_packing = 'manual'
384
        chained_picking_type = 'internal'
385
        chained_location_id = False
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
386
        location = False
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
387
        
388
        for wizard in self.browse(cr, uid, ids, context=context):
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
389
            # Check if errors on location name
390
            errors = self.name_on_change(cr, uid, ids, wizard.location_name, wizard.location_type, wizard.location_usage, context=context)
391
            warning = errors.get('warning', {})
392
            values = errors.get('value', {})
393
            if warning and (values.get('loc_exists', False) or (values.get('reactivate', True) and not context.get('reactivate_loc', False))):
394
                raise osv.except_osv(errors.get('warning', {}).get('title', ''), errors.get('warning', {}).get('message', ''))
395
            # Returns an error if no given location name
396
            if not wizard.location_name:
397
#                # Raise error if location with the same name and the same parameters already exists
398
#                if location_obj.search(cr, uid, [('name', '=', wizard.location_name), 
399
#                                                 ('usage', '=', wizard.location_type or 'internal'),
400
#                                                 ('location_category', '=', wizard.location_usage)], context=context):
401
                raise osv.except_osv(_('Error'), _('You should give a name for the new location !'))
402
            location = wizard.location_id
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
403
            location_name = wizard.location_name
404
            # Check if all parent locations are activated in the system
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
405
            if wizard.location_usage in ('stock', 'eprep') or (wizard.location_type == 'internal' and wizard.location_usage == 'consumption_unit'):
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
406
                # Check if 'Configurable locations' location is active − If not, activate it !
407
                location_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_internal_client_view')
408
                if not location_id:
409
                    raise osv.except_osv(_('Error'), _('Location \'Configurable locations\' not found in the instance or is not activated !'))
410
                
411
                if not location_obj.browse(cr, uid, location_id, context=context).active:
412
                    location_obj.write(cr, uid, [location_id[1]], {'active': True}, context=context)
413
                
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
414
                if wizard.location_usage in ('stock', 'eprep'):
559.31.6 by Quentin THEURET
UF-697 [IMP] Remove chaining between Quarantine (analyze) and stock and between eprep and stock
415
#                    if wizard.location_usage == 'stock':
416
                    location_category = 'stock'
417
                    location_usage = 'internal'
431.10.11 by qt at tempo-consulting
UF-697 [IMP] Moved Eprep locations under 'Configurable locations'
418
                        # Check if 'Intermediate Stocks' is active − If note activate it !
559.31.6 by Quentin THEURET
UF-697 [IMP] Remove chaining between Quarantine (analyze) and stock and between eprep and stock
419
                    parent_location_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_intermediate_client_view')
420
#                    else:
421
#                        location_stock_id = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_stock')
422
#                        if not location_stock_id:
423
#                            raise osv.except_osv(_('Error'), _('Location \'Stock\' not found in the instance or is not activated !'))
424
#                        location_category = 'eprep'
425
#                        location_usage = 'internal'
426
#                        chained_location_type = 'fixed'
427
#                        chained_auto_packing = 'manual'
428
#                        chained_picking_type = 'internal'
429
#                        chained_location_id = location_stock_id[1]
430
#                        parent_location_id = location_id
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
431
                
432
                    if not parent_location_id:
433
                        raise osv.except_osv(_('Error'), _('Location \'Intermediate Stocks\' not found in the instance or is not activated !'))
434
                    
435
                    parent_location_id = parent_location_id[1]
436
                    
437
                    if not location_obj.browse(cr, uid, parent_location_id, context=context).active:
438
                        location_obj.write(cr, uid, [parent_location_id], {'active': True}, context=context)
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
439
                elif wizard.location_usage == 'consumption_unit':
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
440
                    location_category = 'consumption_unit'
441
                    location_usage = 'internal'
442
                    # Check if 'Internal Consumption Units' is active − If note activate it !
443
                    parent_location_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_consumption_units_view')
444
                    
445
                    parent_location_id = parent_location_id[1]
446
                
447
                    if not parent_location_id:
448
                        raise osv.except_osv(_('Error'), _('Location \'Internal Consumption Units\' not found in the instance or is not activated !'))
449
                    
450
                    if not location_obj.browse(cr, uid, parent_location_id, context=context).active:
451
                        location_obj.write(cr, uid, [parent_location_id], {'active': True}, context=context)
452
                else:
453
                    raise osv.except_osv(_('Error'), _('The type of the new location is not correct ! Please check the parameters and retry.'))
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
454
            elif wizard.location_type == 'customer' and wizard.location_usage == 'consumption_unit':
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
455
                location_category = 'consumption_unit'
456
                location_usage = 'customer'
457
                chained_picking_type = 'out'
458
                # Check if 'MSF Customer' location is active − If not, activate it !
459
                parent_location_id = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_internal_customers')
460
                if not parent_location_id:
461
                    raise osv.except_osv(_('Error'), _('Location \'MSF Customer\' not found in the instance or is not activated !'))
462
                                    
463
                parent_location_id = parent_location_id[1]
464
                    
465
                if not location_obj.browse(cr, uid, parent_location_id, context=context).active:
466
                    location_obj.write(cr, uid, [parent_location_id], {'active': True}, context=context)
467
            else:
468
                raise osv.except_osv(_('Error'), _('The type of the new location is not correct ! Please check the parameters and retry.'))
469
        
470
        if not parent_location_id or not location_category or not location_usage:
471
            raise osv.except_osv(_('Error'), _('Parent stock location not found for the new location !'))
472
        
431.10.12 by qt at tempo-consulting
UF-697 [FIX] Creation of optional SLoc : Fixed some issues on creation/re-activation of a SLoc
473
        if not location:
474
            # Create the new location
475
            location_obj.create(cr, uid, {'name': location_name,
476
                                          'location_id': parent_location_id,
477
                                          'location_category': location_category,
478
                                          'usage': location_usage,
479
                                          'chained_location_type': chained_location_type,
480
                                          'chained_auto_packing': chained_auto_packing,
481
                                          'chained_picking_type': chained_picking_type,
482
                                          'chained_location_id': chained_location_id,
483
                                          'optional_loc': True,
484
                                          }, context=context)
485
        else:
486
            # Reactivate the location
487
            location_obj.write(cr, uid, [location.id], {'active': True}, context=context)
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
488
        
489
        return_view_id = data_obj.get_object_reference(cr, uid, 'stock', 'view_location_tree')
490
        
491
        if return_view_id:
492
            return {'type': 'ir.actions.act_window',
559.31.11 by Quentin THEURET
UF-697 [FIX] Fix the unknow title when adding a new configurable location
493
                    'name': 'Locations Structure',
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
494
                    'res_model': 'stock.location',
495
                    'domain': [('location_id','=',False)],
496
                    'view_type': 'tree',
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
497
                    'target': 'crush',
431.10.7 by qt-tempo-consulting
UF-697 [IMP] Added a wizard to create a new optionnal stock location
498
                    'view_id': [return_view_id[1]],
499
                    }
500
        else:
501
            return {'type': 'ir.actions.act_window'}
502
    
503
stock_location_configuration_wizard()
504
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
505
506
class stock_remove_location_wizard(osv.osv_memory):
507
    _name = 'stock.remove.location.wizard'
508
    
509
    _columns = {
510
        'location_id': fields.many2one('stock.location', string='Location to remove'),
511
        'location_usage': fields.selection([('internal', 'Internal'), ('customer', 'External')], string='Location type'),
512
        'location_category': fields.selection([('eprep', 'EPREP'), ('stock', 'Stock'), ('consumption_unit', 'Consumption Unit')],
513
                                              string='Location type'),
514
        'error_message': fields.text(string='Information Message', readonly=True),
515
        'error': fields.boolean(string='Error'),
516
        'move_from_to': fields.boolean(string='Has a move from/to the location'),
517
        'not_empty': fields.boolean(string='Location not empty'),
518
        'has_child': fields.boolean(string='Location has children locations'),
519
    }
520
    
734 by jf
UF-846 [DEV] Stock refactoring
521
    def location_id_on_change(self, cr, uid, ids, location_id, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
522
        '''
523
        Check if no moves to this location aren't done
524
        Check if there is no stock in this location
525
        '''
526
        res = {'error_message': '', 
527
               'move_from_to': False, 
528
               'not_empty': False,
529
               'has_child': False}
530
        warning = {}
531
        error = False
532
        
533
        if location_id:
534
            location = self.pool.get('stock.location').browse(cr, uid, location_id, context=context)
535
            # Check if no moves to this location aren't done
536
            move_from_to = self.pool.get('stock.move').search(cr, uid, [('state', 'not in', ('done', 'cancel')), '|', ('location_id', '=', location.id), ('location_dest_id', '=', location.id)])
537
            if move_from_to:
538
                error = True
539
                res['move_from_to'] = True
540
                res['error_message'] += '''* You have at least one move from or to the location '%s' which is not 'Done'.
541
Please click on the 'See moves' button to see which moves are still in progress from/to this location.''' %location.name
542
                res['error_message'] += '\n' + '\n'
543
            # Check if no stock in the location
544
            if location.stock_real and location.usage == 'internal':
545
                error = True
546
                res['not_empty'] = True
547
                res['error_message'] += '''* The location '%s' is not empty of products. 
548
Please click on the 'Products in location' button to see which products are still in the location.''' %location.name
549
                res['error_message'] += '\n' + '\n'
550
551
            # Check if the location has children locations
552
            if location.child_ids:
553
                error = True
554
                res['has_child'] = True
555
                res['error_message'] += '''* The location '%s' has children locations.
556
Please remove all children locations before remove it. 
557
Please click on the 'Children locations' button to see all children locations.''' %location.name
558
                res['error_message'] += '\n' + '\n'
559
                
560
        if error:
561
            warning.update({'title': 'Be careful !',
562
                            'message': 'You have a problem with this location − Please see the message in the form for more information.'})
563
            
564
        res['error'] = error
565
        
566
        return {'value': res,
567
                'warning': warning}
568
        
734 by jf
UF-846 [DEV] Stock refactoring
569
    def check_error(self, cr, uid, ids, context=None):
431.10.9 by qt at tempo-consulting
UF-697 [IMP] Added the remove optional feature with removing parent optional location if is empty
570
        '''
571
        Check if errors are always here
572
        '''
573
        for wizard in self.browse(cr, uid, ids, context=context):
574
            errors = self.location_id_on_change(cr, uid, ids, wizard.location_id.id, context=context)
575
            self.write(cr, uid, ids, errors.get('value', {}), context=context)
576
            
577
        return {'type': 'ir.actions.act_window',
578
                'res_model': 'stock.remove.location.wizard',
579
                'res_id': wizard.id,
580
                'view_type': 'form',
581
                'view_mode': 'form',
582
                'target': 'new',}
583
        
734 by jf
UF-846 [DEV] Stock refactoring
584
    def location_usage_change(self, cr, uid, ids, usage, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
585
        if usage and usage == 'customer':
586
            return {'value': {'location_category': 'consumption_unit'}} 
587
        
588
        return {}
589
        
734 by jf
UF-846 [DEV] Stock refactoring
590
    def deactivate_location(self, cr, uid, ids, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
591
        '''
592
        Deactivate the selected location
593
        '''
431.10.9 by qt at tempo-consulting
UF-697 [IMP] Added the remove optional feature with removing parent optional location if is empty
594
        location = False
595
        data_obj = self.pool.get('ir.model.data')
596
        location_obj = self.pool.get('stock.location')
597
        configurable_loc_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_internal_client_view')[1]
598
        intermediate_loc_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_intermediate_client_view')[1]
599
        internal_cu_loc_id = data_obj.get_object_reference(cr, uid, 'msf_config_locations', 'stock_location_consumption_units_view')[1]
600
        
601
        for wizard in self.browse(cr, uid, ids, context=context):
602
            if wizard.error or wizard.has_child or wizard.not_empty or wizard.move_from_to:
603
                raise osv.except_osv(_('Error'), _('You cannot remove this location because some errors are still here !'))
604
            
605
            location = wizard.location_id
606
        
607
        # De-activate the location
608
        location_obj.write(cr, uid, [location.id], {'active': False}, context=context)
609
            
610
        # Check if parent location should be also de-activated
431.10.11 by qt at tempo-consulting
UF-697 [IMP] Moved Eprep locations under 'Configurable locations'
611
        if location.location_id.id in (intermediate_loc_id, internal_cu_loc_id, configurable_loc_id):
431.10.9 by qt at tempo-consulting
UF-697 [IMP] Added the remove optional feature with removing parent optional location if is empty
612
            empty = True
613
            for child in location.location_id.child_ids:
614
                if child.active:
615
                    empty = False
616
            if empty:
617
                location_obj.write(cr, uid, [location.location_id.id], {'active': False}, context=context)
618
                
619
                if location.location_id.location_id.id == configurable_loc_id:
620
                    empty2 = True
621
                    for child in location.location_id.location_id.child_ids:
622
                        if child.active:
623
                            empty2 = False
624
                    if empty2:
625
                        location_obj.write(cr, uid, [location.location_id.location_id.id], {'active': False}, context=context)
626
            
627
        return_view_id = data_obj.get_object_reference(cr, uid, 'stock', 'view_location_tree')
628
        
629
        if return_view_id:
630
            return {'type': 'ir.actions.act_window',
631
                    'res_model': 'stock.location',
632
                    'domain': [('location_id','=',False)],
633
                    'view_type': 'tree',
634
                    'target': 'crush',
635
                    'view_id': [return_view_id[1]],
636
                    }
637
        else:
638
            return {'type': 'ir.actions.act_window'}
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
639
    
734 by jf
UF-846 [DEV] Stock refactoring
640
    def see_moves(self, cr, uid, ids, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
641
        '''
642
        Returns all stock.picking containing a stock move not done from/to the location
643
        '''
644
        location = False
645
        picking_ids = []
646
        
647
        for wizard in self.browse(cr, uid, ids, context=context):
648
            location = wizard.location_id
649
            
650
        move_ids = self.pool.get('stock.move').search(cr, uid, [('state', 'not in', ('done', 'cancel')), '|', ('location_id', '=', location.id), ('location_dest_id', '=', location.id)])
651
        for move in self.pool.get('stock.move').browse(cr, uid, move_ids, context=context):
652
            if move.picking_id and move.picking_id.id not in picking_ids:
653
                picking_ids.append(move.picking_id.id)
654
                
655
        view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'vpicktree')[1]
656
        if location.usage == 'customer':
657
            view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'view_picking_out_tree')[1]
658
        
659
        return {'type': 'ir.actions.act_window',
660
                'res_model': 'stock.picking',
661
                'domain': [('id', 'in', picking_ids)],
662
                'view_id': [view_id],
663
                'view_type': 'form',
664
                'view_mode': 'tree,form',
665
                'target': 'current',
666
                }
667
        
734 by jf
UF-846 [DEV] Stock refactoring
668
    def products_in_location(self, cr, uid, ids, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
669
        '''
670
        Returns a list of products in the location
671
        '''
734 by jf
UF-846 [DEV] Stock refactoring
672
        if context is None:
673
            context = {}
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
674
        location = False
675
        
676
        for wizard in self.browse(cr, uid, ids, context=context):
677
            location = wizard.location_id
678
            
679
        context.update({'contact_display': 'partner', 'search_default_real':1, 
680
                        'search_default_location_type_internal':1,
681
                        'search_default_group_product':1,
682
                        'group_by':[], 'group_by_no_leaf':1})
683
        context.update({'search_default_location_id': location.id})
684
        
685
        return {'type': 'ir.actions.act_window',
686
                'res_model': 'report.stock.inventory',
687
                'view_type': 'form',
688
                'view_mode': 'tree',
689
                'domain': [('location_id', '=', location.id)],
690
                'context': context,
691
                'target': 'current'}
692
        
734 by jf
UF-846 [DEV] Stock refactoring
693
    def children_location(self, cr, uid, ids, context=None):
431.10.8 by qt-tempo-consulting
UF-697 [IMP] Remove the location : See all documents which generates error on deletion
694
        '''
695
        Returns the list of all children locations
696
        '''
697
        location_ids = []
698
        location = False
699
        
700
        for wizard in self.browse(cr, uid, ids, context=context):
701
            location = wizard.location_id
702
            
703
        for loc in location.child_ids:
704
            location_ids.append(loc.id)
705
            
706
        return {'type': 'ir.actions.act_window',
707
                'res_model': 'stock.location',
708
                'view_type': 'form',
709
                'view_mode': 'tree,form',
710
                'domain': [('id', 'in', location_ids)],
711
                'target': 'current',}
712
    
713
stock_remove_location_wizard()
714
734 by jf
UF-846 [DEV] Stock refactoring
715
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: