Merge lp:~openbig/bigconsulting/changes_in_stock_minimum_calculator into lp:bigconsulting
- changes_in_stock_minimum_calculator
- Merge into addons
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
openbig | Pending | ||
Review via email: mp+27589@code.launchpad.net |
Commit message
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
1 | === modified file 'stock_minimum_calculator/__init__.py' | |||
2 | --- stock_minimum_calculator/__init__.py 2010-06-09 14:36:04 +0000 | |||
3 | +++ stock_minimum_calculator/__init__.py 2010-06-15 07:09:25 +0000 | |||
4 | @@ -21,6 +21,8 @@ | |||
5 | 21 | ############################################################################## | 21 | ############################################################################## |
6 | 22 | 22 | ||
7 | 23 | import stock_minimum_calculator | 23 | import stock_minimum_calculator |
8 | 24 | import stock_order_point_calculator | ||
9 | 25 | import supplier_cost_optimated_leadtimes | ||
10 | 24 | import wizard | 26 | import wizard |
12 | 25 | import stock_order_point_calculator | 27 | |
13 | 26 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | 28 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
14 | 27 | \ No newline at end of file | 29 | \ No newline at end of file |
15 | 28 | 30 | ||
16 | === modified file 'stock_minimum_calculator/__terp__.py' | |||
17 | --- stock_minimum_calculator/__terp__.py 2010-06-11 07:42:16 +0000 | |||
18 | +++ stock_minimum_calculator/__terp__.py 2010-06-15 07:09:25 +0000 | |||
19 | @@ -30,11 +30,11 @@ | |||
20 | 30 | we have proper re-order quentity for each products. | 30 | we have proper re-order quentity for each products. |
21 | 31 | """, | 31 | """, |
22 | 32 | "depends": ['stock','mrp'], | 32 | "depends": ['stock','mrp'], |
24 | 33 | "demo_xml": [], | 33 | "demo_xml": ["stock_minimum_calculator_demo.xml"], |
25 | 34 | "update_xml": ['stock_minimum_calculator_view.xml', | 34 | "update_xml": ['stock_minimum_calculator_view.xml', |
26 | 35 | "stock_minimujm_calculator_wizard.xml", | 35 | "stock_minimujm_calculator_wizard.xml", |
29 | 36 | "stock_order_point_calculator_view.xml", | 36 | "stock_minimum_calculator_sequence.xml", |
30 | 37 | "stock_minimum_calculator_sequence.xml" | 37 | "supplier_cost_optimated_leadtimes_view.xml", |
31 | 38 | ], | 38 | ], |
32 | 39 | "license": "GPL-3", | 39 | "license": "GPL-3", |
33 | 40 | "active": False, | 40 | "active": False, |
34 | 41 | 41 | ||
35 | === modified file 'stock_minimum_calculator/stock_minimujm_calculator_wizard.xml' | |||
36 | --- stock_minimum_calculator/stock_minimujm_calculator_wizard.xml 2010-06-09 14:36:04 +0000 | |||
37 | +++ stock_minimum_calculator/stock_minimujm_calculator_wizard.xml 2010-06-15 07:09:25 +0000 | |||
38 | @@ -7,5 +7,12 @@ | |||
39 | 7 | name="set_seasonal.trend" | 7 | name="set_seasonal.trend" |
40 | 8 | menu="True" | 8 | menu="True" |
41 | 9 | id="id_set_seasonal_trend"/> | 9 | id="id_set_seasonal_trend"/> |
42 | 10 | <wizard | ||
43 | 11 | string="Order Point Cacluator" | ||
44 | 12 | model="product.product" | ||
45 | 13 | name="orderpoint.calculator" | ||
46 | 14 | menu="True" | ||
47 | 15 | id="id_order_point_cacluator"/> | ||
48 | 16 | |||
49 | 10 | </data> | 17 | </data> |
50 | 11 | </openerp> | 18 | </openerp> |
51 | 12 | 19 | ||
52 | === modified file 'stock_minimum_calculator/stock_minimum_calculator.py' | |||
53 | --- stock_minimum_calculator/stock_minimum_calculator.py 2010-06-11 06:02:15 +0000 | |||
54 | +++ stock_minimum_calculator/stock_minimum_calculator.py 2010-06-15 07:09:25 +0000 | |||
55 | @@ -36,7 +36,6 @@ | |||
56 | 36 | } | 36 | } |
57 | 37 | stock_holding_rate() | 37 | stock_holding_rate() |
58 | 38 | 38 | ||
59 | 39 | |||
60 | 40 | class supplier_product(osv.osv): | 39 | class supplier_product(osv.osv): |
61 | 41 | _name = 'supplier.product' | 40 | _name = 'supplier.product' |
62 | 42 | _rec_name = 'partner_id' | 41 | _rec_name = 'partner_id' |
63 | @@ -48,63 +47,6 @@ | |||
64 | 48 | 47 | ||
65 | 49 | supplier_product() | 48 | supplier_product() |
66 | 50 | 49 | ||
67 | 51 | class res_partner(osv.osv): | ||
68 | 52 | _inherit = "res.partner" | ||
69 | 53 | _columns = { | ||
70 | 54 | 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate'), | ||
71 | 55 | } | ||
72 | 56 | res_partner() | ||
73 | 57 | |||
74 | 58 | |||
75 | 59 | class supplier_cost_opti_lead_time(osv.osv): | ||
76 | 60 | _name = "supplier.cost.opti.lead.time" | ||
77 | 61 | _columns = { | ||
78 | 62 | 'supp_cost_id':fields.char("ID",size=64, required=True), | ||
79 | 63 | 'name':fields.char("Name of the rule",size=64, required=True), | ||
80 | 64 | 'partner_id': fields.many2one('res.partner', 'Suplier'), | ||
81 | 65 | 'date_start': fields.date('Date', required=True), | ||
82 | 66 | 'active': fields.boolean('Active'), | ||
83 | 67 | 'yrl_purchase_rev':fields.float("YRL Purchase Revenue",required=True), | ||
84 | 68 | 'economic_no_order':fields.float("Economic Number of orders",readonly=True), | ||
85 | 69 | 'cost_per_del':fields.float("Cost Per Delivery",required=True), | ||
86 | 70 | 'economic_lead_time':fields.float("Economic Lead Time",readonly=True), | ||
87 | 71 | 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate',required=True), | ||
88 | 72 | 'staus': fields.selection([ | ||
89 | 73 | ('draft','Draft'), | ||
90 | 74 | ('valid','Valid'), | ||
91 | 75 | ('cancel','Cancel'), | ||
92 | 76 | ],'Status',readonly=True), | ||
93 | 77 | } | ||
94 | 78 | _defaults = { | ||
95 | 79 | 'date_start': lambda *a: time.strftime('%Y-%m-%d'), | ||
96 | 80 | } | ||
97 | 81 | |||
98 | 82 | def action_compute(self, cr, uid, ids, context={}): | ||
99 | 83 | for id in ids: | ||
100 | 84 | cost_op = self.browse(cr, uid,id,context=context) | ||
101 | 85 | economic_numer_orders = (cost_op.yrl_purchase_rev * cost_op.stock_holding_rate_id.stock_hold_rate)/ (2*cost_op.cost_per_del) | ||
102 | 86 | economic_lead_time = 360 / economic_numer_orders | ||
103 | 87 | self.write(cr, uid, [id],{'economic_lead_time':economic_lead_time,'economic_no_order':economic_numer_orders}) | ||
104 | 88 | return True | ||
105 | 89 | |||
106 | 90 | def action_cancel(self, cr, uid, ids, context={}): | ||
107 | 91 | for o in self.browse(cr, uid, ids): | ||
108 | 92 | self.write(cr, uid, [o.id], {'staus': 'cancel'}) | ||
109 | 93 | return True | ||
110 | 94 | |||
111 | 95 | def action_validate(self, cr, uid, ids, context={}): | ||
112 | 96 | for o in self.browse(cr, uid, ids): | ||
113 | 97 | already_id = self_obj.search(cr, uid, [('partner_id','=',o.partner_id.id),('id', 'not in', ids),('staus','=','valid')]) | ||
114 | 98 | if already_id: | ||
115 | 99 | old_partner_id = self.browse(cr, uid, already_id[0]) | ||
116 | 100 | if o.partner_id.id == old_partner_id.partner_id.id: | ||
117 | 101 | raise osv.except_osv(_('Error !'), | ||
118 | 102 | _('You can not this partner becasue this partner aleready with valid entry')) | ||
119 | 103 | self.write(cr, uid, [o.id], {'staus': 'valid'}) | ||
120 | 104 | return True | ||
121 | 105 | |||
122 | 106 | supplier_cost_opti_lead_time() | ||
123 | 107 | |||
124 | 108 | class product_seasonal(osv.osv): | 50 | class product_seasonal(osv.osv): |
125 | 109 | _name = 'product.seasonal' | 51 | _name = 'product.seasonal' |
126 | 110 | _columns = { | 52 | _columns = { |
127 | 111 | 53 | ||
128 | === added file 'stock_minimum_calculator/stock_minimum_calculator_demo.xml' | |||
129 | --- stock_minimum_calculator/stock_minimum_calculator_demo.xml 1970-01-01 00:00:00 +0000 | |||
130 | +++ stock_minimum_calculator/stock_minimum_calculator_demo.xml 2010-06-15 07:09:25 +0000 | |||
131 | @@ -0,0 +1,17 @@ | |||
132 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
133 | 2 | <openerp> | ||
134 | 3 | <data noupdate="1"> | ||
135 | 4 | |||
136 | 5 | <record id="product_seasonal_id1" model="product.seasonal"> | ||
137 | 6 | <field name="name">Normal Seasonal</field> | ||
138 | 7 | <field name="code">main</field> | ||
139 | 8 | <field name="seasonal_factor">1.0</field> | ||
140 | 9 | </record> | ||
141 | 10 | <record id="product_seasonal_id2" model="product.seasonal"> | ||
142 | 11 | <field name="name">Christmas Seasonal</field> | ||
143 | 12 | <field name="code">christmas</field> | ||
144 | 13 | <field name="seasonal_factor">1.12</field> | ||
145 | 14 | </record> | ||
146 | 15 | |||
147 | 16 | </data> | ||
148 | 17 | </openerp> | ||
149 | 0 | 18 | ||
150 | === modified file 'stock_minimum_calculator/stock_minimum_calculator_sequence.xml' | |||
151 | --- stock_minimum_calculator/stock_minimum_calculator_sequence.xml 2010-06-11 07:42:16 +0000 | |||
152 | +++ stock_minimum_calculator/stock_minimum_calculator_sequence.xml 2010-06-15 07:09:25 +0000 | |||
153 | @@ -3,12 +3,12 @@ | |||
154 | 3 | <data noupdate="1"> | 3 | <data noupdate="1"> |
155 | 4 | <!-- Sequences for stock.orderpoint.step2 --> | 4 | <!-- Sequences for stock.orderpoint.step2 --> |
156 | 5 | <record id="sequence_stock_op_point" model="ir.sequence.type"> | 5 | <record id="sequence_stock_op_point" model="ir.sequence.type"> |
159 | 6 | <field name="name">Stock orderpoint step2</field> | 6 | <field name="name">Stock orderpoint Calculator</field> |
160 | 7 | <field name="code">stock.orderpoint.step2</field> | 7 | <field name="code">stock.orderpoint.calculator</field> |
161 | 8 | </record> | 8 | </record> |
162 | 9 | <record id="sequence_stock_op" model="ir.sequence"> | 9 | <record id="sequence_stock_op" model="ir.sequence"> |
165 | 10 | <field name="name">Stock orderpoint step2</field> | 10 | <field name="name">stock orderpoint Calculator</field> |
166 | 11 | <field name="code">stock.orderpoint.step2</field> | 11 | <field name="code">stock.orderpoint.calculator</field> |
167 | 12 | <field name="prefix">OP/</field> | 12 | <field name="prefix">OP/</field> |
168 | 13 | <field name="padding">5</field> | 13 | <field name="padding">5</field> |
169 | 14 | <field name="number_increment">1</field> | 14 | <field name="number_increment">1</field> |
170 | 15 | 15 | ||
171 | === modified file 'stock_minimum_calculator/stock_minimum_calculator_view.xml' | |||
172 | --- stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-10 06:28:31 +0000 | |||
173 | +++ stock_minimum_calculator/stock_minimum_calculator_view.xml 2010-06-15 07:09:25 +0000 | |||
174 | @@ -2,7 +2,7 @@ | |||
175 | 2 | <openerp> | 2 | <openerp> |
176 | 3 | <data> | 3 | <data> |
177 | 4 | 4 | ||
179 | 5 | <record id="stock_holding_rate_tree_view" model="ir.ui.view"> | 5 | <record id="stock_holding_rate_tree_view" model="ir.ui.view"> |
180 | 6 | <field name="name">stock.holding.rate.tree</field> | 6 | <field name="name">stock.holding.rate.tree</field> |
181 | 7 | <field name="model">stock.holding.rate</field> | 7 | <field name="model">stock.holding.rate</field> |
182 | 8 | <field name="type">tree</field> | 8 | <field name="type">tree</field> |
183 | @@ -52,69 +52,8 @@ | |||
184 | 52 | <field name="view_type">form</field> | 52 | <field name="view_type">form</field> |
185 | 53 | <field name="view_id" ref="stock_holding_rate_tree_view"/> | 53 | <field name="view_id" ref="stock_holding_rate_tree_view"/> |
186 | 54 | </record> | 54 | </record> |
187 | 55 | |||
188 | 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"/> |
189 | 56 | |||
190 | 57 | <record id="supplier_cost_opti_lead_time_tree_view" model="ir.ui.view"> | ||
191 | 58 | <field name="name">supplier.cost.opti.lead.time.tree</field> | ||
192 | 59 | <field name="model">supplier.cost.opti.lead.time</field> | ||
193 | 60 | <field name="type">tree</field> | ||
194 | 61 | <field name="arch" type="xml"> | ||
195 | 62 | <tree string="Supplier Cost Optimated Lead Times"> | ||
196 | 63 | <field name="supp_cost_id"/> | ||
197 | 64 | <field name="name"/> | ||
198 | 65 | <field name="partner_id"/> | ||
199 | 66 | <field name="date_start"/> | ||
200 | 67 | <field name="yrl_purchase_rev"/> | ||
201 | 68 | <field name="economic_no_order"/> | ||
202 | 69 | <field name="cost_per_del"/> | ||
203 | 70 | <field name="economic_lead_time"/> | ||
204 | 71 | <field name="stock_holding_rate_id"/> | ||
205 | 72 | <field name="staus"/> | ||
206 | 73 | </tree> | ||
207 | 74 | </field> | ||
208 | 75 | </record> | ||
209 | 76 | |||
210 | 77 | <record id="supplier_cost_opti_lead_time_form_view" model="ir.ui.view"> | ||
211 | 78 | <field name="name">supplier.cost.opti.lead.time.form</field> | ||
212 | 79 | <field name="model">supplier.cost.opti.lead.time</field> | ||
213 | 80 | <field name="type">form</field> | ||
214 | 81 | <field name="arch" type="xml"> | ||
215 | 82 | <form string="Supplier Cost Optimated Lead Times"> | ||
216 | 83 | <group colspan="6" col="6"> | ||
217 | 84 | <field name="name"/> | ||
218 | 85 | <field name="supp_cost_id"/> | ||
219 | 86 | <field name="active"/> | ||
220 | 87 | <field name="partner_id"/> | ||
221 | 88 | <field name="date_start"/> | ||
222 | 89 | </group> | ||
223 | 90 | <group colspan="2" col="2"> | ||
224 | 91 | <separator colspan="4" string="Automatic Declaration"/> | ||
225 | 92 | <field name="yrl_purchase_rev"/> | ||
226 | 93 | <field name="cost_per_del"/> | ||
227 | 94 | <field name="stock_holding_rate_id"/> | ||
228 | 95 | </group> | ||
229 | 96 | <group colspan="2" col="2"> | ||
230 | 97 | <separator colspan="4" string="Economic Number of orders"/> | ||
231 | 98 | <field name="economic_no_order"/> | ||
232 | 99 | <field name="economic_lead_time"/> | ||
233 | 100 | <button name="action_compute" string="Calculate Lead Time" type="object"/> | ||
234 | 101 | </group> | ||
235 | 102 | <field name="staus"/> | ||
236 | 103 | <button name="action_cancel" string="Cancel" type="object"/> | ||
237 | 104 | <button name="action_validate" string="Valid" type="object"/> | ||
238 | 105 | </form> | ||
239 | 106 | </field> | ||
240 | 107 | </record> | ||
241 | 108 | <record id="supplier_cost_opti_lead_time_normal_action" model="ir.actions.act_window"> | ||
242 | 109 | <field name="name">Supplier Cost Optimated Lead Times</field> | ||
243 | 110 | <field name="type">ir.actions.act_window</field> | ||
244 | 111 | <field name="res_model">supplier.cost.opti.lead.time</field> | ||
245 | 112 | <field name="view_type">form</field> | ||
246 | 113 | <field name="view_id" ref="supplier_cost_opti_lead_time_tree_view"/> | ||
247 | 114 | </record> | ||
248 | 115 | <menuitem action="supplier_cost_opti_lead_time_normal_action" id="menu_supplier_cost_opti_lead_time" parent="stock.menu_stock_configuration"/> | ||
249 | 116 | |||
250 | 117 | |||
251 | 118 | 57 | ||
252 | 119 | <record id="product_seasonal_tree_view" model="ir.ui.view"> | 58 | <record id="product_seasonal_tree_view" model="ir.ui.view"> |
253 | 120 | <field name="name">product.seasonal.tree</field> | 59 | <field name="name">product.seasonal.tree</field> |
254 | @@ -150,17 +89,6 @@ | |||
255 | 150 | </record> | 89 | </record> |
256 | 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"/> |
257 | 152 | 91 | ||
258 | 153 | <record model="ir.ui.view" id="view_supplier_holding_rate_form1"> | ||
259 | 154 | <field name="name">res.partner.form</field> | ||
260 | 155 | <field name="model">res.partner</field> | ||
261 | 156 | <field name="inherit_id" ref="stock.view_partner_property_form"/> | ||
262 | 157 | <field name="type">form</field> | ||
263 | 158 | <field name="arch" type="xml"> | ||
264 | 159 | <field name="property_stock_supplier" position="after"> | ||
265 | 160 | <field name="stock_holding_rate_id" /> | ||
266 | 161 | </field> | ||
267 | 162 | </field> | ||
268 | 163 | </record> | ||
269 | 164 | <record model="ir.ui.view" id="view_supplier_holding_rate_form"> | 92 | <record model="ir.ui.view" id="view_supplier_holding_rate_form"> |
270 | 165 | <field name="name">product.product.form</field> | 93 | <field name="name">product.product.form</field> |
271 | 166 | <field name="model">product.product</field> | 94 | <field name="model">product.product</field> |
272 | 167 | 95 | ||
273 | === removed file 'stock_minimum_calculator/stock_order_point_calculator.py' | |||
274 | --- stock_minimum_calculator/stock_order_point_calculator.py 2010-06-11 07:42:16 +0000 | |||
275 | +++ stock_minimum_calculator/stock_order_point_calculator.py 1970-01-01 00:00:00 +0000 | |||
276 | @@ -1,217 +0,0 @@ | |||
277 | 1 | # -*- coding: utf-8 -*- | ||
278 | 2 | ############################################################################## | ||
279 | 3 | # | ||
280 | 4 | # OpenERP, Open Source Management Solution | ||
281 | 5 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
282 | 6 | # | ||
283 | 7 | # This program is free software: you can redistribute it and/or modify | ||
284 | 8 | # it under the terms of the GNU Affero General Public License as | ||
285 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
286 | 10 | # License, or (at your option) any later version. | ||
287 | 11 | # | ||
288 | 12 | # This program is distributed in the hope that it will be useful, | ||
289 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
290 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
291 | 15 | # GNU Affero General Public License for more details. | ||
292 | 16 | # | ||
293 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
294 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
295 | 19 | # | ||
296 | 20 | ############################################################################## | ||
297 | 21 | from osv import fields, osv | ||
298 | 22 | import time | ||
299 | 23 | from tools.translate import _ | ||
300 | 24 | |||
301 | 25 | class stock_orderpoint_step1(osv.osv_memory): | ||
302 | 26 | |||
303 | 27 | _name="stock.orderpoint.step1" | ||
304 | 28 | _columns = { | ||
305 | 29 | 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse',required=True), | ||
306 | 30 | 'deactive': fields.boolean('Deactive Existing Rules'), | ||
307 | 31 | 'delactive': fields.boolean('Delete Exiting Rules(for this warehosue)'), | ||
308 | 32 | } | ||
309 | 33 | |||
310 | 34 | def _de_next(self, cr, uid, ids, context=None): | ||
311 | 35 | |||
312 | 36 | mod_obj = self.pool.get('ir.model.data') | ||
313 | 37 | product_obj = self.pool.get('product.product') | ||
314 | 38 | min_rule_obj = self.pool.get('stock.warehouse.orderpoint') | ||
315 | 39 | form = self.read(cr, uid, ids, [])[0] | ||
316 | 40 | |||
317 | 41 | stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',form['warehouse_id'])]) | ||
318 | 42 | |||
319 | 43 | if form['deactive']: | ||
320 | 44 | for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context): | ||
321 | 45 | min_rule_obj.write(cr, uid, [stock_rule_id.id], {'active':False}, context=context) | ||
322 | 46 | |||
323 | 47 | elif form['delactive']: | ||
324 | 48 | for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context): | ||
325 | 49 | min_rule_obj.unlink(cr, uid, [stock_rule_id.id],context=context) | ||
326 | 50 | |||
327 | 51 | |||
328 | 52 | model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_stock_orderpoint_step2')], context=context) | ||
329 | 53 | resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] | ||
330 | 54 | return { | ||
331 | 55 | 'name': _('Stock Orderpoint Step2'), | ||
332 | 56 | 'context': context, | ||
333 | 57 | 'view_type': 'form', | ||
334 | 58 | 'view_mode': 'form', | ||
335 | 59 | 'res_model': 'stock.orderpoint.step2', | ||
336 | 60 | 'views': [(resource_id,'form')], | ||
337 | 61 | 'type': 'ir.actions.act_window', | ||
338 | 62 | 'target': 'new', | ||
339 | 63 | } | ||
340 | 64 | stock_orderpoint_step1() | ||
341 | 65 | |||
342 | 66 | |||
343 | 67 | class stock_orderpoint_step2(osv.osv_memory): | ||
344 | 68 | |||
345 | 69 | _name="stock.orderpoint.step2" | ||
346 | 70 | _columns = { | ||
347 | 71 | 'min_qty_calculation': fields.selection([('optimal_stock_coverage', 'Optimal Stock Coverage'), | ||
348 | 72 | ('normal_stock_coverage', 'Normal Stock Coverage'), | ||
349 | 73 | ], 'Method Calculation Minimum Qty',required=True), | ||
350 | 74 | 'max_qty_calculation': fields.selection([('optimal_stock_coverage', 'Optimal Stock Coverage'), | ||
351 | 75 | ('normal_stock_coverage', 'Normal Stock Coverage'), | ||
352 | 76 | ], 'Method Calculation Maximum Qty',required=True), | ||
353 | 77 | } | ||
354 | 78 | _defaults = { | ||
355 | 79 | 'min_qty_calculation': lambda *a: 'optimal_stock_coverage', | ||
356 | 80 | 'max_qty_calculation': lambda *a: 'optimal_stock_coverage', | ||
357 | 81 | } | ||
358 | 82 | |||
359 | 83 | def _next_calculate(self, cr, uid, ids, context=None): | ||
360 | 84 | |||
361 | 85 | purchase_obj = self.pool.get('purchase.order') | ||
362 | 86 | sale_obj = self.pool.get('sale.order') | ||
363 | 87 | product_obj = self.pool.get('product.product') | ||
364 | 88 | supp_obj = self.pool.get("product.supplierinfo") | ||
365 | 89 | supp_cost_opt_obj = self.pool.get("supplier.cost.opti.lead.time") | ||
366 | 90 | wizard_obj = self.pool.get("stock.orderpoint.step1") | ||
367 | 91 | min_rule_obj = self.pool.get('stock.warehouse.orderpoint') | ||
368 | 92 | order_period_obj = self.pool.get("stock.warehosue.orderpoint.period") | ||
369 | 93 | |||
370 | 94 | form = self.read(cr, uid, ids, [])[0] | ||
371 | 95 | |||
372 | 96 | purchase_ids = purchase_obj.search(cr,uid,[]) | ||
373 | 97 | start_pur_id = min(purchase_ids) | ||
374 | 98 | last_pur_id = max(purchase_ids) | ||
375 | 99 | |||
376 | 100 | ############# Calculation of purchase Quantity upto today | ||
377 | 101 | purchase_qty = 0.0 | ||
378 | 102 | if purchase_ids: | ||
379 | 103 | for pur_id in purchase_ids: | ||
380 | 104 | purchase_data = purchase_obj.browse(cr,uid,pur_id) | ||
381 | 105 | for line in purchase_data.order_line: | ||
382 | 106 | purchase_qty += line.product_qty | ||
383 | 107 | |||
384 | 108 | |||
385 | 109 | ##### Calculation of sale order Quantity of open orders | ||
386 | 110 | sale_qty = 0.0 | ||
387 | 111 | sale_ids = self.pool.get('sale.order').search(cr, uid, [('state','in',['manual','progress'])]) | ||
388 | 112 | if sale_ids: | ||
389 | 113 | for sale_id in sale_ids: | ||
390 | 114 | sale_data = self.pool.get('sale.order').browse(cr,uid,sale_id) | ||
391 | 115 | for line in sale_data.order_line: | ||
392 | 116 | sale_qty += line.product_uom_qty | ||
393 | 117 | |||
394 | 118 | |||
395 | 119 | ##################calculation of date difference between first and last purchase order | ||
396 | 120 | first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order | ||
397 | 121 | last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order | ||
398 | 122 | first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d')) | ||
399 | 123 | last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d')) | ||
400 | 124 | diff_day = (last_date-first_date)/(3600*24) | ||
401 | 125 | |||
402 | 126 | ##### Calculation of purchase lead time | ||
403 | 127 | purchase_lead_time = 0.0 | ||
404 | 128 | company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id | ||
405 | 129 | purchase_lead_time = company.po_lead | ||
406 | 130 | |||
407 | 131 | ##### Calculation of supplier lead time | ||
408 | 132 | product_id = product_obj.browse(cr, uid, context['id'], context) | ||
409 | 133 | supplier_lead_time = 0.0 | ||
410 | 134 | if product_id: | ||
411 | 135 | for supp in product_id.seller_ids: | ||
412 | 136 | sup = supp_obj.browse(cr, uid, supp.id, context) | ||
413 | 137 | supplier_lead_time = sup.delay | ||
414 | 138 | |||
415 | 139 | |||
416 | 140 | ##### Calculation of average_daily_consumption | ||
417 | 141 | average_daily_consumption = 0.0 | ||
418 | 142 | if purchase_ids and diff_day > 0.0: | ||
419 | 143 | average_daily_consumption = (sale_qty + purchase_qty )/diff_day | ||
420 | 144 | else: | ||
421 | 145 | plan_consume = product_id.plan_avg_consume | ||
422 | 146 | average_daily_consumption = plan_consume | ||
423 | 147 | ######### calculation of safety stock | ||
424 | 148 | safety_stock = purchase_qty / len(purchase_ids) | ||
425 | 149 | |||
426 | 150 | ### calculation of Economic lead time (days) | ||
427 | 151 | cost_op_id = supp_cost_opt_obj.search(cr, uid, [('partner_id','=',sup.name.id)]) | ||
428 | 152 | economic_lead_days = 0.0 | ||
429 | 153 | economic_numer_orders = 0.0 | ||
430 | 154 | economic_lead_time = 0.0 | ||
431 | 155 | if cost_op_id: | ||
432 | 156 | cost_op = supp_cost_opt_obj.browse(cr, uid,cost_op_id[0]) | ||
433 | 157 | economic_numer_orders = cost_op.economic_no_order | ||
434 | 158 | economic_lead_time = cost_op.economic_lead_time | ||
435 | 159 | economic_lead_days = economic_lead_time * 30 #Economic leaddays: field economic leadtime from supplier.leadtimes * 30 | ||
436 | 160 | |||
437 | 161 | ### Calculation of the percentage of this days period | ||
438 | 162 | future_seasonal_fac = 0.0 | ||
439 | 163 | periods = self.pool.get('account.period').find(cr, uid) | ||
440 | 164 | for period in periods: | ||
441 | 165 | trend_id = order_period_obj.search(cr, uid, [('period_id','=',period)]) | ||
442 | 166 | if trend_id: | ||
443 | 167 | per = order_period_obj.browse(cr, uid,trend_id[0]).percentage | ||
444 | 168 | future_seasonal_fac = economic_lead_days + purchase_lead_time / per | ||
445 | 169 | |||
446 | 170 | #### Calculation of seasonal Factor | ||
447 | 171 | |||
448 | 172 | #??????seasonal factor = percentage of product.seasonaltrend for future period of follwing date: | ||
449 | 173 | #today + economic lead days + purchase lead time / "percentage of this days period" | ||
450 | 174 | seasonal_fac = 0.0 | ||
451 | 175 | seasonal_fac = product_id.seasonal_id.seasonal_factor | ||
452 | 176 | |||
453 | 177 | |||
454 | 178 | ### Calculation for minimum quantity | ||
455 | 179 | optimal_stock_coverage = 0.0 | ||
456 | 180 | normal_stock_coverage = 0.0 | ||
457 | 181 | if form['min_qty_calculation'] == 'optimal_stock_coverage': | ||
458 | 182 | optimal_stock_coverage = average_daily_consumption * seasonal_fac * (economic_lead_days + purchase_lead_time) / safety_stock | ||
459 | 183 | else: | ||
460 | 184 | normal_stock_coverage = average_daily_consumption * (supplier_lead_time + purchase_lead_time)/safety_stock | ||
461 | 185 | |||
462 | 186 | |||
463 | 187 | ### Calculation for maximum quantity | ||
464 | 188 | optimal_stock_coverage_max = 0.0 | ||
465 | 189 | normal_stock_coverage_max = 0.0 | ||
466 | 190 | if form['max_qty_calculation'] == 'optimal_stock_coverage': | ||
467 | 191 | optimal_stock_coverage_max = (average_daily_consumption * seasonal_fac * (economic_lead_days + purchase_lead_time)) | ||
468 | 192 | else: | ||
469 | 193 | normal_stock_coverage_max = average_daily_consumption * (supplier_lead_time + purchase_lead_time) | ||
470 | 194 | |||
471 | 195 | ids = wizard_obj.search(cr, uid, []) | ||
472 | 196 | |||
473 | 197 | wizz_id = wizard_obj.browse(cr, uid, ids[0]) | ||
474 | 198 | max1 = 'max' | ||
475 | 199 | name = self.pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.step2') | ||
476 | 200 | |||
477 | 201 | self.pool.get('stock.warehouse.orderpoint').create(cr, uid, { | ||
478 | 202 | 'name': name, | ||
479 | 203 | 'active': True, | ||
480 | 204 | 'warehouse_id': wizz_id.warehouse_id.id, | ||
481 | 205 | 'location_id': product_id.property_stock_inventory.id, | ||
482 | 206 | 'product_id': context['id'], | ||
483 | 207 | 'product_min_qty': optimal_stock_coverage or normal_stock_coverage, | ||
484 | 208 | 'product_max_qty': optimal_stock_coverage_max or normal_stock_coverage_max, | ||
485 | 209 | 'qty_multiple':1, | ||
486 | 210 | 'product_uom':product_id.uom_id.id, | ||
487 | 211 | 'logic':'max' | ||
488 | 212 | } ) | ||
489 | 213 | return {} | ||
490 | 214 | |||
491 | 215 | stock_orderpoint_step2() | ||
492 | 216 | |||
493 | 217 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
494 | 218 | \ No newline at end of file | 0 | \ No newline at end of file |
495 | 219 | 1 | ||
496 | === removed file 'stock_minimum_calculator/stock_order_point_calculator_view.xml' | |||
497 | --- stock_minimum_calculator/stock_order_point_calculator_view.xml 2010-06-09 14:36:04 +0000 | |||
498 | +++ stock_minimum_calculator/stock_order_point_calculator_view.xml 1970-01-01 00:00:00 +0000 | |||
499 | @@ -1,50 +0,0 @@ | |||
500 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
501 | 2 | <openerp> | ||
502 | 3 | <data> | ||
503 | 4 | <record id="view_account_invoice_pay" model="ir.ui.view"> | ||
504 | 5 | <field name="name">stock.orderpoint.step1.form</field> | ||
505 | 6 | <field name="model">stock.orderpoint.step1</field> | ||
506 | 7 | <field name="type">form</field> | ||
507 | 8 | <field name="arch" type="xml"> | ||
508 | 9 | <form string="Wizard Order Point Calculator Step1 - Choose Warehouse and Updating Settings"> | ||
509 | 10 | <group colspan="4" > | ||
510 | 11 | <field name="warehouse_id"/> | ||
511 | 12 | <field name="deactive"/> | ||
512 | 13 | <field name="delactive"/> | ||
513 | 14 | </group> | ||
514 | 15 | <group colspan="4" col="6"> | ||
515 | 16 | <label string ="" colspan="2"/> | ||
516 | 17 | <button icon="gtk-cancel" special="cancel" string="Cancel"/> | ||
517 | 18 | <button icon="gtk-execute" string="Next Step" name="_de_next" type="object"/> | ||
518 | 19 | </group> | ||
519 | 20 | </form> | ||
520 | 21 | </field> | ||
521 | 22 | </record> | ||
522 | 23 | |||
523 | 24 | <act_window name="Orderpoint Calculator" | ||
524 | 25 | res_model="stock.orderpoint.step1" | ||
525 | 26 | src_model="product.product" | ||
526 | 27 | view_mode="form" | ||
527 | 28 | target="new" | ||
528 | 29 | context="{'id': active_id}" | ||
529 | 30 | id="action_view_stock_orderpoint_step1"/> | ||
530 | 31 | |||
531 | 32 | <record id="view_stock_orderpoint_step2" model="ir.ui.view"> | ||
532 | 33 | <field name="name">stock.orderpoint.step2.form</field> | ||
533 | 34 | <field name="model">stock.orderpoint.step2</field> | ||
534 | 35 | <field name="type">form</field> | ||
535 | 36 | <field name="arch" type="xml"> | ||
536 | 37 | <form string="Wizard Order Point Calculator Step2 - Choose Method"> | ||
537 | 38 | <field name="min_qty_calculation"/> | ||
538 | 39 | <field name="max_qty_calculation" /> | ||
539 | 40 | <group colspan="4" col="6"> | ||
540 | 41 | <button icon="gtk-cancel" special="cancel" string="Cancel"/> | ||
541 | 42 | <button icon="gtk-execute" string="Next Step" name="_next_calculate" type="object"/> | ||
542 | 43 | </group> | ||
543 | 44 | </form> | ||
544 | 45 | </field> | ||
545 | 46 | </record> | ||
546 | 47 | |||
547 | 48 | |||
548 | 49 | </data> | ||
549 | 50 | </openerp> | ||
550 | 51 | \ No newline at end of file | 0 | \ No newline at end of file |
551 | 52 | 1 | ||
552 | === added file 'stock_minimum_calculator/supplier_cost_optimated_leadtimes.py' | |||
553 | --- stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 1970-01-01 00:00:00 +0000 | |||
554 | +++ stock_minimum_calculator/supplier_cost_optimated_leadtimes.py 2010-06-15 07:09:25 +0000 | |||
555 | @@ -0,0 +1,89 @@ | |||
556 | 1 | # -*- coding: utf-8 -*- | ||
557 | 2 | ############################################################################## | ||
558 | 3 | # | ||
559 | 4 | # OpenERP, Open Source Management Solution | ||
560 | 5 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
561 | 6 | # | ||
562 | 7 | # This program is free software: you can redistribute it and/or modify | ||
563 | 8 | # it under the terms of the GNU Affero General Public License as | ||
564 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
565 | 10 | # License, or (at your option) any later version. | ||
566 | 11 | # | ||
567 | 12 | # This program is distributed in the hope that it will be useful, | ||
568 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
569 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
570 | 15 | # GNU Affero General Public License for more details. | ||
571 | 16 | # | ||
572 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
573 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
574 | 19 | # | ||
575 | 20 | ############################################################################## | ||
576 | 21 | from osv import fields, osv | ||
577 | 22 | import time | ||
578 | 23 | from tools.translate import _ | ||
579 | 24 | from mx import DateTime | ||
580 | 25 | |||
581 | 26 | class supplier_cost_optimated_leadtimes(osv.osv_memory): | ||
582 | 27 | |||
583 | 28 | _name="supplier.cost.optimated.leadtimes" | ||
584 | 29 | _columns = { | ||
585 | 30 | 'partner_id': fields.many2one('res.partner', 'Suplier'), | ||
586 | 31 | 'account_purchase_rev': fields.many2one('account.analytic.account', 'Acc. Purchase Revenues', required=True), | ||
587 | 32 | 'account_cost_pre_del': fields.many2one('account.analytic.account', 'Acc. Delivery Cost'), | ||
588 | 33 | 'date_start': fields.date('From Period', required=True), | ||
589 | 34 | 'date_stop': fields.date('To Period', required=True), | ||
590 | 35 | 'purchase_rev':fields.float("Purchase Revenue",readonly=True,), | ||
591 | 36 | 'economic_no_order':fields.float("Economic Number of orders",readonly=True), | ||
592 | 37 | 'cost_per_del':fields.float("Cost Per Delivery",readonly=True), | ||
593 | 38 | 'economic_lead_time':fields.float("Economic Lead Time", readonly=True), | ||
594 | 39 | 'stock_holding_rate_id':fields.many2one("stock.holding.rate",'Holding Rate',required=True), | ||
595 | 40 | } | ||
596 | 41 | |||
597 | 42 | def _compute(self, cr, uid, ids, context=None): | ||
598 | 43 | |||
599 | 44 | form = self.read(cr, uid, ids, [], context=context)[0] | ||
600 | 45 | |||
601 | 46 | analytic_account_obj = self.pool.get('account.analytic.account') | ||
602 | 47 | analytic_line_obj = self.pool.get('account.analytic.line') | ||
603 | 48 | stock_hold_rate_obj = self.pool.get("stock.holding.rate") | ||
604 | 49 | |||
605 | 50 | date_start = form['date_start'] | ||
606 | 51 | date_stop = form['date_stop'] | ||
607 | 52 | |||
608 | 53 | pur_balance = 0.0 | ||
609 | 54 | pur_analytic_id = form['account_purchase_rev'] | ||
610 | 55 | |||
611 | 56 | pur_analytic_line_id = analytic_line_obj.search(cr,uid,[('account_id','=',pur_analytic_id), ('date','>=',date_start),('date','<=',date_stop)]) | ||
612 | 57 | |||
613 | 58 | if pur_analytic_line_id: | ||
614 | 59 | for pur_analytic_id in pur_analytic_line_id: | ||
615 | 60 | pur_analytic_amount = analytic_line_obj.browse(cr, uid, pur_analytic_id, context) | ||
616 | 61 | balance = pur_analytic_amount.amount | ||
617 | 62 | pur_balance += balance | ||
618 | 63 | |||
619 | 64 | |||
620 | 65 | cost_del_analytic_id = form['account_cost_pre_del'] | ||
621 | 66 | cost_balance = 0.0 | ||
622 | 67 | |||
623 | 68 | cost_del_analytic_line_id = analytic_line_obj.search(cr,uid,[('account_id','=',cost_del_analytic_id), ('date','>=',date_start),('date','<=',date_stop)]) | ||
624 | 69 | |||
625 | 70 | if cost_del_analytic_line_id: | ||
626 | 71 | for cost_analytic_id in cost_del_analytic_line_id: | ||
627 | 72 | cost_analytic_amount = analytic_line_obj.browse(cr, uid, cost_analytic_id, context) | ||
628 | 73 | balance = cost_analytic_amount.amount | ||
629 | 74 | cost_balance += balance | ||
630 | 75 | |||
631 | 76 | stock_hold_id = stock_hold_rate_obj.browse(cr, uid, form['stock_holding_rate_id']) | ||
632 | 77 | stock_hold_rate = stock_hold_id.stock_hold_rate | ||
633 | 78 | |||
634 | 79 | if pur_balance and cost_balance: | ||
635 | 80 | for id in ids: | ||
636 | 81 | economic_numer_orders = (pur_balance * stock_hold_rate)/ (2 * cost_balance) | ||
637 | 82 | economic_lead_time = 360 / economic_numer_orders | ||
638 | 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}) | ||
639 | 84 | |||
640 | 85 | return True | ||
641 | 86 | |||
642 | 87 | supplier_cost_optimated_leadtimes() | ||
643 | 88 | |||
644 | 89 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
645 | 0 | \ No newline at end of file | 90 | \ No newline at end of file |
646 | 1 | 91 | ||
647 | === added file 'stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml' | |||
648 | --- stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml 1970-01-01 00:00:00 +0000 | |||
649 | +++ stock_minimum_calculator/supplier_cost_optimated_leadtimes_view.xml 2010-06-15 07:09:25 +0000 | |||
650 | @@ -0,0 +1,46 @@ | |||
651 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
652 | 2 | <openerp> | ||
653 | 3 | <data> | ||
654 | 4 | <record id="view_supplier_cost_optimated_leadtimes" model="ir.ui.view"> | ||
655 | 5 | <field name="name">supplier.cost.optimated.leadtimes.form</field> | ||
656 | 6 | <field name="model">supplier.cost.optimated.leadtimes</field> | ||
657 | 7 | <field name="type">form</field> | ||
658 | 8 | <field name="arch" type="xml"> | ||
659 | 9 | <form string="Wizard to Calculate Cost Optimized Lead Times"> | ||
660 | 10 | <group colspan="4" > | ||
661 | 11 | <field name="partner_id"/> | ||
662 | 12 | <field name="stock_holding_rate_id"/> | ||
663 | 13 | <field name="date_start"/> | ||
664 | 14 | <field name="account_purchase_rev"/> | ||
665 | 15 | <field name="date_stop"/> | ||
666 | 16 | <field name="account_cost_pre_del"/> | ||
667 | 17 | <separator colspan="4" string="Result of Calculation"/> | ||
668 | 18 | <field name="purchase_rev"/> | ||
669 | 19 | <field name="economic_no_order"/> | ||
670 | 20 | <field name="cost_per_del"/> | ||
671 | 21 | <field name="economic_lead_time"/> | ||
672 | 22 | </group> | ||
673 | 23 | |||
674 | 24 | <group colspan="4" col="4"> | ||
675 | 25 | <button icon="gtk-cancel" special="cancel" string="Cancel"/> | ||
676 | 26 | <button icon="gtk-execute" string="Calculate Lead Time" name="_compute" type="object"/> | ||
677 | 27 | </group> | ||
678 | 28 | </form> | ||
679 | 29 | </field> | ||
680 | 30 | </record> | ||
681 | 31 | |||
682 | 32 | <record id="action_supplier_cost_optimated_leadtimes" model="ir.actions.act_window"> | ||
683 | 33 | <field name="name">Supplier Cost Optimated Leadtimes</field> | ||
684 | 34 | <field name="type">ir.actions.act_window</field> | ||
685 | 35 | <field name="res_model">supplier.cost.optimated.leadtimes</field> | ||
686 | 36 | <field name="view_type">form</field> | ||
687 | 37 | <field name="view_mode">form</field> | ||
688 | 38 | <field name="view_id" ref="view_supplier_cost_optimated_leadtimes"/> | ||
689 | 39 | <field name="target">new</field> | ||
690 | 40 | </record> | ||
691 | 41 | <menuitem action="action_supplier_cost_optimated_leadtimes" | ||
692 | 42 | id="menu_action_supplier_cost_optimated_leadtimesy" | ||
693 | 43 | parent="stock.next_id_61"/> | ||
694 | 44 | |||
695 | 45 | </data> | ||
696 | 46 | </openerp> | ||
697 | 0 | \ No newline at end of file | 47 | \ No newline at end of file |
698 | 1 | 48 | ||
699 | === modified file 'stock_minimum_calculator/wizard/__init__.py' | |||
700 | --- stock_minimum_calculator/wizard/__init__.py 2010-06-09 14:36:04 +0000 | |||
701 | +++ stock_minimum_calculator/wizard/__init__.py 2010-06-15 07:09:25 +0000 | |||
702 | @@ -21,6 +21,7 @@ | |||
703 | 21 | ############################################################################## | 21 | ############################################################################## |
704 | 22 | 22 | ||
705 | 23 | import seasonal_trend_set | 23 | import seasonal_trend_set |
706 | 24 | import stock_order_point_calculator | ||
707 | 24 | 25 | ||
708 | 25 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | 26 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
709 | 26 | 27 | ||
710 | 27 | 28 | ||
711 | === removed file 'stock_minimum_calculator/wizard/seasonal_trend_set_view.xml' | |||
712 | --- stock_minimum_calculator/wizard/seasonal_trend_set_view.xml 2010-06-09 14:36:04 +0000 | |||
713 | +++ stock_minimum_calculator/wizard/seasonal_trend_set_view.xml 1970-01-01 00:00:00 +0000 | |||
714 | @@ -1,32 +0,0 @@ | |||
715 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
716 | 2 | <openerp> | ||
717 | 3 | <data> | ||
718 | 4 | |||
719 | 5 | <record id="view_stock_order_rule" model="ir.ui.view"> | ||
720 | 6 | <field name="name">product.seasonal.trend.form</field> | ||
721 | 7 | <field name="model">product.seasonal.trend</field> | ||
722 | 8 | <field name="type">form</field> | ||
723 | 9 | <field name="arch" type="xml"> | ||
724 | 10 | <form string="Set Seasonal Trend"> | ||
725 | 11 | <field name="trend_seasonal_id" /> | ||
726 | 12 | <field name="active" /> | ||
727 | 13 | <group colspan="4" col="6"> | ||
728 | 14 | <button icon="gtk-cancel" special="cancel" string="Cancel"/> | ||
729 | 15 | <button icon="gtk-execute" string="OK" name="_set_seasonal" type="object"/> | ||
730 | 16 | </group> | ||
731 | 17 | </form> | ||
732 | 18 | </field> | ||
733 | 19 | </record> | ||
734 | 20 | |||
735 | 21 | <act_window | ||
736 | 22 | res_model = "product.seasonal.trend" | ||
737 | 23 | src_model = "product.product" | ||
738 | 24 | view_type = "form" | ||
739 | 25 | view_mode = "form" | ||
740 | 26 | name= "Set Seasonal Trend" | ||
741 | 27 | target="new" | ||
742 | 28 | context="{'id': active_id}" | ||
743 | 29 | id="action_product_seasonal_trend"/> | ||
744 | 30 | |||
745 | 31 | </data> | ||
746 | 32 | </openerp> | ||
747 | 33 | \ No newline at end of file | 0 | \ No newline at end of file |
748 | 34 | 1 | ||
749 | === added file 'stock_minimum_calculator/wizard/stock_order_point_calculator.py' | |||
750 | --- stock_minimum_calculator/wizard/stock_order_point_calculator.py 1970-01-01 00:00:00 +0000 | |||
751 | +++ stock_minimum_calculator/wizard/stock_order_point_calculator.py 2010-06-15 07:09:25 +0000 | |||
752 | @@ -0,0 +1,241 @@ | |||
753 | 1 | # -*- coding: utf-8 -*- | ||
754 | 2 | ############################################################################## | ||
755 | 3 | # | ||
756 | 4 | # OpenERP, Open Source Management Solution | ||
757 | 5 | # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). | ||
758 | 6 | # | ||
759 | 7 | # This program is free software: you can redistribute it and/or modify | ||
760 | 8 | # it under the terms of the GNU Affero General Public License as | ||
761 | 9 | # published by the Free Software Foundation, either version 3 of the | ||
762 | 10 | # License, or (at your option) any later version. | ||
763 | 11 | # | ||
764 | 12 | # This program is distributed in the hope that it will be useful, | ||
765 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
766 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
767 | 15 | # GNU Affero General Public License for more details. | ||
768 | 16 | # | ||
769 | 17 | # You should have received a copy of the GNU Affero General Public License | ||
770 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
771 | 19 | # | ||
772 | 20 | ############################################################################## | ||
773 | 21 | |||
774 | 22 | import wizard | ||
775 | 23 | import pooler | ||
776 | 24 | import time | ||
777 | 25 | from tools.translate import _ | ||
778 | 26 | import mx.DateTime | ||
779 | 27 | from mx.DateTime import RelativeDateTime, now, DateTime, localtime | ||
780 | 28 | |||
781 | 29 | orderpoint_calculator_form = """<?xml version="1.0"?> | ||
782 | 30 | <form string="Order Point Calculator "> | ||
783 | 31 | <field name="warehouse_id"/> | ||
784 | 32 | <field name="location_id"/> | ||
785 | 33 | <field name="seasonal_id"/> | ||
786 | 34 | <field name="delactive"/> | ||
787 | 35 | <field name="method_qty_calculation" colspan="4"/> | ||
788 | 36 | <group attrs="{'invisible':[('method_qty_calculation','=','his_cons_without_product')]}" colspan="4"> | ||
789 | 37 | <separator string="Configuration of Base Consumptions Periods" colspan="4"/> | ||
790 | 38 | <field name="date_start"/> | ||
791 | 39 | <field name="date_stop"/> | ||
792 | 40 | </group> | ||
793 | 41 | </form>""" | ||
794 | 42 | |||
795 | 43 | orderpoint_calculator_fields = { | ||
796 | 44 | 'warehouse_id': { | ||
797 | 45 | 'string': 'Warehouse', | ||
798 | 46 | 'type': 'many2one', | ||
799 | 47 | 'relation': 'stock.warehouse', | ||
800 | 48 | 'required': True | ||
801 | 49 | }, | ||
802 | 50 | |||
803 | 51 | 'delactive': { | ||
804 | 52 | 'string':'Delete Exiting Rules(for this warehosue)', | ||
805 | 53 | 'type':'boolean' | ||
806 | 54 | }, | ||
807 | 55 | |||
808 | 56 | 'location_id': { | ||
809 | 57 | 'string': 'Location', | ||
810 | 58 | 'type': 'many2one', | ||
811 | 59 | 'relation': 'stock.location', | ||
812 | 60 | 'required': True | ||
813 | 61 | }, | ||
814 | 62 | |||
815 | 63 | 'seasonal_id': { | ||
816 | 64 | 'string': 'Season of Consumption', | ||
817 | 65 | 'type': 'many2one', | ||
818 | 66 | 'relation': 'product.seasonal', | ||
819 | 67 | 'required': True | ||
820 | 68 | }, | ||
821 | 69 | |||
822 | 70 | 'date_start': { | ||
823 | 71 | 'string':'From Date', | ||
824 | 72 | 'type':'date' | ||
825 | 73 | }, | ||
826 | 74 | |||
827 | 75 | 'date_stop': { | ||
828 | 76 | 'string':'To Date', | ||
829 | 77 | 'type':'date', | ||
830 | 78 | 'default': lambda *a: time.strftime('%Y-%m-%d') | ||
831 | 79 | }, | ||
832 | 80 | |||
833 | 81 | 'method_qty_calculation':{ | ||
834 | 82 | 'string':"Method Calculation", | ||
835 | 83 | 'type':'selection', | ||
836 | 84 | 'selection':[('his_cons_with_product', 'Calculate with historical consumptions of products'), | ||
837 | 85 | ('his_cons_without_product', 'Calculate with Out historical consumptions of product'), | ||
838 | 86 | ('hist_cons_and_open_sale', 'Calculate with historical consumptions of product and Open sales orders'), | ||
839 | 87 | ],'required': True, | ||
840 | 88 | 'default': lambda *a:'his_cons_with_product' | ||
841 | 89 | }, | ||
842 | 90 | } | ||
843 | 91 | |||
844 | 92 | def _get_default(obj, cr, uid, data, context=None): | ||
845 | 93 | pool = pooler.get_pool(cr.dbname) | ||
846 | 94 | |||
847 | 95 | warehouse_id = pool.get('stock.warehouse').search(cr, uid, [])[0] | ||
848 | 96 | location_id = pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0] | ||
849 | 97 | |||
850 | 98 | date = now().strftime('%Y-%m-%d') | ||
851 | 99 | date = mx.DateTime.strptime(date, '%Y-%m-%d') - RelativeDateTime(months=3) | ||
852 | 100 | date = date.strftime('%Y-%m-%d') | ||
853 | 101 | |||
854 | 102 | return {'warehouse_id': warehouse_id, 'location_id':location_id,'date_start':date} | ||
855 | 103 | |||
856 | 104 | def _do_calculate(self, cr, uid, data, context): | ||
857 | 105 | |||
858 | 106 | pool = pooler.get_pool(cr.dbname) | ||
859 | 107 | |||
860 | 108 | purchase_obj = pool.get('purchase.order') | ||
861 | 109 | sale_obj = pool.get('sale.order') | ||
862 | 110 | product_obj = pool.get('product.product') | ||
863 | 111 | supp_obj = pool.get('product.supplierinfo') | ||
864 | 112 | supp_cost_opt_obj = pool.get('supplier.cost.opti.lead.time') | ||
865 | 113 | min_rule_obj = pool.get('stock.warehouse.orderpoint') | ||
866 | 114 | |||
867 | 115 | stock_rule_ids = min_rule_obj.search(cr,uid,[('warehouse_id','=',data['form']['warehouse_id'])]) | ||
868 | 116 | if data['form']['delactive']: | ||
869 | 117 | for stock_rule_id in min_rule_obj.browse(cr, uid, stock_rule_ids, context=context): | ||
870 | 118 | min_rule_obj.unlink(cr, uid, [stock_rule_id.id],context=context) | ||
871 | 119 | |||
872 | 120 | ##### Calculation of purchase lead time | ||
873 | 121 | purchase_lead_time = 0.0 | ||
874 | 122 | company = pool.get('res.users').browse(cr, uid, uid, context).company_id | ||
875 | 123 | purchase_lead_time = company.po_lead | ||
876 | 124 | |||
877 | 125 | ##### Calculation of supplier lead time | ||
878 | 126 | |||
879 | 127 | for id in data['ids']: | ||
880 | 128 | product_id = product_obj.browse(cr, uid, id, context) | ||
881 | 129 | supplier_lead_time = 0.0 | ||
882 | 130 | if product_id: | ||
883 | 131 | for supp in product_id.seller_ids: | ||
884 | 132 | sup = supp_obj.browse(cr, uid, supp.id, context) | ||
885 | 133 | supplier_lead_time = sup.delay | ||
886 | 134 | |||
887 | 135 | ###### Calculation of average_daily_consumption | ||
888 | 136 | date_start = data['form']['date_start'] | ||
889 | 137 | date_stop = data['form']['date_stop'] | ||
890 | 138 | average_daily_consumption = 0.0 | ||
891 | 139 | consum_qty = 0.0 | ||
892 | 140 | sale_ids = sale_obj.search(cr,uid,[('date_order','>=',date_start),('date_order','<=',date_stop)]) | ||
893 | 141 | if sale_ids: | ||
894 | 142 | for sid in sale_ids: | ||
895 | 143 | sale_data = sale_obj.browse(cr,uid,sid) | ||
896 | 144 | for line in sale_data.order_line: | ||
897 | 145 | consum_qty += line.product_uom_qty | ||
898 | 146 | |||
899 | 147 | ##################calculation of date difference between first and last sale order | ||
900 | 148 | sale_ids = sale_obj.search(cr,uid,[]) | ||
901 | 149 | if sale_ids: | ||
902 | 150 | start_sale_id = min(sale_ids) | ||
903 | 151 | last_sale_id = max(sale_ids) | ||
904 | 152 | first_sale_date = sale_obj.browse(cr,uid,start_sale_id).date_order | ||
905 | 153 | last_sale_date = sale_obj.browse(cr,uid,last_sale_id).date_order | ||
906 | 154 | first_date = time.mktime(time.strptime(first_sale_date,'%Y-%m-%d')) | ||
907 | 155 | last_date = time.mktime(time.strptime(last_sale_date,'%Y-%m-%d')) | ||
908 | 156 | diff_day = (last_date-first_date)/(3600*24) | ||
909 | 157 | if diff_day > 0: | ||
910 | 158 | average_daily_consumption = consum_qty / diff_day | ||
911 | 159 | |||
912 | 160 | ###### Calculation of plan_average_daily_consumption | ||
913 | 161 | plan_average_daily_consumption = 0.0 | ||
914 | 162 | if product_id.plan_avg_consume: | ||
915 | 163 | plan_average_daily_consumption = product_id.plan_avg_consume | ||
916 | 164 | |||
917 | 165 | ########## calculation historical consumption of products and open sales orders“ | ||
918 | 166 | ### total sale qty with open state | ||
919 | 167 | |||
920 | 168 | sale_qty = 0.0 | ||
921 | 169 | sale_ids = sale_obj.search(cr, uid, [('state','in',['manual','progress'])]) | ||
922 | 170 | if sale_ids: | ||
923 | 171 | for sale_id in sale_ids: | ||
924 | 172 | sale_data = sale_obj.browse(cr,uid,sale_id) | ||
925 | 173 | for line in sale_data.order_line: | ||
926 | 174 | sale_qty += line.product_uom_qty | ||
927 | 175 | |||
928 | 176 | ################### | ||
929 | 177 | purchase_ids = purchase_obj.search(cr,uid,[]) | ||
930 | 178 | if purchase_ids: | ||
931 | 179 | start_pur_id = min(purchase_ids) | ||
932 | 180 | last_pur_id = max(purchase_ids) | ||
933 | 181 | |||
934 | 182 | ##################calculation of date difference between first and last purchase order | ||
935 | 183 | first_purchase_date = purchase_obj.browse(cr,uid,start_pur_id).date_order | ||
936 | 184 | last_purchase_date = purchase_obj.browse(cr,uid,last_pur_id).date_order | ||
937 | 185 | first_date = time.mktime(time.strptime(first_purchase_date,'%Y-%m-%d')) | ||
938 | 186 | last_date = time.mktime(time.strptime(last_purchase_date,'%Y-%m-%d')) | ||
939 | 187 | pur_diff_day = (last_date-first_date)/(3600*24) | ||
940 | 188 | |||
941 | 189 | product_max_qty = 0.0 | ||
942 | 190 | product_min_qty = 0.0 | ||
943 | 191 | |||
944 | 192 | if data['form']['method_qty_calculation'] == 'his_cons_with_product': | ||
945 | 193 | product_min_qty = average_daily_consumption * (supplier_lead_time + purchase_lead_time) | ||
946 | 194 | product_max_qty = 2 * product_min_qty | ||
947 | 195 | |||
948 | 196 | elif data['form']['method_qty_calculation'] == 'his_cons_without_product': | ||
949 | 197 | product_min_qty = plan_average_daily_consumption * (supplier_lead_time + purchase_lead_time) | ||
950 | 198 | product_max_qty = 2 * product_min_qty | ||
951 | 199 | |||
952 | 200 | else: | ||
953 | 201 | product_min_qty = (average_daily_consumption + sale_qty) / pur_diff_day * (supplier_lead_time + purchase_lead_time) | ||
954 | 202 | product_max_qty = 2 * product_min_qty | ||
955 | 203 | |||
956 | 204 | max1 = 'max' | ||
957 | 205 | name = pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint.calculator') | ||
958 | 206 | pool.get('stock.warehouse.orderpoint').create(cr, uid, { | ||
959 | 207 | 'name': name, | ||
960 | 208 | 'active': True, | ||
961 | 209 | 'warehouse_id': data['form']['warehouse_id'], | ||
962 | 210 | 'location_id': product_id.property_stock_inventory.id, | ||
963 | 211 | 'product_id': id, | ||
964 | 212 | 'product_min_qty': product_min_qty, | ||
965 | 213 | 'product_max_qty': product_max_qty, | ||
966 | 214 | 'qty_multiple':1, | ||
967 | 215 | 'product_uom':product_id.uom_id.id, | ||
968 | 216 | 'logic':'max' | ||
969 | 217 | } ) | ||
970 | 218 | |||
971 | 219 | return {} | ||
972 | 220 | |||
973 | 221 | class orderpoint_calculator(wizard.interface): | ||
974 | 222 | states = { | ||
975 | 223 | 'init' : { | ||
976 | 224 | 'actions' : [_get_default], | ||
977 | 225 | 'result' : {'type' : 'form', | ||
978 | 226 | 'arch' : orderpoint_calculator_form, | ||
979 | 227 | 'fields' : orderpoint_calculator_fields, | ||
980 | 228 | 'state' : [('end', 'Cancel'),('calculation', 'Calculation') ]} | ||
981 | 229 | }, | ||
982 | 230 | 'calculation' : { | ||
983 | 231 | 'actions' : [], | ||
984 | 232 | 'result' : {'type' : 'action', | ||
985 | 233 | 'action' : _do_calculate, | ||
986 | 234 | 'state' : 'end'} | ||
987 | 235 | } | ||
988 | 236 | } | ||
989 | 237 | orderpoint_calculator("orderpoint.calculator") | ||
990 | 238 | |||
991 | 239 | |||
992 | 240 | |||
993 | 241 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: | ||
994 | 0 | \ No newline at end of file | 242 | \ No newline at end of file |