Merge lp:~openbig/bigconsulting/automatically_scanned_qanutity into lp:bigconsulting

Proposed by gpa(OpenERP)
Status: Merged
Merged at revision: 76
Proposed branch: lp:~openbig/bigconsulting/automatically_scanned_qanutity
Merge into: lp:bigconsulting
Diff against target: 446 lines (+233/-132)
4 files modified
packing_barcode_check/packing_barcode_check.py (+2/-2)
packing_barcode_check/wizard/select_picking.py (+1/-0)
stock_minimum_calculator/stock_minimum_calculator_wizard.xml (+1/-1)
stock_minimum_calculator/wizard/stock_order_point_calculator.py (+229/-129)
To merge this branch: bzr merge lp:~openbig/bigconsulting/automatically_scanned_qanutity
Reviewer Review Type Date Requested Status
openbig Pending
Review via email: mp+32764@code.launchpad.net

Description of the change

solved the problem of not increment bug/616645

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'packing_barcode_check/packing_barcode_check.py'
2--- packing_barcode_check/packing_barcode_check.py 2010-08-11 12:37:21 +0000
3+++ packing_barcode_check/packing_barcode_check.py 2010-08-16 13:34:43 +0000
4@@ -31,8 +31,8 @@
5 def _compute_quantity(self, cr, uid, ids, fieldnames, args, context=None):
6 res = {}
7 for obj in self.browse(cr, uid, ids, context=context):
8- total_quantity = sum(move_id.product_qty for move_id in obj.move_lines)
9- scanned_quantity = sum(scan.scan_quantity for scan in obj.scaned_ids)
10+ total_quantity = sum(to_be_id.quantity for to_be_id in obj.tobe_scan_ids)
11+ scanned_quantity = sum(to_be_id.scan_quantity for to_be_id in obj.tobe_scan_ids)
12 res[obj.id] = {
13 'total_quantity' : total_quantity,
14 'scanned_quantity' : scanned_quantity,
15
16=== modified file 'packing_barcode_check/wizard/select_picking.py'
17--- packing_barcode_check/wizard/select_picking.py 2010-08-11 13:15:42 +0000
18+++ packing_barcode_check/wizard/select_picking.py 2010-08-16 13:34:43 +0000
19@@ -47,6 +47,7 @@
20 'res_model': 'stock.picking',
21 'type': 'ir.actions.act_window',
22 'view_id':[resource_id],
23+ 'auto_refresh':1,
24 'res_id':data['form']['picking_id'],
25 'context':"{'contact_display':'partner'}",
26 }
27
28=== modified file 'stock_minimum_calculator/stock_minimum_calculator_wizard.xml'
29--- stock_minimum_calculator/stock_minimum_calculator_wizard.xml 2010-07-27 09:27:59 +0000
30+++ stock_minimum_calculator/stock_minimum_calculator_wizard.xml 2010-08-16 13:34:43 +0000
31@@ -9,7 +9,7 @@
32 id="id_set_seasonal_trend"/>
33 <wizard
34 string="Order Point Cacluator"
35- model="product.product"
36+ model="res.partner"
37 name="orderpoint.calculator"
38 menu="True"
39 id="id_order_point_cacluator"/>
40
41=== modified file 'stock_minimum_calculator/wizard/stock_order_point_calculator.py'
42--- stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-08-04 13:12:02 +0000
43+++ stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-08-16 13:34:43 +0000
44@@ -34,13 +34,9 @@
45 <field name="warehouse_id"/>
46 <field name="location_id"/>
47 <field name="seasonal_id"/>
48+ <field name="max_qty_factor"/>
49 <field name="delactive"/>
50 <field name="method_qty_calculation" colspan="4"/>
51- <group attrs="{'invisible':[('method_qty_calculation','=','his_cons_without_product')]}" colspan="4">
52- <separator string="Configuration of Base Consumptions Periods" colspan="4"/>
53- <field name="date_start"/>
54- <field name="date_stop"/>
55- </group>
56 </form>"""
57
58 orderpoint_calculator_fields = {
59@@ -70,24 +66,19 @@
60 'required': True,
61 'help':'Use this field as index. Reference index is Main Season with 1.00. If you want to change the orderpoint rules you are able to define new season with a seasonal index. This index should reference to 1.00. For example if you expect - 10% consumption for autumn season in comparition to main season enter 0.90.'
62 },
63-
64- 'date_start': {
65- 'string':'From Date',
66- 'type':'date'
67- },
68-
69- 'date_stop': {
70- 'string':'To Date',
71- 'type':'date',
72- 'default': lambda *a: time.strftime('%Y-%m-%d')
73+
74+ 'max_qty_factor': {
75+ 'string':'Max. Qty. Factor',
76+ 'type':'float',
77+ 'required': True
78 },
79
80 'method_qty_calculation':{
81 'string':"Method Calculation",
82 'type':'selection',
83- 'selection':[('his_cons_with_product', 'Calculate with historical consumptions of products'),
84+ 'selection':[('his_cons_with_product', 'Calculate with planning values'),
85 ('his_cons_without_product', 'Calculate with Out historical consumptions of product'),
86- ('hist_cons_and_open_sale', 'Calculate with historical consumptions of product and Open sales orders'),
87+ ('hist_cons_and_open_sale', 'Calculate with historical values'),
88 ],'required': True,
89 'default': lambda *a:'his_cons_with_product'
90 },
91@@ -116,16 +107,99 @@
92
93 return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':from_date,'seasonal_id':seasonal_id}
94
95+
96+def _sale_consume_qty(self, cr, uid, product_id, from_date, to_date, state, context):
97+ """calculation of consumption of product from_date to to_date , where state is done """
98+
99+ pool = pooler.get_pool(cr.dbname)
100+
101+ sale_obj = pool.get('sale.order')
102+ sale_line_obj = pool.get("sale.order.line")
103+ consum_qty = 0.0
104+ sale_ids = sale_obj.search(cr,uid,[('date_order','>=',from_date),('date_order','<=',to_date), ('state','=',state)])
105+ if sale_ids:
106+ for sid in sale_ids:
107+ sale_line_id = sale_line_obj.search(cr,uid,[('order_id','=',sid),('product_id','=',product_id)])
108+ for line_id in sale_line_id:
109+ sale_line_data= sale_line_obj.browse(cr, uid, line_id, context=context).product_uom_qty
110+ consum_qty += sale_line_data
111+
112+ return consum_qty
113+
114+def _sale_open_qty(self, cr, uid, product_id, state, context):
115+ """Calculation of open sale orders"""
116+
117+ pool = pooler.get_pool(cr.dbname)
118+
119+ sale_obj = pool.get('sale.order')
120+ sale_line_obj = pool.get("sale.order.line")
121+ open_sale_qty = 0.0
122+ open_sale_ids = sale_obj.search(cr, uid, [('state','in',state)])
123+ if open_sale_ids:
124+ for sale_id in open_sale_ids:
125+ sale_open_line_ids = sale_line_obj.search(cr,uid,[('order_id','=',sale_id),('product_id','=',product_id)])
126+ for open_line_id in sale_open_line_ids:
127+ sale_line_data= sale_line_obj.browse(cr,uid,open_line_id)
128+ open_sale_qty += sale_line_data.product_uom_qty
129+
130+ return open_sale_qty
131+
132+def _purchase_open_qty(self, cr, uid, product_id, state, context):
133+ """ Calculation of open purchase orders """
134+
135+ pool = pooler.get_pool(cr.dbname)
136+
137+ purchase_obj = pool.get('purchase.order')
138+ purchase_order_line_obj = pool.get('purchase.order.line')
139+ open_purchase_qty = 0.0
140+ open_purchase_ids = purchase_obj.search(cr,uid,[('state','=',state)])
141+ if open_purchase_ids:
142+ for purchase_id in open_purchase_ids:
143+ open_purchase_line_ids= purchase_order_line_obj.search(cr,uid,[('order_id','=',purchase_id),('product_id','=',product_id)])
144+ for open_pur_id in open_purchase_line_ids:
145+ purchase_line_data = purchase_order_line_obj.browse(cr, uid, open_pur_id, context=context)
146+ open_purchase_qty += purchase_line_data.product_qty
147+
148+ return open_purchase_qty
149+
150+def _refund_qty(self, cr, uid, product_id, from_date, to_date, state, context):
151+ """ Calculation of the refund quantities of the prduct from the refund invoice, between from_date, to_date"""
152+
153+ pool = pooler.get_pool(cr.dbname)
154+
155+ account_invoice_obj = pool.get('account.invoice')
156+ account_invoice_line_obj = pool.get('account.invoice.line')
157+ refund_qty = 0.0
158+ refund_invoice_ids = account_invoice_obj.search(cr,uid,[('type','in',state),('date_invoice','>=',from_date),('date_invoice','<=',to_date)])
159+ for refund_id in refund_invoice_ids:
160+ invoie_line_ids = account_invoice_line_obj.search(cr,uid,[('invoice_id','=',refund_id),('product_id','=',product_id)])
161+ for invoice_line_id in invoie_line_ids:
162+ inovice_line_data = account_invoice_line_obj.browse(cr, uid, invoice_line_id, context=context).quantity
163+ refund_qty += inovice_line_data
164+
165+ return refund_qty
166+
167+
168+def _date_diff(self, cr, uid, product_id, from_date, to_date, context):
169+ """ Date difference between from_date and to_date """
170+
171+ first_date = time.mktime(time.strptime(from_date,'%Y-%m-%d %H:%M:%S'))
172+ last_date = time.mktime(time.strptime(to_date,'%Y-%m-%d %H:%M:%S'))
173+ diff_day = (last_date-first_date)/(3600*24)
174+ return diff_day
175+
176 def _do_calculate(self, cr, uid, data, context):
177 pool = pooler.get_pool(cr.dbname)
178
179 purchase_obj = pool.get('purchase.order')
180- sale_obj = pool.get('sale.order')
181+ purchase_order_line_obj = pool.get('purchase.order.line')
182 product_obj = pool.get('product.product')
183 supp_obj = pool.get('product.supplierinfo')
184 supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time')
185 min_rule_obj = pool.get('stock.warehouse.orderpoint')
186 seasonal_obj = pool.get('product.seasonal')
187+ stock_move_obj = pool.get('stock.move')
188+
189 ##### Calculation of purchase lead time
190 purchase_lead_time = 0.0
191 company = pool.get('res.users').browse(cr, uid, uid, context).company_id
192@@ -135,117 +209,143 @@
193 seasonal_id = data['form']['seasonal_id']
194 seasonal_data = seasonal_obj.browse(cr, uid, seasonal_id)
195 seasonal_factor = seasonal_data.seasonal_factor
196-
197- ##### Calculation of supplier lead time
198-
199- for id in data['ids']:
200- product_id = product_obj.browse(cr, uid, id, context)
201- supplier_lead_time = 0.0
202- if product_id:
203- for supp in product_id.seller_ids:
204- sup = supp_obj.browse(cr, uid, supp.id, context)
205- supplier_lead_time = sup.delay
206-
207- ###### Calculation of average_daily_consumption
208- date_start = data['form']['date_start']
209- date_stop = data['form']['date_stop']
210- average_daily_consumption = 0.0
211- sale_line_obj = pool.get("sale.order.line")
212- consum_qty = 0.0
213- sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)])
214- if sale_ids:
215- for sid in sale_ids:
216- sale_line_id = sale_line_obj.search(cr,uid,[('order_id','=',sid),('product_id','=',product_id.id)])
217- for line_id in sale_line_id:
218- sale_line_data= sale_line_obj.browse(cr,uid,line_id)
219- consum_qty += sale_line_data.product_uom_qty
220- ###here consume quantity is total of selected product
221- ##################calculation of date difference between first and last sale order
222- sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)], order='date_order asc')
223- if sale_ids:
224- start_sale_id = sale_ids[0]
225- last_sale_id = sale_ids[-1]
226- first_sale_date = sale_obj.browse(cr,uid,start_sale_id).date_order
227- last_sale_date = sale_obj.browse(cr,uid,last_sale_id).date_order
228- first_date = time.mktime(time.strptime(first_sale_date,'%Y-%m-%d'))
229- last_date = time.mktime(time.strptime(last_sale_date,'%Y-%m-%d'))
230- diff_day = (last_date-first_date)/(3600*24)
231- if diff_day > 0:
232- average_daily_consumption = consum_qty / diff_day
233- ###### Calculation of plan_average_daily_consumption
234- plan_average_daily_consumption = 0.0
235- if product_id.plan_avg_consume:
236- plan_average_daily_consumption = product_id.plan_avg_consume
237-
238- ####### get location #####
239- location_id = data['form']['location_id']
240-
241- ########## calculation historical consumption of products and open sales orders“
242- ### total sale qty with open state
243-
244- sale_qty = 0.0
245- open_sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])])
246- if sale_ids:
247- for sale_id in open_sale_ids:
248- sale_open_line_ids= sale_line_obj.search(cr,uid,[('order_id','=',sale_id),('product_id','=',product_id.id)])
249- for open_line_id in sale_open_line_ids:
250- sale_line_data= sale_line_obj.browse(cr,uid,open_line_id)
251- sale_qty += sale_line_data.product_uom_qty
252- ###################
253- purchase_ids = purchase_obj.search(cr,uid,[])
254- if purchase_ids:
255- start_pur_id = min(purchase_ids)
256- last_pur_id = max(purchase_ids)
257-
258- ##################calculation of date difference between first and last purchase order
259- first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order
260- last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order
261- first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d'))
262- last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d'))
263- pur_diff_day = (last_date-first_date)/(3600*24)
264- product_max_qty = 0.0
265- product_min_qty = 0.0
266-
267- if data['form']['method_qty_calculation'] == 'his_cons_with_product':
268- product_min_qty = int(math.ceil(average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
269- product_max_qty = 2 * product_min_qty
270-
271- elif data['form']['method_qty_calculation'] == 'his_cons_without_product':
272- product_min_qty = int(math.ceil(plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
273- product_max_qty = 2 * product_min_qty
274-
275- else:
276- try:
277- product_min_qty = int(math.ceil((consum_qty + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
278- except Exception,e:
279- product_min_qty = 0.0
280- product_max_qty = 2 * product_min_qty
281-
282- if data['form']['delactive']:
283- stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)])
284- for stock_rule_id in stock_rule_ids:
285- min_rule_obj.unlink(cr, uid, [stock_rule_id],context=context)
286-
287- mini_stock_rule_id = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)])
288- if mini_stock_rule_id:
289- for stock_rule_id in mini_stock_rule_id:
290- min_rule_obj.write(cr, uid, [stock_rule_id],{'product_min_qty':product_min_qty,'product_max_qty':product_max_qty,},context=context)
291- else:
292- name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator')
293- pool.get('stock.warehouse.orderpoint').create(cr, uid, {
294- 'name': name,
295- 'active': True,
296- 'warehouse_id': data['form']['warehouse_id'],
297- 'location_id': location_id,
298- 'product_id': id,
299- 'product_min_qty': product_min_qty,
300- 'product_max_qty': product_max_qty,
301- 'qty_multiple':1,
302- 'product_uom':product_id.uom_id.id,
303- 'logic':'max'
304- } )
305-
306-
307+
308+ # max_qty_factor factor
309+ max_qty_factor = data['form']['max_qty_factor']
310+
311+ # 1. Calculation of the date date start in one year later than current date
312+ from_date = (datetime.now() - relativedelta(months=12)).strftime('%Y-%m-%d %H:%M:%S')
313+ to_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
314+
315+ # 2.1 first find the all the product which fullfill the criteria of the 2.1
316+ product_ids = product_obj.search(cr,uid,[('active','=',True),('type','=','product'),
317+ ('procure_method','=','make_to_stock'),
318+ ('supply_method','=','buy'),
319+ ('purchase_ok','=',True),
320+ ('state','not in',['end','obsolete']),
321+ ])
322+ ####### get location #####
323+ location_id = data['form']['location_id']
324+ ###########
325+
326+ #2. Second point find the products for the perticular suppliers
327+ for partner_id in data['ids']:
328+ filter_products = []
329+ for product_id in product_ids:
330+ product_data = product_obj.browse(cr, uid, product_id, context=context)
331+ for seller_id in product_data.seller_ids:
332+ if seller_id.name.id == partner_id:
333+ filter_products.append(product_id)
334+
335+ #3. Calculation of the first stock input date as first input
336+ for filter_product_id in filter_products:
337+ product_data = pool.get('product.product').browse(cr, uid, filter_product_id, context=context)
338+ supplier_lead_time = 0.0
339+
340+ # supplier_lead_time of the supplier delay
341+ for seller_id in product_data.seller_ids:
342+ if seller_id.name.id == partner_id:
343+ supplier_lead_time = seller_id.delay
344+
345+ stock_move_ids = stock_move_obj.search(cr, uid, [('product_id','=',filter_product_id)])
346+
347+ average_daily_consumption = 0.0
348+ first_stock_move_ids = []
349+ # Take the first input date of the stock move where stock move of incoming picking or stock move not have any picking
350+ for first_stock_id in stock_move_ids:
351+ first_data = stock_move_obj.browse(cr, uid, first_stock_id, context=context)
352+ if first_data.picking_id:
353+ if first_data.picking_id.type == 'in':
354+ first_stock_move_ids.append(first_stock_id)
355+ else:
356+ first_stock_move_ids.append(first_stock_id)
357+
358+ if first_stock_move_ids:
359+ first_stock_move_id = first_stock_move_ids[0]
360+ first_input = stock_move_obj.browse(cr, uid, first_stock_move_id, context=context).date_planned
361+
362+ # Case 1 if first input is less than from date
363+ if first_input < from_date:
364+ consum_qty = _sale_consume_qty(self, cr, uid, from_date, to_date, 'done', context)
365+ refund_qty = _refund_qty(self, cr, uid, filter_product_id, from_date, to_date, ['out_refund','in_refund'], context)
366+ open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, from_date, to_date, ['manual','progress'], context)
367+ open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
368+ pur_diff_day = _date_diff(self, cr, uid, filter_product_id, from_date, to_date, context)
369+ ### calculation of average_daily_consumption
370+ if pur_diff_day > 0:
371+ average_daily_consumption = (consum_qty - refund_qty + open_sale_qty - open_purchase_qty) / pur_diff_day
372+
373+ elif from_date < first_input and first_input < to_date:
374+ first_date = first_input
375+ consum_qty = _sale_consume_qty(self, cr, uid, filter_product_id, first_date, to_date, 'done', context)
376+ refund_qty = _refund_qty(self, cr, uid, filter_product_id, first_date, to_date, ['out_refund','in_refund'], context)
377+ open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, ['manual','progress'], context)
378+ open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
379+ pur_diff_day = _date_diff(self, cr, uid, filter_product_id, first_date, to_date, context)
380+
381+ ### calculation of average_daily_consumption
382+ if pur_diff_day>0:
383+ average_daily_consumption = (consum_qty - refund_qty + open_sale_qty - open_purchase_qty) / pur_diff_day
384+ else:
385+ open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, ['manual','progress'], context)
386+ open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
387+
388+ # calculation of first open purchase order date
389+ open_purchase_ids = purchase_obj.search(cr,uid,[('state','=','approved')])
390+ first_open_purchase_order = min(open_purchase_ids)
391+ fst_open_pur_date = purchase_obj.browse(cr, uid, first_open_purchase_order, context=context).date_order
392+
393+ # Days difference between to date and first purchase date
394+ pur_to_date = time.mktime(time.strptime(to_date,'%Y-%m-%d %H:%M:%S'))
395+ pur_open_date = time.mktime(time.strptime(fst_open_pur_date,'%Y-%m-%d'))
396+ pur_diff_day = (pur_to_date-pur_open_date)/(3600*24)
397+
398+ if pur_diff_day>0:
399+ average_daily_consumption = (open_sale_qty - open_purchase_qty)/pur_diff_day
400+
401+ ###### Calculation of plan_average_daily_consumption
402+ plan_average_daily_consumption = 0.0
403+ plan_average_daily_consumption = product_data.plan_avg_consume
404+
405+ if data['form']['method_qty_calculation'] == 'his_cons_with_product':
406+ product_min_qty = int(math.ceil(average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
407+ product_max_qty = max_qty_factor * product_min_qty
408+
409+ elif data['form']['method_qty_calculation'] == 'his_cons_without_product':
410+ product_min_qty = int(math.ceil(plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
411+ product_max_qty = max_qty_factor * product_min_qty
412+
413+ else:
414+ try:
415+ product_min_qty = int(math.ceil((consum_qty + open_sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
416+ except Exception,e:
417+ product_min_qty = 0.0
418+ product_max_qty = max_qty_factor * product_min_qty
419+
420+ if data['form']['delactive']:
421+ stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',filter_product_id)])
422+ for stock_rule_id in stock_rule_ids:
423+ min_rule_obj.unlink(cr, uid, [stock_rule_id],context=context)
424+
425+ mini_stock_rule_id = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',filter_product_id)])
426+ if mini_stock_rule_id:
427+ for stock_rule_id in mini_stock_rule_id:
428+ min_rule_obj.write(cr, uid, [stock_rule_id],{'product_min_qty':product_min_qty,'product_max_qty':product_max_qty,},context=context)
429+ else:
430+ name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator')
431+ pool.get('stock.warehouse.orderpoint').create(cr, uid, {
432+ 'name': name,
433+ 'active': True,
434+ 'warehouse_id': data['form']['warehouse_id'],
435+ 'location_id': location_id,
436+ 'product_id': filter_product_id,
437+ 'product_min_qty': product_min_qty,
438+ 'product_max_qty': product_max_qty,
439+ 'qty_multiple':1,
440+ 'product_uom':product_data.uom_id.id,
441+ 'logic':'price',
442+ } )
443+
444 return {}
445
446 def _get_message(self, cr, uid, data, context):

Subscribers

People subscribed via source and target branches