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

Proposed by gpa(OpenERP)
Status: Merged
Merged at revision: 16
Proposed branch: lp:~openbig/bigconsulting/changes_in_stock_minimum_calculator
Merge into: lp:bigconsulting
Diff against target: 994 lines (+413/-439)
14 files modified
stock_minimum_calculator/__init__.py (+3/-1)
stock_minimum_calculator/__terp__.py (+3/-3)
stock_minimum_calculator/stock_minimujm_calculator_wizard.xml (+7/-0)
stock_minimum_calculator/stock_minimum_calculator.py (+0/-58)
stock_minimum_calculator/stock_minimum_calculator_demo.xml (+17/-0)
stock_minimum_calculator/stock_minimum_calculator_sequence.xml (+4/-4)
stock_minimum_calculator/stock_minimum_calculator_view.xml (+2/-74)
stock_minimum_calculator/stock_order_point_calculator.py (+0/-217)
stock_minimum_calculator/stock_order_point_calculator_view.xml (+0/-50)
stock_minimum_calculator/supplier_cost_optimated_leadtimes.py (+89/-0)
stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml (+46/-0)
stock_minimum_calculator/wizard/__init__.py (+1/-0)
stock_minimum_calculator/wizard/seasonal_trend_set_view.xml (+0/-32)
stock_minimum_calculator/wizard/stock_order_point_calculator.py (+241/-0)
To merge this branch: bzr merge lp:~openbig/bigconsulting/changes_in_stock_minimum_calculator
Reviewer Review Type Date Requested Status
openbig Pending
Review via email: mp+27589@code.launchpad.net

Description of the change

