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

« back to all changes in this revision

Viewing changes to msf_cross_docking/cross_docking.py

  • Committer: jf
  • Date: 2012-06-13 12:43:21 UTC
  • mfrom: (827.5.11 uf-635)
  • Revision ID: jf@tempo4-20120613124321-2b8cwgl86gyy2tb7
UF-635 [DEV] Documents workflow: Graphic representation
lp:~unifield-team/unifield-wm/uf-635 revno 838

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2012 TeMPO Consulting, MSF, Smile
 
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
from tools.translate import _
 
25
import logging
 
26
import tools
 
27
from os import path
 
28
 
 
29
class purchase_order(osv.osv):
 
30
    '''
 
31
    Enables the option cross docking
 
32
    '''
 
33
    _name = 'purchase.order'
 
34
    _inherit = 'purchase.order'
 
35
 
 
36
    _columns = {
 
37
        'cross_docking_ok': fields.boolean('Cross docking'),
 
38
        'location_id': fields.many2one('stock.location', 'Destination', required=True, domain=[('usage','<>','view')], 
 
39
        help="""This location is set according to the Warehouse selected, or according to the option 'Cross docking' 
 
40
        or freely if you do not select 'Warehouse'.But if the 'Order category' is set to 'Transport' or 'Service', 
 
41
        you cannot have an other location than 'Service'"""),
 
42
    }
 
43
 
 
44
    _defaults = {
 
45
        'cross_docking_ok': False,
 
46
    }
 
47
    
 
48
    def onchange_internal_type(self, cr, uid, ids, order_type, partner_id, dest_partner_id=False, warehouse_id=False):
 
49
        '''
 
50
        Changes destination location
 
51
        '''
 
52
        res = super(purchase_order, self).onchange_internal_type(cr, uid, ids, order_type, partner_id, dest_partner_id, warehouse_id)
 
53
        if order_type == 'direct':
 
54
            location_id = self.onchange_cross_docking_ok(cr, uid, ids, False, warehouse_id)['value']['location_id']
 
55
        
 
56
            if 'value' in res:
 
57
                res['value'].update({'location_id': location_id})
 
58
            else:
 
59
                res.update({'value': {'location_id': location_id}})
 
60
        
 
61
        return res
 
62
 
 
63
    def onchange_cross_docking_ok(self, cr, uid, ids, cross_docking_ok, warehouse_id, context=None):
 
64
        """ Finds location id for changed cross_docking_ok.
 
65
        @param cross_docking_ok: Changed value of cross_docking_ok.
 
66
        @return: Dictionary of values.
 
67
        """
 
68
        if isinstance(ids, (int, long)):
 
69
            ids = [ids]
 
70
        obj_data = self.pool.get('ir.model.data')
 
71
        if cross_docking_ok:
 
72
            l = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
73
        else:
 
74
            warehouse_obj = self.pool.get('stock.warehouse')
 
75
            if not warehouse_id:
 
76
                warehouse_ids = warehouse_obj.search(cr, uid, [], limit=1)
 
77
                if not warehouse_ids:
 
78
                    return {'warning': {'title': _('Error !'), 'message': _('No Warehouse defined !')}, 'value': {'location_id': False}}
 
79
                warehouse_id = warehouse_ids[0]
 
80
            l = warehouse_obj.read(cr, uid, [warehouse_id], ['lot_input_id'])[0]['lot_input_id'][0]
 
81
        return {'value': {'location_id': l}}
 
82
    
 
83
    def onchange_location_id(self, cr, uid, ids, location_id, categ, context=None):
 
84
        """ If location_id == cross docking we tick the box "cross docking".
 
85
        @param location_id: Changed value of location_id.
 
86
        @return: Dictionary of values.
 
87
        """
 
88
        if isinstance(ids, (int, long)):
 
89
            ids = [ids]
 
90
        res = {}
 
91
        res['value'] = {}
 
92
        obj_data = self.pool.get('ir.model.data')
 
93
        if location_id == self.pool.get('stock.location').get_cross_docking_location(cr, uid) and categ not in ['service', 'transport']:
 
94
            cross_docking_ok = True
 
95
        elif location_id != self.pool.get('stock.location').get_cross_docking_location(cr, uid):
 
96
            cross_docking_ok = False
 
97
        elif location_id != self.pool.get('stock.location').get_service_location(cr, uid) and categ in ['service', 'transport']:
 
