Merge lp:~openbig/bigconsulting/new_changes_in_stock_minimum_calculator into lp:bigconsulting
- new_changes_in_stock_minimum_calculator
- Merge into addons
Proposed by
gpa(OpenERP)
Status: | Merged |
---|---|
Merged at revision: | 27 |
Proposed branch: | lp:~openbig/bigconsulting/new_changes_in_stock_minimum_calculator |
Merge into: | lp:bigconsulting |
Diff against target: |
359 lines (+105/-115) 6 files modified
stock_minimum_calculator/__init__.py (+0/-1) stock_minimum_calculator/__terp__.py (+1/-1) stock_minimum_calculator/stock_minimum_calculator.py (+0/-14) stock_minimum_calculator/stock_minimum_calculator_view.xml (+0/-41) stock_minimum_calculator/supplier_cost_optimated_leadtimes.py (+9/-6) stock_minimum_calculator/wizard/stock_order_point_calculator.py (+95/-52) |
To merge this branch: | bzr merge lp:~openbig/bigconsulting/new_changes_in_stock_minimum_calculator |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
openbig | Pending | ||
Review via email: mp+28140@code.launchpad.net |
Commit message
Description of the change
changes in the stock_minimum_
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 'stock_minimum_calculator/__init__.py' |
2 | --- stock_minimum_calculator/__init__.py 2010-06-15 06:50:37 +0000 |
3 | +++ stock_minimum_calculator/__init__.py 2010-06-22 08:06:27 +0000 |
4 | @@ -21,7 +21,6 @@ |
5 | ############################################################################## |
6 | |
7 | import stock_minimum_calculator |
8 | -import stock_order_point_calculator |
9 | import supplier_cost_optimated_leadtimes |
10 | import wizard |
11 | |
12 | |
13 | === modified file 'stock_minimum_calculator/__terp__.py' |
14 | --- stock_minimum_calculator/__terp__.py 2010-06-15 06:50:37 +0000 |
15 | +++ stock_minimum_calculator/__terp__.py 2010-06-22 08:06:27 +0000 |
16 | @@ -29,7 +29,7 @@ |
17 | minimum stock rules based on real and virtual stock comparison so |
18 | we have proper re-order quentity for each products. |
19 | """, |
20 | - "depends": ['stock','mrp'], |
21 | + "depends": ['stock','mrp',"sale"], |
22 | "demo_xml": ["stock_minimum_calculator_demo.xml"], |
23 | "update_xml": ['stock_minimum_calculator_view.xml', |
24 | "stock_minimujm_calculator_wizard.xml", |
25 | |
26 | === modified file 'stock_minimum_calculator/stock_minimum_calculator.py' |
27 | --- stock_minimum_calculator/stock_minimum_calculator.py 2010-06-15 06:50:37 +0000 |
28 | +++ stock_minimum_calculator/stock_minimum_calculator.py 2010-06-22 08:06:27 +0000 |
29 | @@ -65,18 +65,4 @@ |
30 | } |
31 | product_product() |
32 | |
33 | - |
34 | -class stock_warehosue_orderpoint_period(osv.osv): |
35 | - ### Add for percenatage of the period |
36 | - _name = "stock.warehosue.orderpoint.period" |
37 | - _columns = { |
38 | - 'name':fields.char("Name",size=64,required=True), |
39 | - 'product_id':fields.many2one('product.product', 'Product',required=True), |
40 | - 'partner_id':fields.many2one('res.partner','Partner',required=True), |
41 | - 'period_id' :fields.many2one('account.period',"Period",required=True), |
42 | - 'percentage':fields.float("Percenatage",required=True), |
43 | - } |
44 | - |
45 | -stock_warehosue_orderpoint_period() |
46 | - |
47 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
48 | \ No newline at end of file |
49 | |
50 | === modified file 'stock_minimum_calculator/stock_minimum_calculator_view.xml' |
51 | --- stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-15 06:50:37 +0000 |
52 | +++ stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-22 08:06:27 +0000 |
53 | @@ -102,46 +102,5 @@ |
54 | </field> |
55 | </record> |
56 | |
57 | -<!-- Add for percenatage of the period --> |
58 | - <record id="stock_warehosue_orderpoint_period_tree_view" model="ir.ui.view"> |
59 | - <field name="name">stock.warehosue.orderpoint.period.tree</field> |
60 | - <field name="model">stock.warehosue.orderpoint.period</field> |
61 | - <field name="type">tree</field> |
62 | - <field name="arch" type="xml"> |
63 | - <tree string="Period Percenatage"> |
64 | - <field name="name"/> |
65 | - <field name="product_id"/> |
66 | - <field name="partner_id"/> |
67 | - <field name="period_id"/> |
68 | - <field name="percentage"/> |
69 | - </tree> |
70 | - </field> |
71 | - </record> |
72 | - |
73 | - <record id="stock_warehosue_orderpoint_period_form_view" model="ir.ui.view"> |
74 | - <field name="name">stock.warehosue.orderpoint.period.form</field> |
75 | - <field name="model">stock.warehosue.orderpoint.period</field> |
76 | - <field name="type">form</field> |
77 | - <field name="arch" type="xml"> |
78 | - <form string="Period Percenatage"> |
79 | - <field name="name"/> |
80 | - <field name="product_id"/> |
81 | - <field name="partner_id"/> |
82 | - <field name="period_id"/> |
83 | - <field name="percentage"/> |
84 | - </form> |
85 | - </field> |
86 | - </record> |
87 | - <record id="stock_warehosue_orderpoint_period_normal_action" model="ir.actions.act_window"> |
88 | - <field name="name">Period Percenatage</field> |
89 | - <field name="type">ir.actions.act_window</field> |
90 | - <field name="res_model">stock.warehosue.orderpoint.period</field> |
91 | - <field name="view_type">form</field> |
92 | - <field name="view_id" ref="stock_warehosue_orderpoint_period_tree_view"/> |
93 | - </record> |
94 | - |
95 | - <menuitem action="stock_warehosue_orderpoint_period_normal_action" id="menu_period_supplier" parent="stock.menu_stock_configuration"/> |
96 | - |
97 | - |
98 | </data> |
99 | </openerp> |
100 | \ No newline at end of file |
101 | |
102 | === modified file 'stock_minimum_calculator/supplier_cost_optimated_leadtimes.py' |
103 | --- stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 2010-06-15 06:50:37 +0000 |
104 | +++ stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 2010-06-22 08:06:27 +0000 |
105 | @@ -40,9 +40,8 @@ |
106 | } |
107 | |
108 | def _compute(self, cr, uid, ids, context=None): |
109 | - |
110 | + |
111 | form = self.read(cr, uid, ids, [], context=context)[0] |
112 | - |
113 | analytic_account_obj = self.pool.get('account.analytic.account') |
114 | analytic_line_obj = self.pool.get('account.analytic.line') |
115 | stock_hold_rate_obj = self.pool.get("stock.holding.rate") |
116 | @@ -76,11 +75,15 @@ |
117 | stock_hold_id = stock_hold_rate_obj.browse(cr, uid, form['stock_holding_rate_id']) |
118 | stock_hold_rate = stock_hold_id.stock_hold_rate |
119 | |
120 | + economic_numer_orders = 0.0 |
121 | + economic_lead_time = 0.0 |
122 | + |
123 | if pur_balance and cost_balance: |
124 | - for id in ids: |
125 | - economic_numer_orders = (pur_balance * stock_hold_rate)/ (2 * cost_balance) |
126 | - economic_lead_time = 360 / economic_numer_orders |
127 | - self.write(cr, uid, [id],{'cost_per_del':cost_balance,'purchase_rev':pur_balance, 'economic_no_order':economic_numer_orders,'economic_lead_time':economic_lead_time}) |
128 | + economic_numer_orders = (pur_balance * stock_hold_rate)/ (2 * cost_balance) |
129 | + economic_lead_time = 360 / economic_numer_orders |
130 | + |
131 | + for id in ids: |
132 | + self.write(cr, uid, [id],{'cost_per_del':cost_balance,'purchase_rev':pur_balance, 'economic_no_order':economic_numer_orders,'economic_lead_time':economic_lead_time}) |
133 | |
134 | return True |
135 | |
136 | |
137 | === modified file 'stock_minimum_calculator/wizard/stock_order_point_calculator.py' |
138 | --- stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-06-15 06:50:37 +0000 |
139 | +++ stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-06-22 08:06:27 +0000 |
140 | @@ -24,7 +24,9 @@ |
141 | import time |
142 | from tools.translate import _ |
143 | import mx.DateTime |
144 | -from mx.DateTime import RelativeDateTime, now, DateTime, localtime |
145 | +from mx.DateTime import RelativeDateTime, now, DateTime |
146 | +from tools import config |
147 | +import math |
148 | |
149 | orderpoint_calculator_form = """<?xml version="1.0"?> |
150 | <form string="Order Point Calculator "> |
151 | @@ -89,17 +91,26 @@ |
152 | }, |
153 | } |
154 | |
155 | +_messages_form = '''<?xml version="1.0"?> |
156 | +<form string="Warning"> |
157 | + <label string="Information Regarding Method of Calculation" colspan="4"/> |
158 | + <field name="message" colspan="4" nolabel="1"/> |
159 | +</form>''' |
160 | +_message_fields = { |
161 | + 'message': {'string':'Message' ,'type':'text', 'readonly':True} |
162 | + } |
163 | + |
164 | def _get_default(obj, cr, uid, data, context=None): |
165 | pool = pooler.get_pool(cr.dbname) |
166 | |
167 | warehouse_id = pool.get('stock.warehouse').search(cr, uid, [])[0] |
168 | location_id = pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0] |
169 | |
170 | - date = now().strftime('%Y-%m-%d') |
171 | - date = mx.DateTime.strptime(date, '%Y-%m-%d') - RelativeDateTime(months=3) |
172 | - date = date.strftime('%Y-%m-%d') |
173 | + from_date = now().strftime('%Y-%m-%d') |
174 | + from_date = mx.DateTime.strptime(from_date, '%Y-%m-%d') - RelativeDateTime(months=3) |
175 | + from_date = from_date.strftime('%Y-%m-%d') |
176 | |
177 | - return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':date} |
178 | + return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':from_date} |
179 | |
180 | def _do_calculate(self, cr, uid, data, context): |
181 | |
182 | @@ -112,11 +123,6 @@ |
183 | supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time') |
184 | min_rule_obj = pool.get('stock.warehouse.orderpoint') |
185 | |
186 | - stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id'])]) |
187 | - if data['form']['delactive']: |
188 | - for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context): |
189 | - min_rule_obj.unlink(cr, uid, [stock_rule_id.id],context=context) |
190 | - |
191 | ##### Calculation of purchase lead time |
192 | purchase_lead_time = 0.0 |
193 | company = pool.get('res.users').browse(cr, uid, uid, context).company_id |
194 | @@ -129,21 +135,24 @@ |
195 | supplier_lead_time = 0.0 |
196 | if product_id: |
197 | for supp in product_id.seller_ids: |
198 | - sup = supp_obj.browse(cr, uid, supp.id, context) |
199 | - supplier_lead_time = sup.delay |
200 | - |
201 | + sup = supp_obj.browse(cr, uid, supp.id, context) |
202 | + supplier_lead_time = sup.delay |
203 | + |
204 | ###### Calculation of average_daily_consumption |
205 | date_start = data['form']['date_start'] |
206 | date_stop = data['form']['date_stop'] |
207 | average_daily_consumption = 0.0 |
208 | + sale_line_obj = pool.get("sale.order.line") |
209 | consum_qty = 0.0 |
210 | sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)]) |
211 | if sale_ids: |
212 | for sid in sale_ids: |
213 | - sale_data = sale_obj.browse(cr,uid,sid) |
214 | - for line in sale_data.order_line: |
215 | - consum_qty += line.product_uom_qty |
216 | - |
217 | + sale_line_id = sale_line_obj.search(cr,uid,[('order_id','=',sid),('product_id','=',product_id.id)]) |
218 | + for line_id in sale_line_id: |
219 | + sale_line_data= sale_line_obj.browse(cr,uid,line_id) |
220 | + consum_qty += sale_line_data.product_uom_qty |
221 | + ###here cosume quantity is total of selected produdct |
222 | + |
223 | ##################calculation of date difference between first and last sale order |
224 | sale_ids = sale_obj.search(cr,uid,[]) |
225 | if sale_ids: |
226 | @@ -161,18 +170,17 @@ |
227 | plan_average_daily_consumption = 0.0 |
228 | if product_id.plan_avg_consume: |
229 | plan_average_daily_consumption = product_id.plan_avg_consume |
230 | - |
231 | ########## calculation historical consumption of products and open sales orders“ |
232 | ### total sale qty with open state |
233 | |
234 | sale_qty = 0.0 |
235 | - sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])]) |
236 | + open_sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])]) |
237 | if sale_ids: |
238 | - for sale_id in sale_ids: |
239 | - sale_data = sale_obj.browse(cr,uid,sale_id) |
240 | - for line in sale_data.order_line: |
241 | - sale_qty += line.product_uom_qty |
242 | - |
243 | + for sale_id in open_sale_ids: |
244 | + sale_open_line_ids= sale_line_obj.search(cr,uid,[('order_id','=',sale_id),('product_id','=',product_id.id)]) |
245 | + for open_line_id in sale_open_line_ids: |
246 | + sale_line_data= sale_line_obj.browse(cr,uid,open_line_id) |
247 | + sale_qty += sale_line_data.product_uom_qty |
248 | ################### |
249 | purchase_ids = purchase_obj.search(cr,uid,[]) |
250 | if purchase_ids: |
251 | @@ -189,34 +197,60 @@ |
252 | product_max_qty = 0.0 |
253 | product_min_qty = 0.0 |
254 | |
255 | + |
256 | if data['form']['method_qty_calculation'] == 'his_cons_with_product': |
257 | - product_min_qty = average_daily_consumption * (supplier_lead_time + purchase_lead_time) |
258 | + product_min_qty = int(math.ceil(average_daily_consumption * (supplier_lead_time + purchase_lead_time))) |
259 | product_max_qty = 2 * product_min_qty |
260 | - |
261 | + |
262 | elif data['form']['method_qty_calculation'] == 'his_cons_without_product': |
263 | - product_min_qty = plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) |
264 | - product_max_qty = 2 * product_min_qty |
265 | - |
266 | - else: |
267 | - product_min_qty = (average_daily_consumption + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) |
268 | - product_max_qty = 2 * product_min_qty |
269 | - |
270 | - max1 = 'max' |
271 | - name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator') |
272 | - pool.get('stock.warehouse.orderpoint').create(cr, uid, { |
273 | - 'name': name, |
274 | - 'active': True, |
275 | - 'warehouse_id': data['form']['warehouse_id'], |
276 | - 'location_id': product_id.property_stock_inventory.id, |
277 | - 'product_id': id, |
278 | - 'product_min_qty': product_min_qty, |
279 | - 'product_max_qty': product_max_qty, |
280 | - 'qty_multiple':1, |
281 | - 'product_uom':product_id.uom_id.id, |
282 | - 'logic':'max' |
283 | - } ) |
284 | + product_min_qty = int(math.ceil(plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time))) |
285 | + product_max_qty = 2 * product_min_qty |
286 | + |
287 | + else: |
288 | + try: |
289 | + product_min_qty = int(math.ceil((consum_qty + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time))) |
290 | + except Exception,e: |
291 | + product_min_qty = 0.0 |
292 | + product_max_qty = 2 * product_min_qty |
293 | + |
294 | + if data['form']['delactive']: |
295 | + stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)]) |
296 | + for stock_rule_id in stock_rule_ids: |
297 | + min_rule_obj.unlink(cr, uid, [stock_rule_id],context=context) |
298 | + |
299 | + mini_stock_rule_id = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id']),('product_id','=',product_id.id)]) |
300 | + if mini_stock_rule_id: |
301 | + for stock_rule_id in mini_stock_rule_id: |
302 | + min_rule_obj.write(cr, uid, [stock_rule_id],{'product_min_qty':product_min_qty,'product_max_qty':product_max_qty,},context=context) |
303 | + else: |
304 | + name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator') |
305 | + pool.get('stock.warehouse.orderpoint').create(cr, uid, { |
306 | + 'name': name, |
307 | + 'active': True, |
308 | + 'warehouse_id': data['form']['warehouse_id'], |
309 | + 'location_id': product_id.property_stock_inventory.id, |
310 | + 'product_id': id, |
311 | + 'product_min_qty': product_min_qty, |
312 | + 'product_max_qty': product_max_qty, |
313 | + 'qty_multiple':1, |
314 | + 'product_uom':product_id.uom_id.id, |
315 | + 'logic':'max' |
316 | + } ) |
317 | |
318 | + |
319 | return {} |
320 | + |
321 | +def _get_message(self, cr, uid, data, context): |
322 | + |
323 | + if data['form']['method_qty_calculation'] == 'his_cons_with_product': |
324 | + data['form']['message'] = _("Are your sure that you have enough historical data to calculate stock orderpoint rules with this methodology, Otherwise you should try the other options, \n Calculate without historical consumption of products or ,Calculate with historical consumption of products and sales orders") |
325 | + elif data['form']['method_qty_calculation'] == 'his_cons_without_product': |
326 | + data['form']['message'] = _("Your calculation is based on the field plan average daily consumption.\n Are your sure not to calculate with the method , Calculate with historical consumption of products") |
327 | + else: |
328 | + data['form']['message'] = _("Are your sure that you have really not enough historical data to calculate stock orderpoint rules? \n Otherwise you should prefer the options , Calculate with historical consumption of products. This results may calculate better results than calculation with this methodology.") |
329 | + return data['form'] |
330 | + |
331 | + |
332 | |
333 | class orderpoint_calculator(wizard.interface): |
334 | states = { |
335 | @@ -228,11 +262,20 @@ |
336 | 'state' : [('end', 'Cancel'),('calculation', 'Calculation') ]} |
337 | }, |
338 | 'calculation' : { |
339 | - 'actions' : [], |
340 | - 'result' : {'type' : 'action', |
341 | - 'action' : _do_calculate, |
342 | - 'state' : 'end'} |
343 | - } |
344 | + 'actions' : [ _do_calculate ], |
345 | + 'result' : {'type' : 'state', |
346 | + 'state' : 'end2'} |
347 | + }, |
348 | + |
349 | + 'end2': { |
350 | + 'actions': [ _get_message ], |
351 | + 'result': {'type': 'form', 'arch': _messages_form, |
352 | + 'fields': _message_fields, |
353 | + 'state': ( |
354 | + ('end', 'Close'), |
355 | + ) |
356 | + }, |
357 | + }, |
358 | } |
359 | orderpoint_calculator("orderpoint.calculator") |
360 |