Merge lp:~vauxoo/addons-vauxoo/7.0-stock_property_account_product_dev_jorge into lp:addons-vauxoo/7.0

Status: Needs review
Proposed branch: lp:~vauxoo/addons-vauxoo/7.0-stock_property_account_product_dev_jorge
Merge into: lp:addons-vauxoo/7.0
Diff against target: 400 lines (+373/-0)
5 files modified
stock_valuation_account_product/__init__.py (+23/-0)
stock_valuation_account_product/__openerp__.py (+51/-0)
stock_valuation_account_product/model/__init__.py (+23/-0)
stock_valuation_account_product/model/product_product.py (+256/-0)
stock_valuation_account_product/view/product_product_stock_valuation_account.xml (+20/-0)
To merge this branch: bzr merge lp:~vauxoo/addons-vauxoo/7.0-stock_property_account_product_dev_jorge
Reviewer Review Type Date Requested Status
Moisés López - http://www.vauxoo.com Needs Fixing
Jorge Angel Naranjo Rogel - http://www.vauxoo.com Needs Resubmitting
Jose Antonio Morales Ponce(vauxoo) - - http://www.vauxoo.com Needs Fixing
Rodolfo Lopez Pending
Review via email: mp+185370@code.launchpad.net

Description of the change

Se crea modulo para agregar el campo property de valoración inventario en el producto. Ademas se modifica la función que genera la poliza de valoración de inventario, que tome como prioridad la cuenta de valoración de inventario del producto y después la de la categoría en caso de que el producto no tenga.

To post a comment you must log in.
Revision history for this message
Jose Antonio Morales Ponce(vauxoo) - - http://www.vauxoo.com (josemoralesp) wrote :

El modulo ya tiene traduccion?

review: Needs Fixing
Revision history for this message
Jorge Angel Naranjo Rogel - http://www.vauxoo.com (jorge-nr) wrote :

Si el property ya tiene traducción por eso no agrege esa parte.

review: Needs Resubmitting
Revision history for this message
Moisés López - http://www.vauxoo.com (moylop260) wrote :

@Jorge,
En lo personal no me gusta nada que sea "Method overriding"
Sin embargo, donde no hay otra opción, pues se hace.
Aunque también tenemos la via del "parche", que tampoco es la mejor opción.
O un branch paralelo al nativo, para agregar esta funcionalidad, y que se haga el merge en nuestros branches, e incluso lo proponemos para que OpenERP lo considere dentro de sus cambios.

Otra opción, es hacer un análisis de estas funciones para separar la preparación de los diccionarios (como hace stock.py), para que se puedan heredar fácilmente.

Otra opción (que en lo personal, no me gusta tampoco), para marearte más, es como lo hace el módulo de anglosaxon, que modifica la póliza una vez creada.

En resumen, vamos a tomar el siguiente camino:
-Hacer un branch clone de openobject-addons para agregar la parte que necesitamos.
-Reportar un bug (tipo wishlist) con el tema de que no están dejando heredable esta parte.

review: Needs Fixing

Unmerged revisions

802. By Jorge Angel Naranjo Rogel - http://www.vauxoo.com

[IMP][stock_valuation_account_product] Depends account_anglo_saxon

801. By Jorge Angel Naranjo Rogel - http://www.vauxoo.com

[IMP][stock_valuation_account_product] Delete function load_valuation_items and prints

800. By Jorge Angel Naranjo Rogel - http://www.vauxoo.com