98
            return {'warning': {'title': _('Error !'), 'message': _("""
 
99
            If the 'Order Category' is 'Service' or 'Transport', you cannot have an other location than 'Service'
 
100
            """)}, 'value': {'location_id': self.pool.get('stock.location').get_service_location(cr, uid)}}
 
101
        res['value']['cross_docking_ok'] = cross_docking_ok
 
102
        return res
 
103
    
 
104
    def onchange_warehouse_id(self, cr, uid, ids,  warehouse_id, order_type, dest_address_id):
 
105
        """ Set cross_docking_ok to False when we change warehouse.
 
106
        @param warehouse_id: Changed id of warehouse.
 
107
        @return: Dictionary of values.
 
108
        """
 
109
        res = super(purchase_order, self).onchange_warehouse_id(cr, uid, ids,  warehouse_id, order_type, dest_address_id)
 
110
        if warehouse_id:
 
111
            res['value'].update({'cross_docking_ok': False})
 
112
        return res
 
113
    
 
114
    
 
115
    def onchange_categ(self, cr, uid, ids, categ, context=None):
 
116
        """ Sets cross_docking to False if the categ is service or transport.
 
117
        @param categ: Changed value of categ.
 
118
        @return: Dictionary of values.
 
119
        """
 
120
        if isinstance(ids, (int, long)):
 
121
            ids = [ids]
 
122
        obj_data = self.pool.get('ir.model.data')
 
123
        bool_value = None
 
124
        defined_location = None
 
125
        if categ in ['service', 'transport']:
 
126
            bool_value = False
 
127
            defined_location = self.pool.get('stock.location').get_service_location(cr, uid)
 
128
        return {'value': {'cross_docking_ok': bool_value, 'location_id':defined_location}}
 
129
 
 
130
    def write(self, cr, uid, ids, vals, context=None):
 
131
        if isinstance(ids, (int, long)):
 
132
            ids = [ids]
 
133
        obj_data = self.pool.get('ir.model.data')
 
134
        location_id = False
 
135
        cross_docking_ok = False
 
136
        active_id = context.get('active_id', False)
 
137
        order = self.browse(cr, uid, ids, context=context)[0]
 
138
        default_cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
139
        if vals.get('location_id', order.location_id.id):
 
140
            default_location_id = vals.get('location_id', order.location_id.id)
 
141
        elif order.warehouse_id.lot_input_id:
 
142
            default_location_id = order.warehouse_id.lot_input_id.id
 
143
        type_value = vals.get('order_type', order.order_type)
 
144
        if type_value == 'direct':
 
145
            vals.update({'cross_docking_ok': False})
 
146
        if  vals.get('cross_docking_ok'):
 
147
            cross_docking_ok = vals.get('cross_docking_ok')
 
148
        elif active_id:
 
149
            if self.read(cr, uid, [active_id],['cross_docking_ok'], context=context):
 
150
                cross_docking_ok = self.read(cr, uid, [active_id],['cross_docking_ok'], context=context)[0]['cross_docking_ok']
 
151
        if vals.get('location_id', False):
 
152
            location_id = vals.get('location_id', False)
 
153
        elif active_id:
 
154
            if self.read(cr, uid, [active_id],['cross_docking_ok'], context=context):
 
155
                location_id = self.read(cr, uid, [active_id],['location_id'], context=context)[0]['location_id'][0]
 
156
        if cross_docking_ok or location_id == default_cross_docking_location:
 
157
            if not vals.get('categ') in ['service', 'transport']:
 
158
                default_location_id = default_cross_docking_location
 
159
                vals.update({'location_id': default_location_id, 'cross_docking_ok': True})
 
160
            else:
 
161
                vals.update({'location_id': default_location_id, 'cross_docking_ok': False})
 
162
        elif not cross_docking_ok or location_id != default_cross_docking_location:
 
163
            if vals.get('categ') in ['service', 'transport']:
 
164
                default_location_id = self.pool.get('stock.location').get_service_location(cr, uid)
 
165
                vals.update({'location_id': default_location_id, 'cross_docking_ok': False})
 
166
            else:
 
167
                vals.update({'location_id': default_location_id, 'cross_docking_ok': False})
 
168
        elif location_id == self.pool.get('stock.location').get_cross_docking_location(cr, uid):
 
169
            vals.update({'location_id': default_cross_docking_location, 'cross_docking_ok': True})
 
