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

Proposed by gpa(OpenERP)
Status: Superseded
Proposed branch: lp:~openbig/bigconsulting/order_point_calcultor
Merge into: lp:bigconsulting
Diff against target: 419 lines (+230/-130)
2 files modified
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/order_point_calcultor
Reviewer Review Type Date Requested Status
openbig Pending
Review via email: mp+32739@code.launchpad.net

This proposal supersedes a proposal from 2010-08-16.

This proposal has been superseded by a proposal from 2010-08-16.

Description of the change

improvement in order point calculator wizard bug 615927

To post a comment you must log in.
79. By gpa(OpenERP)

optimzation in wizard order point calculator

80. By gpa(OpenERP)

optimization in stock order point wizard

81. By gpa(OpenERP)

optimization in stock order point wizard

82. By gpa(OpenERP)

improvement for automatically increment in scanned quantity and real quantity

83. By gpa(OpenERP)

changes in first condition of date

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'stock_minimum_calculator/stock_minimum_calculator_wizard.xml'
--- stock_minimum_calculator/stock_minimum_calculator_wizard.xml 2010-07-27 09:27:59 +0000
+++ stock_minimum_calculator/stock_minimum_calculator_wizard.xml 2010-08-16 12:31:14 +0000
@@ -9,7 +9,7 @@
9 id="id_set_seasonal_trend"/>9 id="id_set_seasonal_trend"/>
10 <wizard10 <wizard
11 string="Order Point Cacluator"11 string="Order Point Cacluator"
12 model="product.product"12 model="res.partner"
13 name="orderpoint.calculator"13 name="orderpoint.calculator"
14 menu="True"14 menu="True"
15 id="id_order_point_cacluator"/>15 id="id_order_point_cacluator"/>
1616
=== modified file 'stock_minimum_calculator/wizard/stock_order_point_calculator.py'
--- stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-08-04 13:12:02 +0000
+++ stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-08-16 12:31:14 +0000
@@ -34,13 +34,9 @@
34 <field name="warehouse_id"/>34 <field name="warehouse_id"/>
35 <field name="location_id"/>35 <field name="location_id"/>
36 <field name="seasonal_id"/>36 <field name="seasonal_id"/>
37 <field name="max_qty_factor"/>
37 <field name="delactive"/>38 <field name="delactive"/>
38 <field name="method_qty_calculation" colspan="4"/>39 <field name="method_qty_calculation" colspan="4"/>
39 <group attrs="{'invisible':[('method_qty_calculation','=','his_cons_without_product')]}" colspan="4">
40 <separator string="Configuration of Base Consumptions Periods" colspan="4"/>
41 <field name="date_start"/>
42 <field name="date_stop"/>
43 </group>
44</form>"""40</form>"""
4541
46orderpoint_calculator_fields = {42orderpoint_calculator_fields = {
@@ -70,24 +66,19 @@
70 'required': True,66 'required': True,
71 '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.'67 '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.'
72 },68 },
7369
74 'date_start': {70 'max_qty_factor': {
75 'string':'From Date',71 'string':'Max. Qty. Factor',
76 'type':'date'72 'type':'float',
77 },73 'required': True
78
79 'date_stop': {
80 'string':'To Date',
81 'type':'date',
82 'default': lambda *a: time.strftime('%Y-%m-%d')
83 },74 },
8475
85 'method_qty_calculation':{76 'method_qty_calculation':{
86 'string':"Method Calculation",77 'string':"Method Calculation",
87 'type':'selection',78 'type':'selection',
88 'selection':[('his_cons_with_product', 'Calculate with historical consumptions of products'),79 'selection':[('his_cons_with_product', 'Calculate with planning values'),
89 ('his_cons_without_product', 'Calculate with Out historical consumptions of product'),80 ('his_cons_without_product', 'Calculate with Out historical consumptions of product'),
90 ('hist_cons_and_open_sale', 'Calculate with historical consumptions of product and Open sales orders'),81 ('hist_cons_and_open_sale', 'Calculate with historical values'),
91 ],'required': True,82 ],'required': True,
92 'default': lambda *a:'his_cons_with_product'83 'default': lambda *a:'his_cons_with_product'
93 },84 },
@@ -116,16 +107,99 @@
116107
117 return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':from_date,'seasonal_id':seasonal_id}108 return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':from_date,'seasonal_id':seasonal_id}
118109
110
111def _sale_consume_qty(self, cr, uid, product_id, from_date, to_date, state, context):
112 """calculation of consumption of product from_date to to_date , where state is done """
113
114 pool = pooler.get_pool(cr.dbname)
115
116 sale_obj = pool.get('sale.order')
117 sale_line_obj = pool.get("sale.order.line")
118 consum_qty = 0.0
119 sale_ids = sale_obj.search(cr,uid,[('date_order','>=',from_date),('date_order','<=',to_date), ('state','=',state)])
120 if sale_ids:
121 for sid in sale_ids:
122 sale_line_id = sale_line_obj.search(cr,uid,[('order_id','=',sid),('product_id','=',product_id)])
123 for line_id in sale_line_id:
124 sale_line_data= sale_line_obj.browse(cr, uid, line_id, context=context).product_uom_qty
125 consum_qty += sale_line_data
126
127 return consum_qty
128
129def _sale_open_qty(self, cr, uid, product_id, state, context):
130 """Calculation of open sale orders"""
131
132 pool = pooler.get_pool(cr.dbname)
133
134 sale_obj = pool.get('sale.order')
135 sale_line_obj = pool.get("sale.order.line")
136 open_sale_qty = 0.0
137 open_sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])])
138 if open_sale_ids:
139 for sale_id in open_sale_ids:
140 sale_open_line_ids = sale_line_obj.search(cr,uid,[('order_id','=',sale_id),('product_id','=',product_id)])
141 for open_line_id in sale_open_line_ids:
142 sale_line_data= sale_line_obj.browse(cr,uid,open_line_id)
143 open_sale_qty += sale_line_data.product_uom_qty
144
145 return open_sale_qty
146
147def _purchase_open_qty(self, cr, uid, product_id, state, context):
148 """ Calculation of open purchase orders """
149
150 pool = pooler.get_pool(cr.dbname)
151
152 purchase_obj = pool.get('purchase.order')
153 purchase_order_line_obj = pool.get('purchase.order.line')
154 open_purchase_qty = 0.0
155 open_purchase_ids = purchase_obj.search(cr,uid,[('state','=',state)])
156 if open_purchase_ids:
157 for purchase_id in open_purchase_ids:
158 open_purchase_line_ids= purchase_order_line_obj.search(cr,uid,[('order_id','=',purchase_id),('product_id','=',product_id)])
159 for open_pur_id in open_purchase_line_ids:
160 purchase_line_data = purchase_order_line_obj.browse(cr, uid, open_pur_id, context=context)
161 open_purchase_qty += purchase_line_data.product_qty
162
163 return open_purchase_qty
164
165def _refund_qty(self, cr, uid, product_id, from_date, to_date, state, context):
166 """ Calculation of the refund quantities of the prduct from the refund invoice, between from_date, to_date"""
167
168 pool = pooler.get_pool(cr.dbname)
169
170 account_invoice_obj = pool.get('account.invoice')
171 account_invoice_line_obj = pool.get('account.invoice.line')
172 refund_qty = 0.0
173 refund_invoice_ids = account_invoice_obj.search(cr,uid,[('type','in',['out_refund','in_refund']),('date_invoice','>=',from_date),('date_invoice','<=',to_date)])
174 for refund_id in refund_invoice_ids:
175 invoie_line_ids = account_invoice_line_obj.search(cr,uid,[('invoice_id','=',refund_id),('product_id','=',product_id)])
176 for invoice_line_id in invoie_line_ids:
177 inovice_line_data = account_invoice_line_obj.browse(cr, uid, invoice_line_id, context=context).quantity
178 refund_qty += inovice_line_data
179
180 return refund_qty
181
182
183def _date_diff(self, cr, uid, product_id, from_date, to_date, context):
184 """ Date difference between from_date and to_date """
185
186 first_date = time.mktime(time.strptime(from_date,'%Y-%m-%d %H:%M:%S'))
187 last_date = time.mktime(time.strptime(to_date,'%Y-%m-%d %H:%M:%S'))
188 diff_day = (last_date-first_date)/(3600*24)
189 return diff_day
190
119def _do_calculate(self, cr, uid, data, context):191def _do_calculate(self, cr, uid, data, context):
120 pool = pooler.get_pool(cr.dbname)192 pool = pooler.get_pool(cr.dbname)
121193
122 purchase_obj = pool.get('purchase.order')194 purchase_obj = pool.get('purchase.order')
123 sale_obj = pool.get('sale.order')195 purchase_order_line_obj = pool.get('purchase.order.line')
124 product_obj = pool.get('product.product')196 product_obj = pool.get('product.product')
125 supp_obj = pool.get('product.supplierinfo')197 supp_obj = pool.get('product.supplierinfo')
126 supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time')198 supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time')
127 min_rule_obj = pool.get('stock.warehouse.orderpoint')199 min_rule_obj = pool.get('stock.warehouse.orderpoint')
128 seasonal_obj = pool.get('product.seasonal')200 seasonal_obj = pool.get('product.seasonal')
201 stock_move_obj = pool.get('stock.move')
202
129 ##### Calculation of purchase lead time203 ##### Calculation of purchase lead time
130 purchase_lead_time = 0.0204 purchase_lead_time = 0.0
131 company = pool.get('res.users').browse(cr, uid, uid, context).company_id205 company = pool.get('res.users').browse(cr, uid, uid, context).company_id
@@ -135,117 +209,143 @@
135 seasonal_id = data['form']['seasonal_id']209 seasonal_id = data['form']['seasonal_id']
136 seasonal_data = seasonal_obj.browse(cr, uid, seasonal_id)210 seasonal_data = seasonal_obj.browse(cr, uid, seasonal_id)
137 seasonal_factor = seasonal_data.seasonal_factor211 seasonal_factor = seasonal_data.seasonal_factor
138212
139 ##### Calculation of supplier lead time213 # max_qty_factor factor
140214 max_qty_factor = data['form']['max_qty_factor']
141 for id in data['ids']:215
142 product_id = product_obj.browse(cr, uid, id, context)216 # 1. Calculation of the date date start in one year later than current date
143 supplier_lead_time = 0.0217 from_date = (datetime.now() - relativedelta(months=12)).strftime('%Y-%m-%d %H:%M:%S')
144 if product_id:218 to_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
145 for supp in product_id.seller_ids:219
146 sup = supp_obj.browse(cr, uid, supp.id, context)220 # 2.1 first find the all the product which fullfill the criteria of the 2.1
147 supplier_lead_time = sup.delay221 product_ids = product_obj.search(cr,uid,[('active','=',True),('type','=','product'),
148222 ('procure_method','=','make_to_stock'),
149 ###### Calculation of average_daily_consumption223 ('supply_method','=','buy'),
150 date_start = data['form']['date_start']224 ('purchase_ok','=',True),
151 date_stop = data['form']['date_stop']225 ('state','not in',['end','obsolete']),
152 average_daily_consumption = 0.0226 ])
153 sale_line_obj = pool.get("sale.order.line")227 ####### get location #####
154 consum_qty = 0.0228 location_id = data['form']['location_id']
155 sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)])229 ###########
156 if sale_ids:230
157 for sid in sale_ids:231 #2. Second point find the products for the perticular suppliers
158 sale_line_id = sale_line_obj.search(cr,uid,[('order_id','=',sid),('product_id','=',product_id.id)])232 for partner_id in data['ids']:
159 for line_id in sale_line_id:233 filter_products = []
160 sale_line_data= sale_line_obj.browse(cr,uid,line_id)234 for product_id in product_ids:
161 consum_qty += sale_line_data.product_uom_qty235 product_data = product_obj.browse(cr, uid, product_id, context=context)
162 ###here consume quantity is total of selected product236 for seller_id in product_data.seller_ids:
163 ##################calculation of date difference between first and last sale order237 if seller_id.name.id == partner_id:
164 sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)], order='date_order asc')238 filter_products.append(product_id)
165 if sale_ids:239
166 start_sale_id = sale_ids[0]240 #3. Calculation of the first stock input date as first input
167 last_sale_id = sale_ids[-1]241 for filter_product_id in filter_products:
168 first_sale_date = sale_obj.browse(cr,uid,start_sale_id).date_order242 product_data = pool.get('product.product').browse(cr, uid, filter_product_id, context=context)
169 last_sale_date = sale_obj.browse(cr,uid,last_sale_id).date_order243 supplier_lead_time = 0.0
170 first_date = time.mktime(time.strptime(first_sale_date,'%Y-%m-%d'))244
171 last_date = time.mktime(time.strptime(last_sale_date,'%Y-%m-%d'))245 # supplier_lead_time of the supplier delay
172 diff_day = (last_date-first_date)/(3600*24)246 for seller_id in product_data.seller_ids:
173 if diff_day > 0:247 if seller_id.name.id == partner_id:
174 average_daily_consumption = consum_qty / diff_day248 supplier_lead_time = seller_id.delay
175 ###### Calculation of plan_average_daily_consumption249
176 plan_average_daily_consumption = 0.0250 stock_move_ids = stock_move_obj.search(cr, uid, [('product_id','=',filter_product_id)])
177 if product_id.plan_avg_consume:251
178 plan_average_daily_consumption = product_id.plan_avg_consume252 average_daily_consumption = 0.0
179253 first_stock_move_ids = []
180 ####### get location #####254 # Take the first input date of the stock move where stock move of incoming picking or stock move not have any picking
181 location_id = data['form']['location_id']255 for first_stock_id in stock_move_ids:
182256 first_data = stock_move_obj.browse(cr, uid, first_stock_id, context=context)
183 ########## calculation historical consumption of products and open sales orders“257 if first_data.picking_id:
184 ### total sale qty with open state258 if first_data.picking_id.type == 'in':
185259 first_stock_move_ids.append(first_stock_id)
186 sale_qty = 0.0260 else:
187 open_sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])])261 first_stock_move_ids.append(first_stock_id)
188 if sale_ids:262
189 for sale_id in open_sale_ids:263 if first_stock_move_ids:
190 sale_open_line_ids= sale_line_obj.search(cr,uid,[('order_id','=',sale_id),('product_id','=',product_id.id)])264 first_stock_move_id = first_stock_move_ids[0]
191 for open_line_id in sale_open_line_ids:265 first_input = stock_move_obj.browse(cr, uid, first_stock_move_id, context=context).date_planned
192 sale_line_data= sale_line_obj.browse(cr,uid,open_line_id)266
193 sale_qty += sale_line_data.product_uom_qty267 # Case 1 if first input is less than from date
194 ###################268 if first_input < from_date:
195 purchase_ids = purchase_obj.search(cr,uid,[])269 consum_qty = _sale_consume_qty(self, cr, uid, from_date, to_date, 'done', context)
196 if purchase_ids:270 refund_qty = _refund_qty(self, cr, uid, filter_product_id, from_date, to_date, ['out_refund','in_refund'], context)
197 start_pur_id = min(purchase_ids)271 open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, from_date, to_date, ['manual','progress'], context)
198 last_pur_id = max(purchase_ids)272 open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
199273 pur_diff_day = _date_diff(self, cr, uid, filter_product_id, from_date, to_date, context)
200 ##################calculation of date difference between first and last purchase order274 ### calculation of average_daily_consumption
201 first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order275 if pur_diff_day > 0:
202 last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order276 average_daily_consumption = (consum_qty - refund_qty + open_sale_qty - open_purchase_qty) / pur_diff_day
203 first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d'))277
204 last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d'))278 elif from_date < first_input and first_input < to_date:
205 pur_diff_day = (last_date-first_date)/(3600*24)279 first_date = first_input
206 product_max_qty = 0.0280 consum_qty = _sale_consume_qty(self, cr, uid, filter_product_id, first_date, to_date, 'done', context)
207 product_min_qty = 0.0281 refund_qty = _refund_qty(self, cr, uid, filter_product_id, first_date, to_date, ['out_refund','in_refund'], context)
208282 open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, ['manual','progress'], context)
209 if data['form']['method_qty_calculation'] == 'his_cons_with_product':283 open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
210 product_min_qty = int(math.ceil(average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))284 pur_diff_day = _date_diff(self, cr, uid, filter_product_id, first_date, to_date, context)
211 product_max_qty = 2 * product_min_qty285
212286 ### calculation of average_daily_consumption
213 elif data['form']['method_qty_calculation'] == 'his_cons_without_product':287 if pur_diff_day>0:
214 product_min_qty = int(math.ceil(plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))288 average_daily_consumption = (consum_qty - refund_qty + open_sale_qty - open_purchase_qty) / pur_diff_day
215 product_max_qty = 2 * product_min_qty289 else:
216290 open_sale_qty = _sale_open_qty(self, cr, uid, filter_product_id, ['manual','progress'], context)
217 else:291 open_purchase_qty = _purchase_open_qty(self, cr, uid, filter_product_id, 'approved', context)
218 try:292
219 product_min_qty = int(math.ceil((consum_qty + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) * seasonal_factor))293 # calculation of first open purchase order date
220 except Exception,e:294 open_purchase_ids = purchase_obj.search(cr,uid,[('state','=','approved')])
221 product_min_qty = 0.0295 first_open_purchase_order = min(open_purchase_ids)
222 product_max_qty = 2 * product_min_qty296 fst_open_pur_date = purchase_obj.browse(cr, uid, first_open_purchase_order, context=context).date_order
223297
224 if data['form']['delactive']:298 # Days difference between to date and first purchase date
225 stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)])299 pur_to_date = time.mktime(time.strptime(to_date,'%Y-%m-%d %H:%M:%S'))
226 for stock_rule_id in stock_rule_ids:300 pur_open_date = time.mktime(time.strptime(fst_open_pur_date,'%Y-%m-%d'))
227 min_rule_obj.unlink(cr, uid, [stock_rule_id],context=context)301 pur_diff_day = (pur_to_date-pur_open_date)/(3600*24)
228302
229 mini_stock_rule_id = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)])303 if pur_diff_day>0:
230 if mini_stock_rule_id:304 average_daily_consumption = (open_sale_qty - open_purchase_qty)/pur_diff_day
231 for stock_rule_id in mini_stock_rule_id:305
232 min_rule_obj.write(cr, uid, [stock_rule_id],{'product_min_qty':product_min_qty,'product_max_qty':product_max_qty,},context=context)306 ###### Calculation of plan_average_daily_consumption
233 else:307 plan_average_daily_consumption = 0.0
234 name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator')308 plan_average_daily_consumption = product_data.plan_avg_consume
235 pool.get('stock.warehouse.orderpoint').create(cr, uid, {309
236 'name': name,310 if data['form']['method_qty_calculation'] == 'his_cons_with_product':
237 'active': True,311 product_min_qty = int(math.ceil(average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
238 'warehouse_id': data['form']['warehouse_id'],312 product_max_qty = max_qty_factor * product_min_qty
239 'location_id': location_id,313
240 'product_id': id,314 elif data['form']['method_qty_calculation'] == 'his_cons_without_product':
241 'product_min_qty': product_min_qty,315 product_min_qty = int(math.ceil(plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
242 'product_max_qty': product_max_qty,316 product_max_qty = max_qty_factor * product_min_qty
243 'qty_multiple':1,317
244 'product_uom':product_id.uom_id.id,318 else:
245 'logic':'max'319 try:
246 } )320 product_min_qty = int(math.ceil((consum_qty + open_sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) * seasonal_factor))
247321 except Exception,e:
248322 product_min_qty = 0.0
323 product_max_qty = max_qty_factor * product_min_qty
324
325 if data['form']['delactive']:
326 stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',filter_product_id)])
327 for stock_rule_id in stock_rule_ids:
328 min_rule_obj.unlink(cr, uid, [stock_rule_id],context=context)
329
330 mini_stock_rule_id = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',filter_product_id)])
331 if mini_stock_rule_id:
332 for stock_rule_id in mini_stock_rule_id:
333 min_rule_obj.write(cr, uid, [stock_rule_id],{'product_min_qty':product_min_qty,'product_max_qty':product_max_qty,},context=context)
334 else:
335 name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator')
336 pool.get('stock.warehouse.orderpoint').create(cr, uid, {
337 'name': name,
338 'active': True,
339 'warehouse_id': data['form']['warehouse_id'],
340 'location_id': location_id,
341 'product_id': filter_product_id,
342 'product_min_qty': product_min_qty,
343 'product_max_qty': product_max_qty,
344 'qty_multiple':1,
345 'product_uom':product_data.uom_id.id,
346 'logic':'price',
347 } )
348
249 return {}349 return {}
250350
251def _get_message(self, cr, uid, data, context):351def _get_message(self, cr, uid, data, context):

Subscribers

People subscribed via source and target branches