[ADD][stock_valuation_account_product] This module added in form view of product in the seccion Accounting the field Stock Valuation Account

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'stock_valuation_account_product'
2=== added file 'stock_valuation_account_product/__init__.py'
3--- stock_valuation_account_product/__init__.py 1970-01-01 00:00:00 +0000
4+++ stock_valuation_account_product/__init__.py 2013-09-12 21:23:37 +0000
5@@ -0,0 +1,23 @@
6+#!/usr/bin/python
7+# -*- encoding: utf-8 -*-
8+#
9+# Module Writen to OpenERP, Open Source Management Solution
10+# Copyright (C) Vauxoo (<http://vauxoo.com>).
11+# All Rights Reserved
12+#
13+# Coded by: Jorge Angel Naranjo Rogel (jorge_nr@vauxoo.com)
14+#
15+# This program is free software: you can redistribute it and/or modify
16+# it under the terms of the GNU Affero General Public License as published by
17+# the Free Software Foundation, either version 3 of the License, or
18+# (at your option) any later version.
19+#
20+# This program is distributed in the hope that it will be useful,
21+# but WITHOUT ANY WARRANTY; without even the implied warranty of
22+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23+# GNU Affero General Public License for more details.
24+#
25+# You should have received a copy of the GNU Affero General Public License
26+# along with this program. If not, see <http://www.gnu.org/licenses/>.
27+#
28+import model
29
30=== added file 'stock_valuation_account_product/__openerp__.py'
31--- stock_valuation_account_product/__openerp__.py 1970-01-01 00:00:00 +0000
32+++ stock_valuation_account_product/__openerp__.py 2013-09-12 21:23:37 +0000
33@@ -0,0 +1,51 @@
34+#!/usr/bin/python
35+# -*- encoding: utf-8 -*-
36+#
37+# Module Writen to OpenERP, Open Source Management Solution
38+# Copyright (C) Vauxoo (<http://vauxoo.com>).
39+# All Rights Reserved
40+#
41+# Coded by: Jorge Angel Naranjo Rogel (jorge_nr@vauxoo.com)
42+#
43+# This program is free software: you can redistribute it and/or modify
44+# it under the terms of the GNU Affero General Public License as published by
45+# the Free Software Foundation, either version 3 of the License, or
46+# (at your option) any later version.
47+#
48+# This program is distributed in the hope that it will be useful,
49+# but WITHOUT ANY WARRANTY; without even the implied warranty of
50+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51+# GNU Affero General Public License for more details.
52+#
53+# You should have received a copy of the GNU Affero General Public License
54+# along with this program. If not, see <http://www.gnu.org/licenses/>.
55+#
56+{
57+ "name": "Stock Valuation Account In Product",
58+ "version": "1.0",
59+ "depends": [
60+ "product",
61+ "stock",
62+ "mrp",
63+ "account_anglo_saxon",
64+ ],
65+ "author": "Vauxoo",
66+ "description" : """
67+Stock Valuation Account In Product
68+====================================
69+
70+This module added in form view of product in the seccion Accounting
71+the field Stock Valuation Account.
72+
73+ """,
74+ "website": "http://vauxoo.com",
75+ "category": "Addons Vauxoo",
76+ "demo": [],
77+ "test": [],
78+ "data": [
79+ 'view/product_product_stock_valuation_account.xml',
80+ ],
81+ 'application': True,
82+ "active": False,
83+ "installable": True,
84+}
85
86=== added directory 'stock_valuation_account_product/model'
87=== added file 'stock_valuation_account_product/model/__init__.py'
88--- stock_valuation_account_product/model/__init__.py 1970-01-01 00:00:00 +0000
89+++ stock_valuation_account_product/model/__init__.py 2013-09-12 21:23:37 +0000
90@@ -0,0 +1,23 @@
91+#!/usr/bin/python
92+# -*- encoding: utf-8 -*-
93+#
94+# Module Writen to OpenERP, Open Source Management Solution
95+# Copyright (C) Vauxoo (<http://vauxoo.com>).
96+# All Rights Reserved
97+#
98+# Coded by: Jorge Angel Naranjo Rogel (jorge_nr@vauxoo.com)
99+#
100+# This program is free software: you can redistribute it and/or modify
101+# it under the terms of the GNU Affero General Public License as published by
102+# the Free Software Foundation, either version 3 of the License, or
103+# (at your option) any later version.
104+#
105+# This program is distributed in the hope that it will be useful,
106+# but WITHOUT ANY WARRANTY; without even the implied warranty of
107+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108+# GNU Affero General Public License for more details.
109+#
110+# You should have received a copy of the GNU Affero General Public License
111+# along with this program. If not, see <http://www.gnu.org/licenses/>.
112+#
113+import product_product
114
115=== added file 'stock_valuation_account_product/model/product_product.py'
116--- stock_valuation_account_product/model/product_product.py 1970-01-01 00:00:00 +0000
117+++ stock_valuation_account_product/model/product_product.py 2013-09-12 21:23:37 +0000
118@@ -0,0 +1,256 @@
119+#!/usr/bin/python
120+# -*- encoding: utf-8 -*-
121+#
122+# Module Writen to OpenERP, Open Source Management Solution
123+# Copyright (C) Vauxoo (<http://vauxoo.com>).
124+# All Rights Reserved
125+#
126+# Coded by: Jorge Angel Naranjo Rogel (jorge_nr@vauxoo.com)
127+#
128+# This program is free software: you can redistribute it and/or modify
129+# it under the terms of the GNU Affero General Public License as published by
130+# the Free Software Foundation, either version 3 of the License, or
131+# (at your option) any later version.
132+#
133+# This program is distributed in the hope that it will be useful,
134+# but WITHOUT ANY WARRANTY; without even the implied warranty of
135+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
136+# GNU Affero General Public License for more details.
137+#
138+# You should have received a copy of the GNU Affero General Public License
139+# along with this program. If not, see <http://www.gnu.org/licenses/>.
140+#
141+from openerp.osv import fields, osv
142+from openerp.tools.translate import _
143+import datetime
144+
145+
146+class product_product (osv.Model):
147+ _inherit = "product.product"
148+ _columns = {
149+ 'property_stock_valuation_account_id': fields.property('account.account',
150+ type='many2one',
151+ relation='account.account',
152+ string="Stock Valuation Account",
153+ view_load=True,
154+ help="When real-time inventory valuation is enabled on a product, this account will hold the current value of the products.",),
155+ }
156+
157+ def get_product_accounts(self, cr, uid, product_id, context=None):
158+ """ To get the stock input account, stock output account and stock journal related to product.
159+ @param product_id: product id
160+ @return: dictionary which contains information regarding stock input account, stock output account and stock journal
161+ """
162+ if context is None:
163+ context = {}
164+ product_obj = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
165+
166+ stock_input_acc = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id or False
167+ if not stock_input_acc:
168+ stock_input_acc = product_obj.categ_id.property_stock_account_input_categ and product_obj.categ_id.property_stock_account_input_categ.id or False
169+
170+ stock_output_acc = product_obj.property_stock_account_output and product_obj.property_stock_account_output.id or False
171+ if not stock_output_acc:
172+ stock_output_acc = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id or False
173+
174+ journal_id = product_obj.categ_id.property_stock_journal and product_obj.categ_id.property_stock_journal.id or False
175+ account_valuation = product_obj.property_stock_valuation_account_id and product_obj.property_stock_valuation_account_id.id or False
176+ if not account_valuation:
177+ return super(product_product, self).get_product_accounts(cr, uid, product_id, context=context)
178+ return {
179+ 'stock_account_input': stock_input_acc,
180+ 'stock_account_output': stock_output_acc,
181+ 'stock_journal': journal_id,
182+ 'property_stock_valuation_account_id': account_valuation
183+ }
184+
185+
186+ def do_change_standard_price(self, cr, uid, ids, datas, context=None):
187+ """ Changes the Standard Price of Product and creates an account move accordingly.
188+ @param datas : dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal
189+ @param context: A standard dictionary
190+ @return:
191+
192+ """
193+ location_obj = self.pool.get('stock.location')
194+ move_obj = self.pool.get('account.move')
195+ move_line_obj = self.pool.get('account.move.line')
196+ if context is None:
197+ context = {}
198+
199+ new_price = datas.get('new_price', 0.0)
200+ stock_output_acc = datas.get('stock_output_account', False)
201+ stock_input_acc = datas.get('stock_input_account', False)
202+ journal_id = datas.get('stock_journal', False)
203+ product_obj=self.browse(cr, uid, ids, context=context)[0]
204+ account_valuation = product_obj.property_stock_valuation_account_id
205+ if not account_valuation:
206+ return super(product_product, self).do_change_standard_price(cr, uid, ids, datas, context=context)
207+
208+ account_valuation_id = account_valuation and account_valuation.id or False
209+ if not account_valuation_id: raise osv.except_osv(_('Error!'), _('Specify valuation Account for Product Category: %s.') % (product_obj.categ_id.name))
210+ move_ids = []
211+ loc_ids = location_obj.search(cr, uid,[('usage','=','internal')])
212+ for rec_id in ids:
213+ for location in location_obj.browse(cr, uid, loc_ids, context=context):
214+ c = context.copy()
215+ c.update({
216+ 'location': location.id,
217+ 'compute_child': False
218+ })
219+
220+ product = self.browse(cr, uid, rec_id, context=c)
221+ qty = product.qty_available
222+ diff = product.standard_price - new_price
223+ if not diff: raise osv.except_osv(_('Error!'), _("No difference between standard price and new price!"))
224+ if qty:
225+ company_id = location.company_id and location.company_id.id or False
226+ if not company_id: raise osv.except_osv(_('Error!'), _('Please specify company in Location.'))
227+ #
228+ # Accounting Entries
229+ #
230+ if not journal_id:
231+ journal_id = product.categ_id.property_stock_journal and product.categ_id.property_stock_journal.id or False
232+ if not journal_id:
233+ raise osv.except_osv(_('Error!'),
234+ _('Please define journal '\
235+ 'on the product category: "%s" (id: %d).') % \
236+ (product.categ_id.name,
237+ product.categ_id.id,))
238+ move_id = move_obj.create(cr, uid, {
239+ 'journal_id': journal_id,
240+ 'company_id': company_id
241+ })
242+
243+ move_ids.append(move_id)
244+
245+
246+ if diff > 0:
247+ if not stock_input_acc:
248+ stock_input_acc = product.\
249+ property_stock_account_input.id
250+ if not stock_input_acc:
251+ stock_input_acc = product.categ_id.\
252+ property_stock_account_input_categ.id
253+ if not stock_input_acc:
254+ raise osv.except_osv(_('Error!'),
255+ _('Please define stock input account ' \
256+ 'for this product: "%s" (id: %d).') % \
257+ (product.name,
258+ product.id,))
259+ amount_diff = qty * diff
260+ move_line_obj.create(cr, uid, {
261+ 'name': product.name,
262+ 'account_id': stock_input_acc,
263+ 'debit': amount_diff,
264+ 'move_id': move_id,
265+ })
266+ move_line_obj.create(cr, uid, {
267+ 'name': product.categ_id.name,
268+ 'account_id': account_valuation_id,
269+ 'credit': amount_diff,
270+ 'move_id': move_id
271+ })
272+ elif diff < 0:
273+ if not stock_output_acc:
274+ stock_output_acc = product.\
275+ property_stock_account_output.id
276+ if not stock_output_acc:
277+ stock_output_acc = product.categ_id.\
278+ property_stock_account_output_categ.id
279+ if not stock_output_acc:
280+ raise osv.except_osv(_('Error!'),
281+ _('Please define stock output account ' \
282+ 'for this product: "%s" (id: %d).') % \
283+ (product.name,
284+ product.id,))
285+ amount_diff = qty * -diff
286+ move_line_obj.create(cr, uid, {
287+ 'name': product.name,
288+ 'account_id': stock_output_acc,
289+ 'credit': amount_diff,
290+ 'move_id': move_id
291+ })
292+ move_line_obj.create(cr, uid, {
293+ 'name': product.categ_id.name,
294+ 'account_id': account_valuation_id,
295+ 'debit': amount_diff,
296+ 'move_id': move_id
297+ })
298+
299+ self.write(cr, uid, rec_id, {'standard_price': new_price})
300+
301+ return move_ids
302+
303+class mrp_production(osv.Model):
304+ _inherit = 'mrp.production'
305+
306+ def get_journal_accounts(self, cr, uid, product, production, context={}):
307+
308+ if not context:
309+ context = {}
310+
311+ src_acc = False
312+ dest_acc = False
313+ entrie = False
314+
315+ if context.get('type', False) == 'consumed':
316+ if product.quantity > 0:
317+ if production.product_id.property_stock_production.valuation_in_account_id:
318+ src_acc = production.product_id.property_stock_production.valuation_in_account_id.id
319+ if product.product_id.type == 'service':
320+ dest_acc = product.property_stock_valuation_account_id and\
321+ product.property_stock_valuation_account_id.id or False
322+ if not dest_acc:
323+ dest_acc = product.product_id.categ_id.property_stock_valuation_account_id and\
324+ product.product_id.categ_id.property_stock_valuation_account_id.id or False
325+ entrie = True
326+ elif production.product_id.property_stock_production.variation_in_account_id:
327+ dest_acc = production.product_id.property_stock_production.variation_in_account_id.id
328+ reference_amount = product.cost_variation
329+
330+ if product.quantity < 0:
331+ if product.product_id.type == 'service':
332+ src_acc = product.property_stock_valuation_account_id and\
333+ product.property_stock_valuation_account_id.id or False
334+ if not src_acc:
335+ src_acc = product.product_id.categ_id.property_stock_valuation_account_id and\
336+ product.product_id.categ_id.property_stock_valuation_account_id.id or False
337+ entrie = True
338+ elif production.product_id.property_stock_production.variation_in_account_id:
339+ src_acc = production.product_id.property_stock_production.variation_in_account_id.id
340+ if production.product_id.property_stock_production.valuation_in_account_id:
341+ dest_acc = production.product_id.property_stock_production.valuation_in_account_id.id
342+ reference_amount = product.cost_variation*-1
343+
344+ if entrie:
345+ return super(mrp_production, self).get_journal_accounts(cr, uid, product, production, context=context)
346+
347+ if context.get('type', False) == 'produced':
348+ if product.quantity > 0:
349+ if production.product_id.property_stock_production.valuation_out_account_id:
350+ src_acc = production.product_id.property_stock_production.variation_out_account_id.id
351+ if production.product_id.property_stock_production.variation_out_account_id:
352+ dest_acc = production.product_id.property_stock_production.valuation_out_account_id.id
353+ reference_amount = product.cost_variation
354+ if product.quantity < 0:
355+ if production.product_id.property_stock_production.variation_out_account_id:
356+ src_acc = production.product_id.property_stock_production.valuation_out_account_id.id
357+ if production.product_id.property_stock_production.valuation_out_account_id:
358+ dest_acc = production.product_id.property_stock_production.variation_out_account_id.id
359+ reference_amount = product.cost_variation*-1
360+
361+ journal_id = product.product_id.categ_id.property_stock_journal.id
362+ if not src_acc or not dest_acc:
363+ raise osv.except_osv(_('Error!'),
364+ _('There is no account defined for this location: "%s" ') %
365+ (production.product_id.property_stock_production.name,))
366+
367+ if not journal_id:
368+ raise osv.except_osv(_('Error!'),
369+ _('There is no journal defined on the product category:\
370+ "%s" (id: %d)') %
371+ (product.product_id.categ_id.name,
372+ product.product_id.categ_id.id,))
373+
374+ return journal_id, src_acc, dest_acc, reference_amount
375
376=== added directory 'stock_valuation_account_product/view'
377=== added file 'stock_valuation_account_product/view/product_product_stock_valuation_account.xml'
378--- stock_valuation_account_product/view/product_product_stock_valuation_account.xml 1970-01-01 00:00:00 +0000
379+++ stock_valuation_account_product/view/product_product_stock_valuation_account.xml 2013-09-12 21:23:37 +0000
380@@ -0,0 +1,20 @@
381+<?xml version='1.0' encoding='UTF-8'?>
382+<openerp>
383+ <data>
384+ <record id="view_product_stock_valuation_account_inherit" model="ir.ui.view">
385+ <field name="name">view.product.stock.valuation.account.inherit</field>
386+ <field name="model">product.product</field>
387+ <field name="inherit_id" ref="product.product_normal_form_view"/>
388+ <field name="priority">30</field>
389+ <field name="arch" type="xml">
390+ <xpath expr="//field[@name='property_stock_account_output']" position="after">
391+ <field name="property_stock_valuation_account_id" attrs="{'invisible':[('valuation', '!=', 'real_time')]}"
392+ domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
393+ </xpath>
394+ </field>
395+ </record>
396+ </data>
397+</openerp>
398+
399+
400+