170
        return super(purchase_order, self).write(cr, uid, ids, vals, context=context)
 
171
 
 
172
    def create(self, cr, uid, vals, context=None):
 
173
        obj_data = self.pool.get('ir.model.data')
 
174
        if vals.get('order_type') == 'direct':
 
175
            vals.update({'cross_docking_ok': False})
 
176
        if vals.get('cross_docking_ok'):
 
177
            vals.update({'location_id': self.pool.get('stock.location').get_cross_docking_location(cr, uid)})
 
178
        return super(purchase_order, self).create(cr, uid, vals, context=context)
 
179
    
 
180
    def _check_cross_docking(self, cr, uid, ids, context=None):
 
181
        """
 
182
        Check that if you select cross docking, you do not have an other location than cross docking
 
183
        """
 
184
        if isinstance(ids, (int, long)):
 
185
            ids = [ids]
 
186
        if context is None:
 
187
            context = {}
 
188
        obj_data = self.pool.get('ir.model.data')
 
189
        cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
190
        for purchase in self.browse(cr, uid, ids, context=context):
 
191
            if purchase.cross_docking_ok and purchase.location_id.id != cross_docking_location:
 
192
                raise osv.except_osv(_('Warning !'), _('If you tick the box \"cross docking\", you cannot have an other location than \"Cross docking\"'))
 
193
            else:
 
194
                return True
 
195
 
 
196
    _constraints = [
 
197
        (_check_cross_docking, 'If you tick the box \"cross docking\", you cannot have an other location than \"Cross docking\"', ['location_id']),
 
198
    ]
 
199
 
 
200
purchase_order()
 
201
 
 
202
class procurement_order(osv.osv):
 
203
 
 
204
    _inherit = 'procurement.order'
 
205
    
 
206
    def po_values_hook(self, cr, uid, ids, context=None, *args, **kwargs):
 
207
        '''
 
208
        When you run the scheduler and you have a sale order line with type = make_to_order,
 
209
        we modify the location_id to set 'cross docking' of the purchase order created in mirror
 
210
        '''
 
211
        if context is None:
 
212
            context = {}
 
213
        if isinstance(ids, (int, long)):
 
214
            ids = [ids]
 
215
        sol_obj = self.pool.get('sale.order.line')
 
216
        obj_data = self.pool.get('ir.model.data')
 
217
        procurement = kwargs['procurement']
 
218
        
 
219
        values = super(procurement_order, self).po_values_hook(cr, uid, ids, context=context, *args, **kwargs)
 
220
        ids = sol_obj.search(cr, uid, [('procurement_id', '=', procurement.id)], context=context)
 
221
        if len(ids):
 
222
            values.update({'cross_docking_ok': True, 'location_id' : self.pool.get('stock.location').get_cross_docking_location(cr, uid)})
 
223
        return values  
 
224
 
 
225
procurement_order()
 
226
 
 
227
class stock_picking(osv.osv):
 
228
    '''
 
229
    do_partial(=function which is originally called from delivery_mechanism) modification 
 
230
    for the selection of the LOCATION for IN (incoming shipment) and OUT (delivery orders)
 
231
    '''
 
232
    _inherit = 'stock.picking'
 
233
 
 
234
    def init(self, cr):
 
235
        """
 
236
        Load msf_cross_docking_data.xml before self
 
237
        """
 
238
        if hasattr(super(stock_picking, self), 'init'):
 
239
            super(stock_picking, self).init(cr)
 
240
 
 
241
        mod_obj = self.pool.get('ir.module.module')
 
242
        logging.getLogger('init').info('HOOK: module msf_cross_docking: loading data/msf_msf_cross_docking_data.xml')
 
243
        pathname = path.join('msf_cross_docking', 'data/msf_cross_docking_data.xml')
 
244
        file = tools.file_open(pathname)
 
245
        tools.convert_xml_import(cr, 'msf_cross_docking', file, {}, mode='init', noupdate=False)
 
246
 
 
247
    _columns = {
 
248
        'cross_docking_ok': fields.boolean('Cross docking'),
 
249
    }
 
250
    
 
251
    '''
 
252
    do_partial(=function which is originally called from delivery_mechanism) modification 
 
253
    for the selection of the LOCATION for IN (incoming shipment) and OUT (delivery orders)
 
254
    '''
 
