Skip to content

Commit

Permalink
[IMP] added wizard to display margins and magin information in produc…
Browse files Browse the repository at this point in the history
…t form view

(lp:c2c-addons/6.1  rev 28.3.13)
  • Loading branch information
gurneyalex committed Jun 13, 2012
1 parent b390141 commit 646e19f
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 66 deletions.
2 changes: 1 addition & 1 deletion product_historical_margin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
##############################################################################

from . import product_historical_margin
##from . import wizard
from . import wizard
6 changes: 4 additions & 2 deletions product_historical_margin/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,22 @@
#
##############################################################################
{'name' : 'Product Historical Margin',
'version' : '0.1',
'version' : '0.2',
'author' : 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Accounting & Finance',
'complexity': "normal", # easy, normal, expert
'depends' : ['product_get_cost_field',
'account',
'sale',
],
'description': """Provides an improved way of computing the margin and markup of a product, especially for product with a averaged cost price. XXX
""",
'website': 'http://www.camptocamp.com/',
'init_xml': [],
'update_xml': ["account_invoice_view.xml",
#"wizard/historical_margin_view.xml",
"wizard/historical_margin_view.xml",
"product_view.xml",
],
'demo_xml': [],
'tests': [],
Expand Down
110 changes: 77 additions & 33 deletions product_historical_margin/product_historical_margin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,68 @@

import decimal_precision as dp

# Don't Forget to remove supplier (in_invoice et in_refund) from the product margin computation
# And remove out_refund from the computation
# et ne prendre que les factures paid.

# TODO: re-enable when the wizard is ready
# Don't Forget to remove supplier from the product margin computation
# And remove credit note from the computation

## class product_product(Model):
## _inherit = 'product_product'
## def _compute_margin(self, cr, uid, ids, field_names, arg, context):
## res = {}
## for obj in self.browse(cr, uid, ids):
## product = obj.product_id
## res[obj.id] = self._compute_margin2(cr, uid, product.id, obj.discount, obj.price_unit)
## print res
## return res
## _columns = {
## 'margin_absolute': fields.function(_compute_margin, method=True,
## readonly=True, type='float',
## string='Margin (absolute)',
## multi='product_historical_margin',
## digits_compute=dp.get_precision('Account'),
## help="The margin on the product in absolute value"),
## 'margin_relative': fields.function(_compute_margin, method=True,
## readonly=True, type='float',
## string='Margin (%)',
## multi='product_historical_margin',
## digits_compute=dp.get_precision('Account'),
## help="The margin on the product in relative value"),
## }
class product_product(Model):
_inherit = 'product.product'
def _compute_margin(self, cr, uid, ids, field_names, arg, context):
res = {}
user_obj = self.pool.get('res.users')
company_id = user_obj.browse(cr, uid, uid).company_id.id

for product in self.browse(cr, uid, ids):
res[product.id] = {'margin_absolute': 0, 'margin_relative': 0}

# get information about invoice lines relative to our products
# belonging to open or paid invoices in the considered period
query = '''SELECT product_id, type,
SUM(quantity),
SUM(quantity*margin_absolute),
SUM(quantity*margin_relative)
FROM account_invoice_line AS line INNER JOIN account_invoice AS inv ON (inv.id = line.invoice_id)
WHERE %s inv.state IN ('open', 'paid')
AND type NOT IN ('in_invoice', 'in_refund')
AND product_id IN %%(product_ids)s
AND inv.company_id = %%(company_id)s
GROUP BY product_id, type
HAVING SUM(quantity) != 0
'''
substs = context.copy()
substs['product_ids'] = tuple(res)
substs['company_id'] = company_id
date_clause = []
if 'from_date' in substs:
date_clause.append('inv.date_invoice >= %(from_date)s AND')
if 'to_date' in substs:
date_clause.append('inv.date_invoice <= %(to_date)s AND')
query %= ' '.join(date_clause)
cr.execute(query, substs)
for product_id, inv_type, quantity, m_abs, m_rel in cr.fetchall():
if inv_type == 'out_refund':
factor = -1.
else:
factor = 1.
res[product_id]['margin_absolute'] += factor * m_abs / quantity
res[product_id]['margin_relative'] += factor * m_rel / quantity
return res

_columns = {
'margin_absolute': fields.function(_compute_margin, method=True,
readonly=True, type='float',
string='Margin (absolute)',
multi='product_historical_margin',
digits_compute=dp.get_precision('Account'),
help="The margin on the product in absolute value"),
'margin_relative': fields.function(_compute_margin, method=True,
readonly=True, type='float',
string='Margin (%)',
multi='product_historical_margin',
digits_compute=dp.get_precision('Account'),
help="The margin on the product in relative value"),
}


class account_invoice_line(Model):
Expand Down Expand Up @@ -83,7 +118,7 @@ def _convert_to_invoice_currency(self, cursor, user, amount, currency_id=False):


def _compute_margin2(self, cr, uid, product_id, discount, price_unit, currency_id=False):

if not product_id:
return {'product_cost_price': 0.0,
'margin_absolute': 0.0,
Expand Down Expand Up @@ -111,7 +146,7 @@ def product_id_change(self, cr, uid, ids, product_id, uom,
price_unit=False, address_invoice_id=False,
currency_id=False, discount=0, context=None, company_id=None):

result = super(account_invoice_line, self).product_id_change(cr, uid, ids, product_id, uos_id, qty=qty, name=name,
result = super(account_invoice_line, self).product_id_change(cr, uid, ids, product_id, uom, qty=qty, name=name,
type=type, partner_id=partner_id, fposition_id=fposition_id, price_unit=price_unit,
address_invoice_id=address_invoice_id, currency_id=currency_id, context=context,
company_id=company_id)
Expand Down Expand Up @@ -152,7 +187,7 @@ def _recalc_margin_parent(self, cr, uid, ids, context=None):
['currency_id'],
10),
}

_columns = {
'product_cost_price': fields.function(_compute_margin, method=True, readonly=True,type='float',
string='Historical Cost Price',
Expand All @@ -167,18 +202,27 @@ def _recalc_margin_parent(self, cr, uid, ids, context=None):
store=_col_store,
digits_compute=dp.get_precision('Account'),
help="The margin on the product in absolute value"),
'margin_relative': fields.function(_compute_margin, method=True,
'margin_relative': fields.function(_compute_margin, method=True,
readonly=True, type='float',
string='Margin (%)',
multi='product_historical_margin',
store=_col_store,
digits_compute=dp.get_precision('Account'),
help="The margin on the product in relative value"),
'invoice_state': fields.related('invoice_id', 'state', type='selection',
readonly=True,
help='optimize queries when computing the margins'),
'invoice_date': fields.related('invoice_id', 'date_invoice', type='date',
readonly=True,
help='optimize queries when computing the margins'),
'invoice_type': fields.related('invoice_id', 'type', type='selection',
readonly=True,
help='optimize queries when computing the margins'),
}

# class AccountChangeCurrency(osv.osv_memory):
# _inherit = 'account.change.currency'
#
#
# def change_currency(self, cr, uid, ids, context=None):
# """We copy past here the original method in order to convert as well the cost price
# in the new curreny."""
Expand All @@ -200,13 +244,13 @@ def _recalc_margin_parent(self, cr, uid, ids, context=None):
# new_price = line.price_unit * rate
# if new_price <= 0:
# raise osv.except_osv(_('Error'), _('New currency is not configured properly !'))
#
#
# if invoice.company_id.currency_id.id != invoice.currency_id.id and invoice.company_id.currency_id.id == new_currency:
# old_rate = invoice.currency_id.rate
# if old_rate <= 0:
# raise osv.except_osv(_('Error'), _('Current currency is not configured properly !'))
# new_price = line.price_unit / old_rate
#
#
# if invoice.company_id.currency_id.id != invoice.currency_id.id and invoice.company_id.currency_id.id != new_currency:
# old_rate = invoice.currency_id.rate
# if old_rate <= 0:
Expand Down
32 changes: 32 additions & 0 deletions product_historical_margin/product_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_product_historical_margin_form" model="ir.ui.view">
<field name="name">product_historical_margin.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref='product.product_normal_form_view'/>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="list_price" position="after">
<field name="margin_absolute" groups="base.group_sale_manager"/>
<field name="margin_relative" groups="base.group_sale_manager"/>
</field>
</field>
</record>

<record id="view_product_historical_margin" model="ir.ui.view">
<field name="name">product.product.historical_margin.tree</field>
<field name="model">product.product</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Historical Margins">
<field name="default_code"/>
<field name="name"/>
<field name="margin_absolute"/>
<field name="margin_relative"/>
</tree>
</field>
</record>

</data>
</openerp>
44 changes: 33 additions & 11 deletions product_historical_margin/wizard/historical_margin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,55 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import datetime
import time

from openerp.osv.orm import TransientModel
from openerp.osv import fields
from openerp.tools.translate import _


class historical_margin(TransientModel):
_name = 'historical_margin'
_name = 'historical.margin'
_description = 'Product historical margin'
_columns = {
'start_date': fields.date('Start Date', help='Date of the first invoice to take into account. The earliest existing invoice will be used if left empty'),
'end_date': fields.date('End Date', help='Date of the last invoice to take into account. The latest existing invoice will be used if left empty')
'from_date': fields.date('From', help='Date of the first invoice to take into account. '
'The earliest existing invoice will be used if left empty'),
'to_date': fields.date('To', help='Date of the last invoice to take into account. '
'The latest existing invoice will be used if left empty')
}
_defaults = {
'start_date': lambda *a: datetime.date(datetime.date.today().year, 1, 1),
#'end_date': lambda *a: datetime.date.today(),
'from_date': time.strftime('%Y-01-01'),
'to_date': time.strftime('%Y-12-31'),
}

def historical_margin_open_window(self, cr, uid, ids, context=None):
def action_open_window(self, cr, uid, ids, context=None):
"""
Open the historical margin view
"""
if context is None:
context = {}
wiz = self.read(cr, uid, ids, [], context)[0]
ctx = context.copy()
ctx['start_date'] = wiz.get('start_date')
ctx['end_date'] = wiz.get('end_date')
# XXX FIXME

ctx['from_date'] = wiz.get('from_date')
ctx['to_date'] = wiz.get('to_date')
data_pool = self.pool.get('ir.model.data')
filter_ids = data_pool.get_object_reference(cr, uid, 'product',
'product_category_search_view')
product_view_id = data_pool.get_object_reference(cr, uid,
'product_historical_margin',
'view_product_historical_margin')
if filter_ids:
filter_id = filter_ids[1]
else:
filter_id = 0
return {
'name': _('Historical Margins'),
'context': ctx,
'view_type': 'tree',
'view_mode': 'tree',
'res_model': 'product.product',
'type': 'ir.actions.act_window',
'view_id': False,
'views': [(product_view_id[1], 'tree')],
'search_view_id': filter_id,
}
32 changes: 13 additions & 19 deletions product_historical_margin/wizard/historical_margin_view.xml
Original file line number Diff line number Diff line change
@@ -1,39 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>

<!-- XXX This file is not processed (not listed in __openerp__.py) -->
<openerp>
<data>
<record id="view_historical_margin" model="ir.ui.view">
<field name="name">historical_margin.form</field>
<field name="model">historical_margin</field>
<field name="name">historical.margin.form</field>
<field name="model">historical.margin</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Historical Margin">
<form string="Historical Margin Properties">
<group colspan="4">
<field name="start_date" "/>
<field name="end_date"/>
<field name="from_date" />
<field name="to_date"/>
</group>
<separator string="" colspan="4"/>
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="terp-gtk-go-back-rtl" string="Compute margins" name="historical_margin_open_window" type="object"/>
<button icon="terp-gtk-go-back-rtl" string="Compute margins" name="action_open_window" type="object"/>
</group>
</form>
</field>
</record>

<record id="action_historical_margin" model="ir.actions.act_window">
<field name="name">Product historical margine</field>
<field name="res_model">historical_margin</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_historical_margin"/>
<field name="target">new</field>
<field name="help">Display the historical margin of your products</field>
</record>
<act_window name="Product Historical Margins"
res_model="historical.margin"
src_model="product.product"
view_mode="form"
target="new"
key2="client_action_multi"
id="historical_margin_act_window"/>

<menuitem icon="STOCK_INDENT" action="action_historical_margin"
id="menu_action_account_tree2"
parent="account.menu_finance_charts" />
</data>
</openerp>

0 comments on commit 646e19f

Please sign in to comment.