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

« back to all changes in this revision

Viewing changes to procurement_cycle/scheduler.py

  • Committer: jf
  • Date: 2012-01-10 20:57:37 UTC
  • mto: (559.2.21 unifield-wm)
  • mto: This revision was merged to the branch mainline in revision 562.
  • Revision ID: jf@ubuntu-20120110205737-gr6hukgf5ggimfup
Data supply

Show diffs side-by-side

added added

removed removed

Lines of Context:
205
205
        supplier_info_obj = self.pool.get('product.supplierinfo')
206
206
        location_obj = self.pool.get('stock.location')
207
207
        cycle_obj = self.pool.get('stock.warehouse.order.cycle')
 
208
        review_obj = self.pool.get('monthly.review.consumption')
 
209
        review_line_obj = self.pool.get('monthly.review.consumption.line')
208
210
        
209
 
        product = product_obj.browse(cr, uid, product_id)
210
 
        location = location_obj.browse(cr, uid, location_id)
 
211
        product = product_obj.browse(cr, uid, product_id, context=context)
 
212
        location = location_obj.browse(cr, uid, location_id, context=context)
211
213
 
212
214
        
213
215
        # Get the delivery lead time
214
 
        delivery_leadtime = product.procure_delay and product.procure_delay/30.0 or 1
 
216
        delivery_leadtime = product.seller_delay and product.seller_delay != 'N/A' and round(int(product.seller_delay)/30.0, 2) or 1
215
217
        if 'leadtime' in d_values and d_values.get('leadtime', 0.00) != 0.00:
216
218
            delivery_leadtime = d_values.get('leadtime')
217
219
        else:
219
221
            for supplier_info in product.seller_ids:
220
222
                if sequence and supplier_info.sequence < sequence:
221
223
                    sequence = supplier_info.sequence
222
 
                    delivery_leadtime = supplier_info.delay/30.0
 
224
                    delivery_leadtime = round(supplier_info.delay/30.0, 2)
223
225
                elif not sequence:
224
226
                    sequence = supplier_info.sequence
225
 
                    delivery_leadtime = supplier_info.delay/30.0
 
227
                    delivery_leadtime = round(supplier_info.delay/30.0, 2)
226
228
                
227
229
        # Get the monthly consumption
228
 
        monthly_consumption = 1.0
 
230
        monthly_consumption = 0.00
229
231
        
230
 
        if cycle_id.product_id and cycle_id.product_id.id and d_values.get('manual_consumption', 0.00) != 0.00:
231
 
            monthly_consumption = d_values.get('manual_consumption')
232
 
        elif 'reviewed_consumption' in d_values and d_values.get('reviewed_consumption'):
 
232
        if 'reviewed_consumption' in d_values and d_values.get('reviewed_consumption'):
233
233
            monthly_consumption = product.reviewed_consumption
 
234
        elif 'monthly_consumption' in d_values and d_values.get('monthly_consumption'):
 
235
            monthly_consumption = product.product_amc
234
236
        else:
235
 
            monthly_consumption = product.monthly_consumption
 
237
            monthly_consumption = d_values.get('manual_consumption', 0.00)
236
238
            
237
239
        # Get the order coverage
238
240
        order_coverage = d_values.get('coverage', 3)
240
242
        # Get the projected available quantity
241
243
        available_qty = self.get_available(cr, uid, product_id, location_id, monthly_consumption, d_values)
242
244
        
243
 
        return (delivery_leadtime * monthly_consumption) + (order_coverage * monthly_consumption) - available_qty
 
245
        qty_to_order = (delivery_leadtime * monthly_consumption) + (order_coverage * monthly_consumption) - available_qty
 
246
        
 
247
        return round(self.pool.get('product.uom')._compute_qty(cr, uid, product.uom_id.id, qty_to_order, product.uom_id.id), 2)
244
248
        
245
249
        
246
250
    def get_available(self, cr, uid, product_id, location_id, monthly_consumption, d_values={}, context={}):
262
266
                        'from_date': time.strftime('%Y-%m-%d')})
263
267
        
264
268
        product = product_obj.browse(cr, uid, product_id, context=context)
265
 
        
 
269
        location_name = location_obj.browse(cr, uid, location_id, context=context).name
 
270
 