255
 
 
256
    def write(self, cr, uid, ids, vals, context=None):
 
257
        """
 
258
        Here we check if all stock move are in stock or in cross docking
 
259
        """
 
260
        if context is None:
 
261
            context = {}
 
262
        if isinstance(ids, (int, long)):
 
263
            ids = [ids]
 
264
        obj_data = self.pool.get('ir.model.data')
 
265
        move_obj = self.pool.get('stock.move')
 
266
        pick_obj = self.pool.get('stock.picking')
 
267
        cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
268
        for pick in pick_obj.browse(cr,uid,ids,context=context):
 
269
            move_lines = pick.move_lines
 
270
            if len(move_lines) >= 1 :
 
271
                for move in move_lines:
 
272
                    move_ids = move.id
 
273
                    for move in move_obj.browse(cr,uid,[move_ids],context=context):
 
274
                        move_cross_docking_ok_value = move_obj.read(cr, uid, [move_ids], ['move_cross_docking_ok'], context=context)
 
275
                        if move.move_cross_docking_ok == True:
 
276
                            vals.update({'cross_docking_ok': True,})
 
277
                        elif move.move_cross_docking_ok == False:
 
278
                            vals.update({'cross_docking_ok': False,})
 
279
        return super(stock_picking, self).write(cr, uid, ids, vals, context=context)
 
280
 
 
281
    def button_cross_docking_all (self, cr, uid, ids, context=None):
 
282
        """
 
283
        set all stock moves with the source location to 'cross docking'
 
284
        """
 
285
        if context is None:
 
286
            context = {}
 
287
        if isinstance(ids, (int, long)):
 
288
            ids = [ids]
 
289
        obj_data = self.pool.get('ir.model.data')
 
290
        move_obj = self.pool.get('stock.move')
 
291
        pick_obj = self.pool.get('stock.picking')
 
292
        cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
293
        for pick in pick_obj.browse(cr,uid,ids,context=context):
 
294
            move_lines = pick.move_lines
 
295
            if len(move_lines) >= 1 :
 
296
                for move in move_lines:
 
297
                    move_ids = move.id
 
298
                    for move in move_obj.browse(cr,uid,[move_ids],context=context):
 
299
                        # Don't change done stock moves
 
300
                        if move.state != 'done':
 
301
                            move_obj.write(cr, uid, [move_ids], {'location_id': cross_docking_location, 'move_cross_docking_ok': True}, context=context)
 
302
                self.write(cr, uid, ids, {'cross_docking_ok': True}, context=context)
 
303
            else :
 
304
                raise osv.except_osv(_('Warning !'), _('Please, enter some stock moves before changing the source location to CROSS DOCKING'))
 
305
        # we check availability : cancel then check
 
306
        self.cancel_assign(cr, uid, ids)
 
307
        self.action_assign(cr, uid, ids)
 
308
        return False
 
309
 
 
310
    def button_stock_all (self, cr, uid, ids, context=None):
 
311
        """
 
312
        set all stock move with the source location to 'stock'
 
313
        """
 
314
        if context is None:
 
315
            context = {}
 
316
        if isinstance(ids, (int, long)):
 
317
            ids = [ids]
 
318
        obj_data = self.pool.get('ir.model.data')
 
319
        move_obj = self.pool.get('stock.move')
 
320
        pick_obj = self.pool.get('stock.picking')
 
321
        for pick in pick_obj.browse(cr,uid,ids,context=context):
 
322
            move_lines = pick.move_lines
 
323
            if len(move_lines) >= 1 :
 
324
                for move in move_lines:
 
325
                    move_ids = move.id
 
326
                    for move in move_obj.browse(cr,uid,[move_ids],context=context):
 
327
                        # Don't change done stock moves
 
328
                        if move.state != 'done':
 
329
                            move_obj.write(cr, uid, [move_ids], {'location_id': pick.warehouse_id.lot_stock_id.id, 'move_cross_docking_ok': False}, context=context)
 
330
                self.write(cr, uid, ids, {'cross_docking_ok': False}, context=context)
 
331
            else :
 
332
                raise osv.except_osv(_('Warning !'), _('Please, enter some stock moves before changing the source location to STOCK'))
 
333
        # we check availability : cancel then check
 
334
        self.cancel_assign(cr, uid, ids)
 
335
        self.action_assign(cr, uid, ids)
 
336
        return False
 