Added change as new specification

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
=== modified file 'stock_minimum_calculator/__init__.py'
--- stock_minimum_calculator/__init__.py 2010-06-09 14:36:04 +0000
+++ stock_minimum_calculator/__init__.py 2010-06-15 07:09:25 +0000
@@ -21,6 +21,8 @@
21##############################################################################21##############################################################################
2222
23import stock_minimum_calculator23import stock_minimum_calculator
24import stock_order_point_calculator
25import supplier_cost_optimated_leadtimes
24import wizard26import wizard
25import stock_order_point_calculator27
26# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:28# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
27\ No newline at end of file29\ No newline at end of file
2830
=== modified file 'stock_minimum_calculator/__terp__.py'
--- stock_minimum_calculator/__terp__.py 2010-06-11 07:42:16 +0000
+++ stock_minimum_calculator/__terp__.py 2010-06-15 07:09:25 +0000
@@ -30,11 +30,11 @@
30 we have proper re-order quentity for each products.30 we have proper re-order quentity for each products.
31 """,31 """,
32 "depends": ['stock','mrp'],32 "depends": ['stock','mrp'],
33 "demo_xml": [],33 "demo_xml": ["stock_minimum_calculator_demo.xml"],
34 "update_xml": ['stock_minimum_calculator_view.xml',34 "update_xml": ['stock_minimum_calculator_view.xml',
35 "stock_minimujm_calculator_wizard.xml",35 "stock_minimujm_calculator_wizard.xml",
36 "stock_order_point_calculator_view.xml",36 "stock_minimum_calculator_sequence.xml",
37 "stock_minimum_calculator_sequence.xml"37 "supplier_cost_optimated_leadtimes_view.xml",
38 ],38 ],
39 "license": "GPL-3",39 "license": "GPL-3",
40 "active": False,40 "active": False,
4141
=== modified file 'stock_minimum_calculator/stock_minimujm_calculator_wizard.xml'
--- stock_minimum_calculator/stock_minimujm_calculator_wizard.xml 2010-06-09 14:36:04 +0000
+++ stock_minimum_calculator/stock_minimujm_calculator_wizard.xml 2010-06-15 07:09:25 +0000
@@ -7,5 +7,12 @@
7 name="set_seasonal.trend"7 name="set_seasonal.trend"
8 menu="True"8 menu="True"
9 id="id_set_seasonal_trend"/>9 id="id_set_seasonal_trend"/>
10 <wizard
11 string="Order Point Cacluator"
12 model="product.product"
13 name="orderpoint.calculator"
14 menu="True"
15 id="id_order_point_cacluator"/>
16
10 </data>17 </data>
11</openerp>18</openerp>
1219
=== modified file 'stock_minimum_calculator/stock_minimum_calculator.py'
--- stock_minimum_calculator/stock_minimum_calculator.py 2010-06-11 06:02:15 +0000
+++ stock_minimum_calculator/stock_minimum_calculator.py 2010-06-15 07:09:25 +0000
@@ -36,7 +36,6 @@
36 }36 }
37stock_holding_rate()37stock_holding_rate()
3838
39
40class supplier_product(osv.osv):39class supplier_product(osv.osv):
41 _name = 'supplier.product'40 _name = 'supplier.product'
42 _rec_name = 'partner_id'41 _rec_name = 'partner_id'
@@ -48,63 +47,6 @@
48 47
49supplier_product()48supplier_product()
5049
51class res_partner(osv.osv):
52 _inherit = "res.partner"
53 _columns = {
54 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate'),
55 }
56res_partner()
57
58
59class supplier_cost_opti_lead_time(osv.osv):
60 _name = "supplier.cost.opti.lead.time"
61 _columns = {
62 'supp_cost_id':fields.char("ID",size=64, required=True),
63 'name':fields.char("Name of the rule",size=64, required=True),
64 'partner_id': fields.many2one('res.partner', 'Suplier'),
65 'date_start': fields.date('Date', required=True),
66 'active': fields.boolean('Active'),
67 'yrl_purchase_rev':fields.float("YRL Purchase Revenue",required=True),
68 'economic_no_order':fields.float("Economic Number of orders",readonly=True),
69 'cost_per_del':fields.float("Cost Per Delivery",required=True),
70 'economic_lead_time':fields.float("Economic Lead Time",readonly=True),
71 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate',required=True),
72 'staus': fields.selection([
73 ('draft','Draft'),
74 ('valid','Valid'),
75 ('cancel','Cancel'),
76 ],'Status',readonly=True),
77 }
78 _defaults = {
79 'date_start': lambda *a: time.strftime('%Y-%m-%d'),
80 }
81
82 def action_compute(self, cr, uid, ids, context={}):
83 for id in ids:
84 cost_op = self.browse(cr, uid,id,context=context)
85 economic_numer_orders = (cost_op.yrl_purchase_rev * cost_op.stock_holding_rate_id.stock_hold_rate)/ (2*cost_op.cost_per_del)
86 economic_lead_time = 360 / economic_numer_orders
87 self.write(cr, uid, [id],{'economic_lead_time':economic_lead_time,'economic_no_order':economic_numer_orders})
88 return True
89
90 def action_cancel(self, cr, uid, ids, context={}):
91 for o in self.browse(cr, uid, ids):
92 self.write(cr, uid, [o.id], {'staus': 'cancel'})
93 return True
94
95 def action_validate(self, cr, uid, ids, context={}):
96 for o in self.browse(cr, uid, ids):
97 already_id = self_obj.search(cr, uid, [('partner_id','=',o.partner_id.id),('id', 'not in', ids),('staus','=','valid')])
98 if already_id:
99 old_partner_id = self.browse(cr, uid, already_id[0])
100 if o.partner_id.id == old_partner_id.partner_id.id:
101 raise osv.except_osv(_('Error !'),
102 _('You can not this partner becasue this partner aleready with valid entry'))
103 self.write(cr, uid, [o.id], {'staus': 'valid'})
104 return True
105
106supplier_cost_opti_lead_time()
107
108class product_seasonal(osv.osv):50class product_seasonal(osv.osv):
109 _name = 'product.seasonal'51 _name = 'product.seasonal'
110 _columns = {52 _columns = {
11153
=== added file 'stock_minimum_calculator/stock_minimum_calculator_demo.xml'
--- stock_minimum_calculator/stock_minimum_calculator_demo.xml 1970-01-01 00:00:00 +0000
+++ stock_minimum_calculator/stock_minimum_calculator_demo.xml 2010-06-15 07:09:25 +0000
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="1">
4
5 <record id="product_seasonal_id1" model="product.seasonal">
6 <field name="name">Normal Seasonal</field>
7 <field name="code">main</field>
8 <field name="seasonal_factor">1.0</field>
9 </record>
10 <record id="product_seasonal_id2" model="product.seasonal">
11 <field name="name">Christmas Seasonal</field>
12 <field name="code">christmas</field>
13 <field name="seasonal_factor">1.12</field>
14 </record>
15
16 </data>
17</openerp>
018
=== modified file 'stock_minimum_calculator/stock_minimum_calculator_sequence.xml'
--- stock_minimum_calculator/stock_minimum_calculator_sequence.xml 2010-06-11 07:42:16 +0000
+++ stock_minimum_calculator/stock_minimum_calculator_sequence.xml 2010-06-15 07:09:25 +0000
@@ -3,12 +3,12 @@
3 <data noupdate="1">3 <data noupdate="1">
4 <!-- Sequences for stock.orderpoint.step2 -->4 <!-- Sequences for stock.orderpoint.step2 -->
5 <record id="sequence_stock_op_point" model="ir.sequence.type">5 <record id="sequence_stock_op_point" model="ir.sequence.type">
6 <field name="name">Stock orderpoint step2</field>6 <field name="name">Stock orderpoint Calculator</field>
7 <field name="code">stock.orderpoint.step2</field>7 <field name="code">stock.orderpoint.calculator</field>
8 </record>8 </record>
9 <record id="sequence_stock_op" model="ir.sequence">9 <record id="sequence_stock_op" model="ir.sequence">
10 <field name="name">Stock orderpoint step2</field>10 <field name="name">stock orderpoint Calculator</field>
11 <field name="code">stock.orderpoint.step2</field>11 <field name="code">stock.orderpoint.calculator</field>
12 <field name="prefix">OP/</field>12 <field name="prefix">OP/</field>
13 <field name="padding">5</field>13 <field name="padding">5</field>
14 <field name="number_increment">1</field>14 <field name="number_increment">1</field>
1515
=== modified file 'stock_minimum_calculator/stock_minimum_calculator_view.xml'
--- stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-10 06:28:31 +0000
+++ stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-15 07:09:25 +0000
@@ -2,7 +2,7 @@
2<openerp>2<openerp>
3 <data>3 <data>
4 4
5 <record id="stock_holding_rate_tree_view" model="ir.ui.view">5 <record id="stock_holding_rate_tree_view" model="ir.ui.view">
6 <field name="name">stock.holding.rate.tree</field>6 <field name="name">stock.holding.rate.tree</field>
7 <field name="model">stock.holding.rate</field>7 <field name="model">stock.holding.rate</field>
8 <field name="type">tree</field>8 <field name="type">tree</field>
@@ -52,69 +52,8 @@
52 <field name="view_type">form</field>52 <field name="view_type">form</field>
53 <field name="view_id" ref="stock_holding_rate_tree_view"/>53 <field name="view_id" ref="stock_holding_rate_tree_view"/>
54 </record>54 </record>
55
55 <menuitem action="stock_holding_rate_tree_view_normal_action" id="menu_stock_holding_rate" parent="stock.menu_stock_configuration"/>56 <menuitem action="stock_holding_rate_tree_view_normal_action" id="menu_stock_holding_rate" parent="stock.menu_stock_configuration"/>
56
57 <record id="supplier_cost_opti_lead_time_tree_view" model="ir.ui.view">
58 <field name="name">supplier.cost.opti.lead.time.tree</field>
59 <field name="model">supplier.cost.opti.lead.time</field>
60 <field name="type">tree</field>
61 <field name="arch" type="xml">
62 <tree string="Supplier Cost Optimated Lead Times">
63 <field name="supp_cost_id"/>
64 <field name="name"/>
65 <field name="partner_id"/>
66 <field name="date_start"/>
67 <field name="yrl_purchase_rev"/>
68 <field name="economic_no_order"/>
69 <field name="cost_per_del"/>
70 <field name="economic_lead_time"/>
71 <field name="stock_holding_rate_id"/>
72 <field name="staus"/>
73 </tree>
74 </field>
75 </record>
76
77 <record id="supplier_cost_opti_lead_time_form_view" model="ir.ui.view">
78 <field name="name">supplier.cost.opti.lead.time.form</field>
79 <field name="model">supplier.cost.opti.lead.time</field>
80 <field name="type">form</field>
81 <field name="arch" type="xml">
82 <form string="Supplier Cost Optimated Lead Times">
83 <group colspan="6" col="6">
84 <field name="name"/>
85 <field name="supp_cost_id"/>
86 <field name="active"/>
87 <field name="partner_id"/>
88 <field name="date_start"/>
89 </group>
90 <group colspan="2" col="2">
91 <separator colspan="4" string="Automatic Declaration"/>
92 <field name="yrl_purchase_rev"/>
93 <field name="cost_per_del"/>
94 <field name="stock_holding_rate_id"/>
95 </group>
96 <group colspan="2" col="2">
97 <separator colspan="4" string="Economic Number of orders"/>
98 <field name="economic_no_order"/>
99 <field name="economic_lead_time"/>
100 <button name="action_compute" string="Calculate Lead Time" type="object"/>
101 </group>
102 <field name="staus"/>
103 <button name="action_cancel" string="Cancel" type="object"/>
104 <button name="action_validate" string="Valid" type="object"/>
105 </form>
106 </field>
107 </record>
108 <record id="supplier_cost_opti_lead_time_normal_action" model="ir.actions.act_window">
109 <field name="name">Supplier Cost Optimated Lead Times</field>
110 <field name="type">ir.actions.act_window</field>
111 <field name="res_model">supplier.cost.opti.lead.time</field>
112 <field name="view_type">form</field>
113 <field name="view_id" ref="supplier_cost_opti_lead_time_tree_view"/>
114 </record>
115 <menuitem action="supplier_cost_opti_lead_time_normal_action" id="menu_supplier_cost_opti_lead_time" parent="stock.menu_stock_configuration"/>
116
117
118 57
119 <record id="product_seasonal_tree_view" model="ir.ui.view">58 <record id="product_seasonal_tree_view" model="ir.ui.view">
120 <field name="name">product.seasonal.tree</field>59 <field name="name">product.seasonal.tree</field>
@@ -150,17 +89,6 @@
150 </record>89 </record>
151 <menuitem action="product_seasonal_normal_action" id="menu_product_seasonal" parent="stock.menu_stock_configuration"/> 90 <menuitem action="product_seasonal_normal_action" id="menu_product_seasonal" parent="stock.menu_stock_configuration"/>
152 91
153 <record model="ir.ui.view" id="view_supplier_holding_rate_form1">
154 <field name="name">res.partner.form</field>
155 <field name="model">res.partner</field>
156 <field name="inherit_id" ref="stock.view_partner_property_form"/>
157 <field name="type">form</field>
158 <field name="arch" type="xml">
159 <field name="property_stock_supplier" position="after">
160 <field name="stock_holding_rate_id" />
161 </field>
162 </field>
163 </record>
164 <record model="ir.ui.view" id="view_supplier_holding_rate_form">92 <record model="ir.ui.view" id="view_supplier_holding_rate_form">
165 <field name="name">product.product.form</field>93 <field name="name">product.product.form</field>
166 <field name="model">product.product</field>94 <field name="model">product.product</field>
16795
=== removed file 'stock_minimum_calculator/stock_order_point_calculator.py'
--- stock_minimum_calculator/stock_order_point_calculator.py 2010-06-11 07:42:16 +0000
+++ stock_minimum_calculator/stock_order_point_calculator.py 1970-01-01 00:00:00 +0000
@@ -1,217 +0,0 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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##############################################################################
21from osv import fields, osv
22import time
23from tools.translate import _
24
25class stock_orderpoint_step1(osv.osv_memory):
26
27 _name="stock.orderpoint.step1"
28 _columns = {
29 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse',required=True),
30 'deactive': fields.boolean('Deactive Existing Rules'),
31 'delactive': fields.boolean('Delete Exiting Rules(for this warehosue)'),
32 }
33
34 def _de_next(self, cr, uid, ids, context=None):
35
36 mod_obj = self.pool.get('ir.model.data')
37 product_obj = self.pool.get('product.product')
38 min_rule_obj = self.pool.get('stock.warehouse.orderpoint')
39 form = self.read(cr, uid, ids, [])[0]
40
41 stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',form['warehouse_id'])])
42
43 if form['deactive']:
44 for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context):
45 min_rule_obj.write(cr, uid, [stock_rule_id.id], {'active':False}, context=context)
46
47 elif form['delactive']:
48 for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context):
49 min_rule_obj.unlink(cr, uid, [stock_rule_id.id],context=context)
50
51
52 model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_stock_orderpoint_step2')], context=context)
53 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
54 return {
55 'name': _('Stock Orderpoint Step2'),
56 'context': context,
57 'view_type': 'form',
58 'view_mode': 'form',
59 'res_model': 'stock.orderpoint.step2',
60 'views': [(resource_id,'form')],
61 'type': 'ir.actions.act_window',
62 'target': 'new',
63 }
64stock_orderpoint_step1()
65
66
67class stock_orderpoint_step2(osv.osv_memory):
68
69 _name="stock.orderpoint.step2"
70 _columns = {
71 'min_qty_calculation': fields.selection([('optimal_stock_coverage', 'Optimal Stock Coverage'),
72 ('normal_stock_coverage', 'Normal Stock Coverage'),
73 ], 'Method Calculation Minimum Qty',required=True),
74 'max_qty_calculation': fields.selection([('optimal_stock_coverage', 'Optimal Stock Coverage'),
75 ('normal_stock_coverage', 'Normal Stock Coverage'),
76 ], 'Method Calculation Maximum Qty',required=True),
77 }
78 _defaults = {
79 'min_qty_calculation': lambda *a: 'optimal_stock_coverage',
80 'max_qty_calculation': lambda *a: 'optimal_stock_coverage',
81 }
82
83 def _next_calculate(self, cr, uid, ids, context=None):
84
85 purchase_obj = self.pool.get('purchase.order')
86 sale_obj = self.pool.get('sale.order')
87 product_obj = self.pool.get('product.product')
88 supp_obj = self.pool.get("product.supplierinfo")
89 supp_cost_opt_obj = self.pool.get("supplier.cost.opti.lead.time")
90 wizard_obj = self.pool.get("stock.orderpoint.step1")
91 min_rule_obj = self.pool.get('stock.warehouse.orderpoint')
92 order_period_obj = self.pool.get("stock.warehosue.orderpoint.period")
93
94 form = self.read(cr, uid, ids, [])[0]
95
96 purchase_ids = purchase_obj.search(cr,uid,[])
97 start_pur_id = min(purchase_ids)
98 last_pur_id = max(purchase_ids)
99
100 ############# Calculation of purchase Quantity upto today
101 purchase_qty = 0.0
102 if purchase_ids:
103 for pur_id in purchase_ids:
104 purchase_data = purchase_obj.browse(cr,uid,pur_id)
105 for line in purchase_data.order_line:
106 purchase_qty += line.product_qty
107
108
109 ##### Calculation of sale order Quantity of open orders
110 sale_qty = 0.0
111 sale_ids = self.pool.get('sale.order').search(cr, uid, [('state','in',['manual','progress'])])
112 if sale_ids:
113 for sale_id in sale_ids:
114 sale_data = self.pool.get('sale.order').browse(cr,uid,sale_id)
115 for line in sale_data.order_line:
116 sale_qty += line.product_uom_qty
117
118
119 ##################calculation of date difference between first and last purchase order
120 first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order
121 last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order
122 first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d'))
123 last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d'))
124 diff_day = (last_date-first_date)/(3600*24)
125
126 ##### Calculation of purchase lead time
127 purchase_lead_time = 0.0
128 company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
129 purchase_lead_time = company.po_lead
130
131 ##### Calculation of supplier lead time
132 product_id = product_obj.browse(cr, uid, context['id'], context)
133 supplier_lead_time = 0.0
134 if product_id:
135 for supp in product_id.seller_ids:
136 sup = supp_obj.browse(cr, uid, supp.id, context)
137 supplier_lead_time = sup.delay
138
139
140 ##### Calculation of average_daily_consumption
141 average_daily_consumption = 0.0
142 if purchase_ids and diff_day > 0.0:
143 average_daily_consumption = (sale_qty + purchase_qty )/diff_day
144 else:
145 plan_consume = product_id.plan_avg_consume
146 average_daily_consumption = plan_consume
147 ######### calculation of safety stock
148 safety_stock = purchase_qty / len(purchase_ids)
149
150 ### calculation of Economic lead time (days)
151 cost_op_id = supp_cost_opt_obj.search(cr, uid, [('partner_id','=',sup.name.id)])
152 economic_lead_days = 0.0
153 economic_numer_orders = 0.0
154 economic_lead_time = 0.0
155 if cost_op_id:
156 cost_op = supp_cost_opt_obj.browse(cr, uid,cost_op_id[0])
157 economic_numer_orders = cost_op.economic_no_order
158 economic_lead_time = cost_op.economic_lead_time
159 economic_lead_days = economic_lead_time * 30 #Economic leaddays: field economic leadtime from supplier.leadtimes * 30
160
161 ### Calculation of the percentage of this days period
162 future_seasonal_fac = 0.0
163 periods = self.pool.get('account.period').find(cr, uid)
164 for period in periods:
165 trend_id = order_period_obj.search(cr, uid, [('period_id','=',period)])
166 if trend_id:
167 per = order_period_obj.browse(cr, uid,trend_id[0]).percentage
168 future_seasonal_fac = economic_lead_days + purchase_lead_time / per
169
170 #### Calculation of seasonal Factor
171
172 #??????seasonal factor = percentage of product.seasonaltrend for future period of follwing date:
173 #today + economic lead days + purchase lead time / "percentage of this days period"
174 seasonal_fac = 0.0
175 seasonal_fac = product_id.seasonal_id.seasonal_factor
176
177
178 ### Calculation for minimum quantity
179 optimal_stock_coverage = 0.0
180 normal_stock_coverage = 0.0
181 if form['min_qty_calculation'] == 'optimal_stock_coverage':
182 optimal_stock_coverage = average_daily_consumption * seasonal_fac * (economic_lead_days + purchase_lead_time) / safety_stock
183 else:
184 normal_stock_coverage = average_daily_consumption * (supplier_lead_time + purchase_lead_time)/safety_stock
185
186
187 ### Calculation for maximum quantity
188 optimal_stock_coverage_max = 0.0
189 normal_stock_coverage_max = 0.0
190 if form['max_qty_calculation'] == 'optimal_stock_coverage':
191 optimal_stock_coverage_max = (average_daily_consumption * seasonal_fac * (economic_lead_days + purchase_lead_time))
192 else:
193 normal_stock_coverage_max = average_daily_consumption * (supplier_lead_time + purchase_lead_time)
194
195 ids = wizard_obj.search(cr, uid, [])
196
197 wizz_id = wizard_obj.browse(cr, uid, ids[0])
198 max1 = 'max'
199 name = self.pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.step2')
200
201 self.pool.get('stock.warehouse.orderpoint').create(cr, uid, {
202 'name': name,
203 'active': True,
204 'warehouse_id': wizz_id.warehouse_id.id,
205 'location_id': product_id.property_stock_inventory.id,
206 'product_id': context['id'],
207 'product_min_qty': optimal_stock_coverage or normal_stock_coverage,
208 'product_max_qty': optimal_stock_coverage_max or normal_stock_coverage_max,
209 'qty_multiple':1,
210 'product_uom':product_id.uom_id.id,
211 'logic':'max'
212 } )
213 return {}
214
215stock_orderpoint_step2()
216
217# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
218\ No newline at end of file0\ No newline at end of file
2191
=== removed file 'stock_minimum_calculator/stock_order_point_calculator_view.xml'
--- stock_minimum_calculator/stock_order_point_calculator_view.xml 2010-06-09 14:36:04 +0000
+++ stock_minimum_calculator/stock_order_point_calculator_view.xml 1970-01-01 00:00:00 +0000
@@ -1,50 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="view_account_invoice_pay" model="ir.ui.view">
5 <field name="name">stock.orderpoint.step1.form</field>
6 <field name="model">stock.orderpoint.step1</field>
7 <field name="type">form</field>
8 <field name="arch" type="xml">
9 <form string="Wizard Order Point Calculator Step1 - Choose Warehouse and Updating Settings">
10 <group colspan="4" >
11 <field name="warehouse_id"/>
12 <field name="deactive"/>
13 <field name="delactive"/>
14 </group>
15 <group colspan="4" col="6">
16 <label string ="" colspan="2"/>
17 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
18 <button icon="gtk-execute" string="Next Step" name="_de_next" type="object"/>
19 </group>
20 </form>
21 </field>
22 </record>
23
24 <act_window name="Orderpoint Calculator"
25 res_model="stock.orderpoint.step1"
26 src_model="product.product"
27 view_mode="form"
28 target="new"
29 context="{'id': active_id}"
30 id="action_view_stock_orderpoint_step1"/>
31
32 <record id="view_stock_orderpoint_step2" model="ir.ui.view">
33 <field name="name">stock.orderpoint.step2.form</field>
34 <field name="model">stock.orderpoint.step2</field>
35 <field name="type">form</field>
36 <field name="arch" type="xml">
37 <form string="Wizard Order Point Calculator Step2 - Choose Method">
38 <field name="min_qty_calculation"/>
39 <field name="max_qty_calculation" />
40 <group colspan="4" col="6">
41 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
42 <button icon="gtk-execute" string="Next Step" name="_next_calculate" type="object"/>
43 </group>
44 </form>
45 </field>
46 </record>
47
48
49 </data>
50</openerp>
51\ No newline at end of file0\ No newline at end of file
521
=== added file 'stock_minimum_calculator/supplier_cost_optimated_leadtimes.py'
--- stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 1970-01-01 00:00:00 +0000
+++ stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 2010-06-15 07:09:25 +0000
@@ -0,0 +1,89 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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##############################################################################
21from osv import fields, osv
22import time
23from tools.translate import _
24from mx import DateTime
25
26class supplier_cost_optimated_leadtimes(osv.osv_memory):
27
28 _name="supplier.cost.optimated.leadtimes"
29 _columns = {
30 'partner_id': fields.many2one('res.partner', 'Suplier'),
31 'account_purchase_rev': fields.many2one('account.analytic.account', 'Acc. Purchase Revenues', required=True),
32 'account_cost_pre_del': fields.many2one('account.analytic.account', 'Acc. Delivery Cost'),
33 'date_start': fields.date('From Period', required=True),
34 'date_stop': fields.date('To Period', required=True),
35 'purchase_rev':fields.float("Purchase Revenue",readonly=True,),
36 'economic_no_order':fields.float("Economic Number of orders",readonly=True),
37 'cost_per_del':fields.float("Cost Per Delivery",readonly=True),
38 'economic_lead_time':fields.float("Economic Lead Time", readonly=True),
39 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate',required=True),
40 }
41
42 def _compute(self, cr, uid, ids, context=None):
43
44 form = self.read(cr, uid, ids, [], context=context)[0]
45
46 analytic_account_obj = self.pool.get('account.analytic.account')
47 analytic_line_obj = self.pool.get('account.analytic.line')
48 stock_hold_rate_obj = self.pool.get("stock.holding.rate")
49
50 date_start = form['date_start']
51 date_stop = form['date_stop']
52
53 pur_balance = 0.0
54 pur_analytic_id = form['account_purchase_rev']
55
56 pur_analytic_line_id = analytic_line_obj.search(cr,uid,[('account_id','=',pur_analytic_id), ('date','>=',date_start),('date','<=',date_stop)])
57
58 if pur_analytic_line_id:
59 for pur_analytic_id in pur_analytic_line_id:
60 pur_analytic_amount = analytic_line_obj.browse(cr, uid, pur_analytic_id, context)
61 balance = pur_analytic_amount.amount
62 pur_balance += balance
63
64
65 cost_del_analytic_id = form['account_cost_pre_del']
66 cost_balance = 0.0
67
68 cost_del_analytic_line_id = analytic_line_obj.search(cr,uid,[('account_id','=',cost_del_analytic_id), ('date','>=',date_start),('date','<=',date_stop)])
69
70 if cost_del_analytic_line_id:
71 for cost_analytic_id in cost_del_analytic_line_id:
72 cost_analytic_amount = analytic_line_obj.browse(cr, uid, cost_analytic_id, context)
73 balance = cost_analytic_amount.amount
74 cost_balance += balance
75
76 stock_hold_id = stock_hold_rate_obj.browse(cr, uid, form['stock_holding_rate_id'])
77 stock_hold_rate = stock_hold_id.stock_hold_rate
78
79 if pur_balance and cost_balance:
80 for id in ids:
81 economic_numer_orders = (pur_balance * stock_hold_rate)/ (2 * cost_balance)
82 economic_lead_time = 360 / economic_numer_orders
83 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})
84
85 return True
86
87supplier_cost_optimated_leadtimes()
88
89# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file90\ No newline at end of file
191
=== added file 'stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml'
--- stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml 1970-01-01 00:00:00 +0000
+++ stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml 2010-06-15 07:09:25 +0000
@@ -0,0 +1,46 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record id="view_supplier_cost_optimated_leadtimes" model="ir.ui.view">
5 <field name="name">supplier.cost.optimated.leadtimes.form</field>
6 <field name="model">supplier.cost.optimated.leadtimes</field>
7 <field name="type">form</field>
8 <field name="arch" type="xml">
9 <form string="Wizard to Calculate Cost Optimized Lead Times">
10 <group colspan="4" >
11 <field name="partner_id"/>
12 <field name="stock_holding_rate_id"/>
13 <field name="date_start"/>
14 <field name="account_purchase_rev"/>
15 <field name="date_stop"/>
16 <field name="account_cost_pre_del"/>
17 <separator colspan="4" string="Result of Calculation"/>
18 <field name="purchase_rev"/>
19 <field name="economic_no_order"/>
20 <field name="cost_per_del"/>
21 <field name="economic_lead_time"/>
22 </group>
23
24 <group colspan="4" col="4">
25 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
26 <button icon="gtk-execute" string="Calculate Lead Time" name="_compute" type="object"/>
27 </group>
28 </form>
29 </field>
30 </record>
31
32 <record id="action_supplier_cost_optimated_leadtimes" model="ir.actions.act_window">
33 <field name="name">Supplier Cost Optimated Leadtimes</field>
34 <field name="type">ir.actions.act_window</field>
35 <field name="res_model">supplier.cost.optimated.leadtimes</field>
36 <field name="view_type">form</field>
37 <field name="view_mode">form</field>
38 <field name="view_id" ref="view_supplier_cost_optimated_leadtimes"/>
39 <field name="target">new</field>
40 </record>
41 <menuitem action="action_supplier_cost_optimated_leadtimes"
42 id="menu_action_supplier_cost_optimated_leadtimesy"
43 parent="stock.next_id_61"/>
44
45 </data>
46</openerp>
0\ No newline at end of file47\ No newline at end of file
148
=== modified file 'stock_minimum_calculator/wizard/__init__.py'
--- stock_minimum_calculator/wizard/__init__.py 2010-06-09 14:36:04 +0000
+++ stock_minimum_calculator/wizard/__init__.py 2010-06-15 07:09:25 +0000
@@ -21,6 +21,7 @@
21##############################################################################21##############################################################################
2222
23import seasonal_trend_set23import seasonal_trend_set
24import stock_order_point_calculator
2425
25# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:26# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2627
2728
=== removed file 'stock_minimum_calculator/wizard/seasonal_trend_set_view.xml'
--- stock_minimum_calculator/wizard/seasonal_trend_set_view.xml 2010-06-09 14:36:04 +0000
+++ stock_minimum_calculator/wizard/seasonal_trend_set_view.xml 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="view_stock_order_rule" model="ir.ui.view">
6 <field name="name">product.seasonal.trend.form</field>
7 <field name="model">product.seasonal.trend</field>
8 <field name="type">form</field>
9 <field name="arch" type="xml">
10 <form string="Set Seasonal Trend">
11 <field name="trend_seasonal_id" />
12 <field name="active" />
13 <group colspan="4" col="6">
14 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
15 <button icon="gtk-execute" string="OK" name="_set_seasonal" type="object"/>
16 </group>
17 </form>
18 </field>
19 </record>
20
21 <act_window
22 res_model = "product.seasonal.trend"
23 src_model = "product.product"
24 view_type = "form"
25 view_mode = "form"
26 name= "Set Seasonal Trend"
27 target="new"
28 context="{'id': active_id}"
29 id="action_product_seasonal_trend"/>
30
31 </data>
32</openerp>
33\ No newline at end of file0\ No newline at end of file
341
=== added file 'stock_minimum_calculator/wizard/stock_order_point_calculator.py'
--- stock_minimum_calculator/wizard/stock_order_point_calculator.py 1970-01-01 00:00:00 +0000
+++ stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-06-15 07:09:25 +0000
@@ -0,0 +1,241 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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
22import wizard
23import pooler
24import time
25from tools.translate import _
26import mx.DateTime
27from mx.DateTime import RelativeDateTime, now, DateTime, localtime
28
29orderpoint_calculator_form = """<?xml version="1.0"?>
30<form string="Order Point Calculator ">
31 <field name="warehouse_id"/>
32 <field name="location_id"/>
33 <field name="seasonal_id"/>
34 <field name="delactive"/>
35 <field name="method_qty_calculation" colspan="4"/>
36 <group attrs="{'invisible':[('method_qty_calculation','=','his_cons_without_product')]}" colspan="4">
37 <separator string="Configuration of Base Consumptions Periods" colspan="4"/>
38 <field name="date_start"/>
39 <field name="date_stop"/>
40 </group>
41</form>"""
42
43orderpoint_calculator_fields = {
44 'warehouse_id': {
45 'string': 'Warehouse',
46 'type': 'many2one',
47 'relation': 'stock.warehouse',
48 'required': True
49 },
50
51 'delactive': {
52 'string':'Delete Exiting Rules(for this warehosue)',
53 'type':'boolean'
54 },
55
56 'location_id': {
57 'string': 'Location',
58 'type': 'many2one',
59 'relation': 'stock.location',
60 'required': True
61 },
62
63 'seasonal_id': {
64 'string': 'Season of Consumption',
65 'type': 'many2one',
66 'relation': 'product.seasonal',
67 'required': True
68 },
69
70 'date_start': {
71 'string':'From Date',
72 'type':'date'
73 },
74
75 'date_stop': {
76 'string':'To Date',
77 'type':'date',
78 'default': lambda *a: time.strftime('%Y-%m-%d')
79 },
80
81 'method_qty_calculation':{
82 'string':"Method Calculation",
83 'type':'selection',
84 'selection':[('his_cons_with_product', 'Calculate with historical consumptions of products'),
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 ],'required': True,
88 'default': lambda *a:'his_cons_with_product'
89 },
90 }
91
92def _get_default(obj, cr, uid, data, context=None):
93 pool = pooler.get_pool(cr.dbname)
94
95 warehouse_id = pool.get('stock.warehouse').search(cr, uid, [])[0]
96 location_id = pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0]
97
98 date = now().strftime('%Y-%m-%d')
99 date = mx.DateTime.strptime(date, '%Y-%m-%d') - RelativeDateTime(months=3)
100 date = date.strftime('%Y-%m-%d')
101
102 return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':date}
103
104def _do_calculate(self, cr, uid, data, context):
105
106 pool = pooler.get_pool(cr.dbname)
107
108 purchase_obj = pool.get('purchase.order')
109 sale_obj = pool.get('sale.order')
110 product_obj = pool.get('product.product')
111 supp_obj = pool.get('product.supplierinfo')
112 supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time')
113 min_rule_obj = pool.get('stock.warehouse.orderpoint')
114
115 stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id'])])
116 if data['form']['delactive']:
117 for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context):
118 min_rule_obj.unlink(cr, uid, [stock_rule_id.id],context=context)
119
120 ##### Calculation of purchase lead time
121 purchase_lead_time = 0.0
122 company = pool.get('res.users').browse(cr, uid, uid, context).company_id
123 purchase_lead_time = company.po_lead
124
125 ##### Calculation of supplier lead time
126
127 for id in data['ids']:
128 product_id = product_obj.browse(cr, uid, id, context)
129 supplier_lead_time = 0.0
130 if product_id:
131 for supp in product_id.seller_ids:
132 sup = supp_obj.browse(cr, uid, supp.id, context)
133 supplier_lead_time = sup.delay
134
135 ###### Calculation of average_daily_consumption
136 date_start = data['form']['date_start']
137 date_stop = data['form']['date_stop']
138 average_daily_consumption = 0.0
139 consum_qty = 0.0
140 sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)])
141 if sale_ids:
142 for sid in sale_ids:
143 sale_data = sale_obj.browse(cr,uid,sid)
144 for line in sale_data.order_line:
145 consum_qty += line.product_uom_qty
146
147 ##################calculation of date difference between first and last sale order
148 sale_ids = sale_obj.search(cr,uid,[])
149 if sale_ids:
150 start_sale_id = min(sale_ids)
151 last_sale_id = max(sale_ids)
152 first_sale_date = sale_obj.browse(cr,uid,start_sale_id).date_order
153 last_sale_date = sale_obj.browse(cr,uid,last_sale_id).date_order
154 first_date = time.mktime(time.strptime(first_sale_date,'%Y-%m-%d'))
155 last_date = time.mktime(time.strptime(last_sale_date,'%Y-%m-%d'))
156 diff_day = (last_date-first_date)/(3600*24)
157 if diff_day > 0:
158 average_daily_consumption = consum_qty / diff_day
159
160 ###### Calculation of plan_average_daily_consumption
161 plan_average_daily_consumption = 0.0
162 if product_id.plan_avg_consume:
163 plan_average_daily_consumption = product_id.plan_avg_consume
164
165 ########## calculation historical consumption of products and open sales orders“
166 ### total sale qty with open state
167
168 sale_qty = 0.0
169 sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])])
170 if sale_ids:
171 for sale_id in sale_ids:
172 sale_data = sale_obj.browse(cr,uid,sale_id)
173 for line in sale_data.order_line:
174 sale_qty += line.product_uom_qty
175
176 ###################
177 purchase_ids = purchase_obj.search(cr,uid,[])
178 if purchase_ids:
179 start_pur_id = min(purchase_ids)
180 last_pur_id = max(purchase_ids)
181
182 ##################calculation of date difference between first and last purchase order
183 first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order
184 last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order
185 first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d'))
186 last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d'))
187 pur_diff_day = (last_date-first_date)/(3600*24)
188
189 product_max_qty = 0.0
190 product_min_qty = 0.0
191
192 if data['form']['method_qty_calculation'] == 'his_cons_with_product':
193 product_min_qty = average_daily_consumption * (supplier_lead_time + purchase_lead_time)
194 product_max_qty = 2 * product_min_qty
195
196 elif data['form']['method_qty_calculation'] == 'his_cons_without_product':
197 product_min_qty = plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time)
198 product_max_qty = 2 * product_min_qty
199
200 else:
201 product_min_qty = (average_daily_consumption + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time)
202 product_max_qty = 2 * product_min_qty
203
204 max1 = 'max'
205 name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator')
206 pool.get('stock.warehouse.orderpoint').create(cr, uid, {
207 'name': name,
208 'active': True,
209 'warehouse_id': data['form']['warehouse_id'],
210 'location_id': product_id.property_stock_inventory.id,
211 'product_id': id,
212 'product_min_qty': product_min_qty,
213 'product_max_qty': product_max_qty,
214 'qty_multiple':1,
215 'product_uom':product_id.uom_id.id,
216 'logic':'max'
217 } )
218
219 return {}
220
221class orderpoint_calculator(wizard.interface):
222 states = {
223 'init' : {
224 'actions' : [_get_default],
225 'result' : {'type' : 'form',
226 'arch' : orderpoint_calculator_form,
227 'fields' : orderpoint_calculator_fields,
228 'state' : [('end', 'Cancel'),('calculation', 'Calculation') ]}
229 },
230 'calculation' : {
231 'actions' : [],
232 'result' : {'type' : 'action',
233 'action' : _do_calculate,
234 'state' : 'end'}
235 }
236 }
237orderpoint_calculator("orderpoint.calculator")
238
239
240
241# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file242\ No newline at end of file

Subscribers

People subscribed via source and target branches