266
271
        ''' Set this part of algorithm as comments because this algorithm seems to be equal to virtual stock
267
272
        
268
273
            To do validate by Magali
272
277
        
273
278
        # Get the available stock
274
279
        # Get the real stock
275
 
#        real_stock = product_obj.get_product_available(cr, uid, [product_id], context={'states': ['done'],
276
 
#                                                                                       'what': 'in', 
277
 
#                                                                                       'location': location_id,
278
 
#                                                                                       'compute_child': True, 
279
 
#                                                                                       'from_date': time.strftime('%Y-%m-%d')})
280
 
#        # Get the picked reservation
281
 
#        ## TODO: To confirm by Magali
 
280
        picked_resa = product_obj.get_product_available(cr, uid, [product_id], context={'states': ['assigned'],
 
281
                                                                                       'what': ('in, out'), 
 
282
                                                                                       'location': location_id,
 
283
                                                                                       'compute_child': True, 
 
284
                                                                                       'from_date': time.strftime('%Y-%m-%d')})
 
285
        # Get the picked reservation
 
286
        ## TODO: To confirm by Magali
282
287
#        picked_reservation = 0.00
283
288
#        move_ids = []
284
289
#        for location in location_obj.search(cr, uid, [('location_id', 'child_of', [location_id])]):
288
293
#            
289
294
#        for move in move_obj.browse(cr, uid, move_ids):
290
295
#            picked_reservation += move.product_qty
291
 
#        
292
 
#        available_stock = real_stock.get(product_id) - picked_reservation
293
 
#        
294
 
#        # Get the quantity on order
295
 
#        ## TODO : To confirm by Magali
 
296
            
 
297
        available_stock = product.qty_available - picked_resa.get(product.id)
 
298
        
 
299
        #available_stock = real_stock.get(product_id) - picked_reservation
 
300
        
 
301
        # Get the quantity on order
 
302
        ## TODO : To confirm by Magali
296
303
#        quantity_on_order = 0.00
297
304
#        move_ids = []
298
305
#        for location in location_obj.search(cr, uid, [('location_id', 'child_of', [location_id])]):
302
309
#        for move in move_obj.browse(cr, uid, move_ids):
303
310
#            quantity_on_order += move.product_qty
304
311
            
 
312
        quantity_on_order = product_obj.get_product_available(cr, uid, [product_id], context={'states': ['confirmed'],
 
313
                                                                                              'what': ('in, out'), 
 
314
                                                                                              'location': location_id,
 
315
                                                                                              'compute_child': True, 
 
316
                                                                                              'from_date': time.strftime('%Y-%m-%d')})
 
317
           
305
318
        # Get the safety stock
306
319
        safety_stock = d_values.get('safety', 0)
307
320
        
310
323
        
311
324
        # Get the expiry quantity
312
325
        # Set as comment because expiry quantity will be developed in a future sprint
313
 
#        expiry_quantity = self.get_expiry_qty(cr, uid, product_id, location_id, monthly_consumption, d_values)
314
 
        expiry_quantity = 0.00
315
 
        
 
326
        expiry_quantity = product_obj.get_expiry_qty(cr, uid, product_id, location_id, monthly_consumption, d_values)
 
327
        expiry_quantity = expiry_quantity and available_stock - expiry_quantity or 0.00
 
328
        #expiry_quantity = 0.00
 
329
 
316
330
        # Set this part of algorithm as comments because this algorithm seems to be equal to virtual stock
317
 
#        return available_stock + quantity_on_order - safety_stock - (safety_time * monthly_consumption) - expiry_quantity
 
331
        return available_stock + quantity_on_order.get(product.id) - safety_stock - (safety_time * monthly_consumption) - expiry_quantity
318
332
 
319
 
        return product.virtual_available - safety_stock - (safety_time * monthly_consumption) - expiry_quantity
320
 
     
321
 
     
322
 
    def get_expiry_qty(self, cr, uid, product_id, location_id, monthly_consumption, d_values={}, context={}):
323
 
        '''
324
 
        Compute the expiry quantities
325
 
        
326
 
        INFO : This method is not use on Sprint1 because the algorithm is
327
 
        not determined
328
 
        '''
329
 
        product_obj = self.pool.get('product.product')
330
 
        stock_obj = self.pool.get('stock.location')
331
 
        batch_obj = self.pool.get('stock.production.lot')
332
 
        move_obj = self.pool.get('stock.move')
333
 
        
334
 
        res = 0.00
335
 
        
336
 
        location_ids = stock_obj.search(cr, uid, [('location_id', 'child_of', location_id)])
337
 
        available_stock = 0.00
338
 
        
339
 
        # Get all batches for this product
340
 
        batch_ids = batch_obj.search(cr, uid, [('product_id', '=', product_id)], offset=0, limit=None, order='life_date')
341
 
        if len(batch_ids) == 1:
342
 
            # Search all moves with this batch number
343
 
            for location in location_ids:
344
 
                context.update({'location_id': location})
345
 
                available_stock += batch_obj.browse(cr, uid, batch_ids, context=context)[0].stock_available
346
 
            expiry_date = batch_obj.browse(cr, uid, batch_ids)[0].life_date or time.strftime('%Y-%m-%d')
347
 
            nb_month = self.get_diff_date(expiry_date)
348
 
            res = available_stock - (nb_month * monthly_consumption)
349
 
        else:
350
 
            # Get the stock available for the product
351
 
            for location in location_ids:
352
 
                context.update({'location_id': location})
353
 
                for batch in batch_obj.browse(cr, uid, batch_ids, context=context):
354
 
                    available_stock += batch.stock_available
355
 
                    
356
 
            last_nb_month = 0
357
 
            sum_nb_month = 0
358
 
            res = 0
359
 
            for batch in batch_obj.browse(cr, uid, batch_ids):
360
 
                nb_month = self.get_diff_date(batch.life_date)
361
 
                if (nb_month - sum_nb_month) > 0:
362
 
                    tmp_qty = (nb_month - sum_nb_month) * monthly_consumption 
363
 
                    res += available_stock - (last_nb_month * monthly_consumption) - tmp_qty
364
 
                else:
365
 
                    break 
366
 
            
367
 
        return res
 
333
#        return product.virtual_available - safety_stock - (safety_time * monthly_consumption) - expiry_quantity
368
334
    
369
335
    def get_diff_date(self, date):
370
336
        '''
371
337
        Returns the number of month between the date in parameter and today
372
338
        '''
373
339
        date = Parser.DateFromString(date)
374
 
        today = today()
 
340
        today = datetime.today()
375
341
        
376
342
        # The batch is expired
377
343
        if date.year < today.year or (date.year == today.year and date.month < today.month):