337
 
 
338
    def _do_incoming_shipment_first_hook(self, cr, uid, ids, context=None, *args, **kwargs):
 
339
        '''
 
340
        This hook refers to delivery_mechanism>delivery_mechanism.py>_do_incoming_shipment.
 
341
        It updates the location_dest_id (to cross docking or to stock) 
 
342
        of selected stock moves when the linked 'incoming shipment' is validated
 
343
        -> only related to 'in' type stock.picking
 
344
        '''
 
345
        values = super(stock_picking, self)._do_incoming_shipment_first_hook(cr, uid, ids, context=context, *args, **kwargs)
 
346
        assert values is not None, 'missing values'
 
347
 
 
348
        if context is None:
 
349
            context = {}
 
350
        if isinstance(ids, (int, long)):
 
351
            ids = [ids]
 
352
       
 
353
        # take ids of the wizard from the context. 
 
354
        # NB: the wizard_ids is created in delivery_mechanism>delivery_mecanism.py> in the method "_stock_picking_action_process_hook"
 
355
        wiz_ids = context.get('wizard_ids')
 
356
        res = {}
 
357
        if not wiz_ids:
 
358
            return res
 
359
 
 
360
# ------ referring to locations 'cross docking' and 'stock' ------------------------------------------------------
 
361
        obj_data = self.pool.get('ir.model.data')
 
362
        cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
363
        stock_location_input = obj_data.get_object_reference(cr, uid, 'msf_cross_docking', 'stock_location_input')[1]
 
364
# ----------------------------------------------------------------------------------------------------------------
 
365
        partial_picking_obj = self.pool.get('stock.partial.picking')
 
366
        
 
367
        # We browse over the wizard (stock.partial.picking)
 
368
        for var in partial_picking_obj.browse(cr, uid, wiz_ids, context=context):
 
369
            """For incoming shipment """
 
370
            # we check the dest_type for INCOMING shipment (and not the source_type which is reserved for OUTGOING shipment)
 
371
            if var.dest_type == 'to_cross_docking':
 
372
                # below, "source_type" is only used for the outgoing shipment. We set it to "None" because by default it is "default"and we do not want that info on INCOMING shipment
 
373
                var.source_type = None
 
374
                product_id = values['product_id']
 
375
                product_type = self.pool.get('product.product').read(cr, uid, product_id, ['type'], context=context)['type']
 
376
                if product_type not in ('service_recep', 'service'):
 
377
                    # treat moves towards CROSS DOCKING if NOT SERVICE
 
378
                    values.update({'location_dest_id': cross_docking_location})
 
379
            elif var.dest_type == 'to_stock' :
 
380
                var.source_type = None
 
381
                # below, "source_type" is only used for the outgoing shipment. We set it to "None" because by default it is "default"and we do not want that info on INCOMING shipment
 
382
                product_id = values['product_id']
 
383
                product_type = self.pool.get('product.product').read(cr, uid, product_id, ['type'], context=context)['type']
 
384
                if product_type not in ('service_recep', 'service'):
 
385
                    # treat moves towards STOCK if NOT SERVICE
 
386
                    values.update({'location_dest_id': stock_location_input})
 
387
        return values
 
388
    
 
389
    def _do_partial_hook(self, cr, uid, ids, context, *args, **kwargs):
 
390
        '''
 
391
        hook to update defaults data of the current object, which is stock.picking.
 
392
        The defaults data are taken from the _do_partial_hook which is on the stock_partial_picking
 
393
        osv_memory object used for the wizard of deliveries.
 
394
        For outgoing shipment 
 
395
        '''
 
396
        if isinstance(ids, (int, long)):
 
397
            ids = [ids]
 
398
        # variable parameters
 
399
        move = kwargs.get('move')
 
400
        assert move, 'missing move'
 
401
        partial_datas = kwargs.get('partial_datas')
 
402
        assert partial_datas, 'missing partial_datas'
 
403
        
 
404
        # calling super method
 
405
        defaults = super(stock_picking, self)._do_partial_hook(cr, uid, ids, context, *args, **kwargs)
 
406
        # location_id is equivalent to the source location: does it exist when we go through the "_do_partial_hook" in the msf_cross_docking> stock_partial_piking> "do_partial_hook"
 
407
        location_id = partial_datas.get('move%s'%(move.id), False).get('location_id')
 
408
        if location_id:
 
409
            defaults.update({'location_id': location_id})
 
410
        
 
411
        return defaults
 
412
    
 
413
stock_picking()
 
414
 
 
415
class stock_move(osv.osv):
 
416
    _inherit = 'stock.move'
 
417
    """
 
418
    The field below 'move_cross_docking_ok' is used solely for the view using attrs. I has been named especially 
 
419
    'MOVE_cross_docking_ok' for not being in conflict with the other 'cross_docking_ok' in the stock.picking object 
 
420
    which also uses attrs according to the value of cross_docking_ok'.
 
421
    """
 
422
    _columns = {
 
423
        'move_cross_docking_ok': fields.boolean('Cross docking'),
 
424
    }
 
425
    
 
426
    def default_get(self, cr, uid, fields, context=None):
 
427
        """ To get default values for the object:
 
428
        If cross docking is checked on the purchase order, we set "cross docking" to the destination location
 
429
        else we keep the default values i.e. "Input"
 
430
        """
 
431
        default_data = super(stock_move, self).default_get(cr, uid, fields, context=context)
 
432
        if context is None:
 
433
            context = {}
 
434
        purchase_id = context.get('purchase_id', [])
 
435
        if not purchase_id:
 
436
            return default_data
 
437
        
 
438
        obj_data = self.pool.get('ir.model.data')
 
439
        purchase_browse = self.pool.get('purchase.order').browse(cr, uid, purchase_id, context=context)
 
440
        # If the purchase order linked has the option cross docking then the new created stock move should have the destination location to cross docking
 
441
        if purchase_browse.cross_docking_ok:
 
442
            default_data.update({'location_dest_id': self.pool.get('stock.location').get_cross_docking_location(cr, uid)})
 
443
        return default_data
 
444
    
 
445
    def button_cross_docking (self, cr, uid, ids, context=None):
 
446
        """
 
447
        for each stock move we enable to change the source location to cross docking
 
448
        """
 
449
        if context is None:
 
450
            context = {}
 
451
        if isinstance(ids, (int, long)):
 
452
            ids = [ids]
 
453
        obj_data = self.pool.get('ir.model.data')
 
454
        cross_docking_location = self.pool.get('stock.location').get_cross_docking_location(cr, uid)
 
455
 
 
456
        todo = []
 
457
        for move in self.browse(cr, uid, ids, context=context):
 
458
            if move.state != 'done': 
 
459
                todo.append(move.id)
 
460
        ret = True
 
461
        if todo:
 
462
            ret = self.write(cr, uid, todo, {'location_id': cross_docking_location, 'move_cross_docking_ok': True}, context=context)
 
463
 
 
464
            # below we cancel availability to recheck it
 
465
            stock_picking_id = self.read(cr, uid, todo, ['picking_id'], context=context)[0]['picking_id'][0]
 
466
            # we cancel availability
 
467
            self.pool.get('stock.picking').cancel_assign(cr, uid, [stock_picking_id])
 
468
            # we recheck availability
 
469
            self.pool.get('stock.picking').action_assign(cr, uid, [stock_picking_id])
 
470
        return ret
 
471
 
 
472
    def button_stock (self, cr, uid, ids, context=None):
 
473
        """
 
474
        for each stock move we enable to change the source location to stock
 
475
        """
 
476
        if context is None:
 
477
            context = {}
 
478
        if isinstance(ids, (int, long)):
 
479
            ids = [ids]
 
480
        obj_data = self.pool.get('ir.model.data')
 
481
        
 
482
        todo = []
 
483
        for move in self.browse(cr, uid, ids, context=context):
 
484
            if move.state != 'done':
 
485
                self.write(cr, uid, move.id, {'location_id': move.picking_id.warehouse_id.lot_stock_id.id, 'move_cross_docking_ok': False}, context=context)
 
486
                todo.append(move.id)
 
487
 
 
488
        if todo:
 
489
            # below we cancel availability to recheck it
 
490
            stock_picking_id = self.read(cr, uid, todo, ['picking_id'], context=context)[0]['picking_id'][0]
 
491
            # we cancel availability
 
492
            self.pool.get('stock.picking').cancel_assign(cr, uid, [stock_picking_id])
 
493
            # we recheck availability
 
494
            self.pool.get('stock.picking').action_assign(cr, uid, [stock_picking_id])
 
495
        return True
 
496
 
 
497
stock_move()