[REF] stock: put some order in inventory psql reports (on quants) in labels, files and code

bzr revid: qdp-launchpad@openerp.com-20131205181052-gsnlps6ifvm016az
This commit is contained in:
Quentin (OpenERP) 2013-12-05 19:10:52 +01:00
parent f051ec20e2
commit f8470c94ee
9 changed files with 69 additions and 164 deletions

View File

@ -87,7 +87,6 @@ Dashboard / Reports for Warehouse Management will include:
'stock_sequence.xml', 'stock_sequence.xml',
'product_view.xml', 'product_view.xml',
'partner_view.xml', 'partner_view.xml',
'report/report_stock_move_view.xml',
'report/report_stock_view.xml', 'report/report_stock_view.xml',
'board_warehouse_view.xml', 'board_warehouse_view.xml',
'res_config_view.xml', 'res_config_view.xml',

View File

@ -23,7 +23,6 @@ import product_stock
import picking import picking
import lot_overview_all import lot_overview_all
import report_stock import report_stock
import report_stock_move
import stock_inventory_move_report import stock_inventory_move_report
import lot_overview import lot_overview

View File

@ -1,75 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import tools
from openerp.osv import fields,osv
from openerp.addons.decimal_precision import decimal_precision as dp
# FP Note: TODO: move in stock.py
class stock_quant(osv.osv):
_inherit = "stock.quant"
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
res = super(stock_quant, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
product_obj = self.pool.get("product.product")
if 'inventory_value' in fields:
for line in res:
if '__domain' in line:
lines = self.search(cr, uid, line['__domain'], context=context)
inv_value = 0.0
for line2 in self.browse(cr, uid, lines, context=context):
inv_value += line2.inventory_value
line['inventory_value'] = inv_value
return res
def _calc_moves(self, cr, uid, ids, name, attr, context=None):
product_obj = self.pool.get("product.product")
res = {}
proddict = {}
# Fill proddict with the products we will need browse records from (optimization)
lines = self.browse(cr, uid, ids, context=context)
for line in lines:
if not line.company_id.id in proddict:
proddict[line.company_id.id] = {}
proddict[line.company_id.id][line.product_id.id] = True
prodbrow = {}
# Fill prodbrow with browse records needed from proddict
for prodelem in proddict.keys():
ctx = context.copy()
ctx['force_company'] = prodelem
prods = product_obj.browse(cr, uid, proddict[prodelem].keys(), context=ctx)
for prod in prods:
prodbrow[(prodelem, prod.id)] = prod
# use prodbrow and existing value on quants to calculate the inventory_value on the report lines
for line in lines:
ctx = context.copy()
ctx['force_company'] = line.company_id.id
prod = product_obj.browse(cr, uid, line.product_id.id, context=ctx)
res[line.id] = self._get_inventory_value(cr, uid, line, prodbrow, context=ctx)
return res
def _get_inventory_value(self, cr, uid, line, prodbrow, context=None):
return prodbrow[(line.company_id.id, line.product_id.id)].standard_price * line.qty
_columns = {
'inventory_value': fields.function(_calc_moves, string="Inventory Value", type='float', readonly=True),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem
id="stock.next_id_61"
name="Warehouse"
sequence="15"
parent="base.menu_reporting"
groups="group_stock_manager"/>
<!-- Inventory Control -->
<record model="ir.ui.view" id="view_stock_quant_tree_value">
<field name="name">stock.quant.tree</field>
<field name="model">stock.quant</field>
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<tree string="Quants">
<field name="product_id"/>
<field name="qty"/>
<field name="location_id"/>
<field name="in_date"/>
<field name="inventory_value"/>
<field name="reservation_id" invisible='1'/>
<field name="propagated_from_id" invisible='1'/>
<field name="company_id" invisible='1'/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_stock_quant_graph_value">
<field name="name">stock.quant.graph</field>
<field name="model">stock.quant</field>
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<graph string="Quants">
<field name="product_id"/>
<field name="qty"/>
<field name="location_id"/>
<field name="inventory_value"/>
</graph>
</field>
</record>
<record id="action_stock_inventory_report" model="ir.actions.act_window">
<field name="name">Inventory Valuation</field>
<field name="res_model">stock.quant</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph,form</field>
<field name="view_id" ref="view_stock_quant_tree_value"/>
<field name="context">{'search_default_real':1, 'search_default_inmovesremaining':1 ,'group_by':['company_id', 'product_id'], 'group_by_no_leaf':0}</field>
<field name="help">Inventory Analysis allows you to easily check and analyse your company stock levels. Sort and group by selection criteria in order to better analyse and manage your company activities.</field>
</record>
<menuitem action="action_stock_inventory_report"
id="menu_action_stock_inventory_report"
parent="next_id_61" sequence="4"/>
</data>
</openerp>

View File

@ -204,6 +204,22 @@ class stock_quant(osv.osv):
res[q.id] += ': ' + str(q.qty) + q.product_id.uom_id.name res[q.id] += ': ' + str(q.qty) + q.product_id.uom_id.name
return res return res
def _calc_inventory_value(self, cr, uid, ids, name, attr, context=None):
res = {}
uid_company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
for quant in self.browse(cr, uid, ids, context=context):
context.pop('force_company', None)
if quant.company_id.id != uid_company_id:
#if the company of the quant is different than the current user company, force the company in the context
#then re-do a browse to read the property fields for the good company.
context['force_company'] = quant.company_id.id
quant = self.browse(cr, uid, quant.id, context=context)
res[quant.id] = self._get_inventory_value(cr, uid, quant, context=context)
return res
def _get_inventory_value(self, cr, uid, quant, context=None):
return quant.product_id.standard_price * quant.qty
_columns = { _columns = {
'name': fields.function(_get_quant_name, type='char', string='Identifier'), 'name': fields.function(_get_quant_name, type='char', string='Identifier'),
'product_id': fields.many2one('product.product', 'Product', required=True), 'product_id': fields.many2one('product.product', 'Product', required=True),
@ -226,12 +242,26 @@ class stock_quant(osv.osv):
# Used for negative quants to reconcile after compensated by a new positive one # Used for negative quants to reconcile after compensated by a new positive one
'propagated_from_id': fields.many2one('stock.quant', 'Linked Quant', help='The negative quant this is coming from'), 'propagated_from_id': fields.many2one('stock.quant', 'Linked Quant', help='The negative quant this is coming from'),
'negative_dest_location_id': fields.many2one('stock.location', 'Destination Location', help='Technical field used to record the destination location of a move that created a negative quant'), 'negative_dest_location_id': fields.many2one('stock.location', 'Destination Location', help='Technical field used to record the destination location of a move that created a negative quant'),
'inventory_value': fields.function(_calc_inventory_value, string="Inventory Value", type='float', readonly=True),
} }
_defaults = { _defaults = {
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.quant', context=c), 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.quant', context=c),
} }
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
''' Overwrite the read_group in order to sum the function field 'inventory_value' in group by'''
res = super(stock_quant, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
if 'inventory_value' in fields:
for line in res:
if '__domain' in line:
lines = self.search(cr, uid, line['__domain'], context=context)
inv_value = 0.0
for line2 in self.browse(cr, uid, lines, context=context):
inv_value += line2.inventory_value
line['inventory_value'] = inv_value
return res
def action_view_quant_history(self, cr, uid, ids, context=None): def action_view_quant_history(self, cr, uid, ids, context=None):
''' '''
This function returns an action that display the history of the quant, which This function returns an action that display the history of the quant, which

View File

@ -1750,9 +1750,12 @@
</record> </record>
<record model="ir.actions.act_window" id="quantsact"> <record model="ir.actions.act_window" id="quantsact">
<field name="name">Quants</field> <field name="name">Current Stock</field>
<field name="context">{'search_default_productgroup':'1', 'search_default_internal_loc': 1}</field> <field name="context">{'search_default_productgroup':'1', 'search_default_internal_loc': 1}</field>
<field name="res_model">stock.quant</field> <field name="res_model">stock.quant</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="help">This analysis gives you a fast overview on the current stock level of your products and their today's inventory value.</field>
</record> </record>
<record model="ir.ui.view" id="view_stock_quant_form"> <record model="ir.ui.view" id="view_stock_quant_form">
@ -1784,7 +1787,7 @@
<field eval="10" name="priority"/> <field eval="10" name="priority"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Quants" create="0"> <tree string="Quants" create="0">
<field name="product_id" invisible="1"/> <field name="product_id"/>
<field name="qty"/> <field name="qty"/>
<field name="location_id"/> <field name="location_id"/>
<field name="owner_id" groups="stock.group_tracking_owner"/> <field name="owner_id" groups="stock.group_tracking_owner"/>
@ -1792,24 +1795,39 @@
<field name="package_id" groups="stock.group_tracking_lot"/> <field name="package_id" groups="stock.group_tracking_lot"/>
<field name="packaging_type_id" invisible="1"/> <field name="packaging_type_id" invisible="1"/>
<field name="in_date"/> <field name="in_date"/>
<field name="inventory_value"/>
<field name="reservation_id" invisible='1'/> <field name="reservation_id" invisible='1'/>
<field name="propagated_from_id" invisible='1'/> <field name="propagated_from_id" invisible='1'/>
<field name='company_id' groups="base.group_multi_company"/>
</tree> </tree>
</field> </field>
</record> </record>
<record model="ir.ui.view" id="view_stock_quant_graph_value">
<field name="name">stock.quant.graph</field>
<field name="model">stock.quant</field>
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<graph string="Quants">
<field name="product_id"/>
<field name="qty"/>
<field name="location_id"/>
<field name="inventory_value"/>
</graph>
</field>
</record>
<!-- Procurements are located in Warehouse menu hierarchy, MRP users should come to Stock application to use it. --> <!-- Procurements are located in Warehouse menu hierarchy, MRP users should come to Stock application to use it. -->
<menuitem id="menu_stock_sched" name="Schedulers" parent="stock.menu_stock_root" sequence="4" groups="stock.group_stock_manager"/> <menuitem id="menu_stock_sched" name="Schedulers" parent="stock.menu_stock_root" sequence="4" groups="stock.group_stock_manager"/>
<menuitem action="action_procurement_compute" id="menu_procurement_compute" parent="menu_stock_sched" groups="base.group_no_one"/> <menuitem action="action_procurement_compute" id="menu_procurement_compute" parent="menu_stock_sched" groups="base.group_no_one"/>
<menuitem action="procurement.action_compute_schedulers" id="menu_stock_proc_schedulers" parent="menu_stock_sched" sequence="20" groups="stock.group_stock_manager"/> <menuitem action="procurement.action_compute_schedulers" id="menu_stock_proc_schedulers" parent="menu_stock_sched" sequence="20" groups="stock.group_stock_manager"/>
<menuitem action="procurement.procurement_exceptions" id="menu_stock_procurement_action" parent="menu_stock_sched" sequence="50" groups="stock.group_stock_manager"/> <menuitem action="procurement.procurement_exceptions" id="menu_stock_procurement_action" parent="menu_stock_sched" sequence="50" groups="stock.group_stock_manager"/>
<menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_configuration" sequence="5"/> <menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_configuration" sequence="5"/>
<menuitem action="action_orderpoint_form" id="menu_stock_order_points" parent="stock.menu_stock_configuration" sequence="10"/> <menuitem action="action_orderpoint_form" id="menu_stock_order_points" parent="stock.menu_stock_configuration" sequence="10"/>
<menuitem id="menu_quants" name="Current Inventory" parent="stock.menu_stock_inventory_control" sequence="20" action="quantsact"/> <menuitem id="stock.next_id_61" name="Warehouse" sequence="15" parent="base.menu_reporting" groups="group_stock_manager"/>
<menuitem id="menu_procurement_rules" name="Procurement Rules" parent="stock.menu_stock_configuration" action="procrules" groups="base.group_no_one"/> <menuitem id="menu_quants" name="Current Stock Value" parent="stock.next_id_61" sequence="20" action="quantsact"/>
<menuitem id="menu_pickingtype" name="Types of Operation" parent="stock.menu_stock_configuration" action="action_picking_type_list"/> <menuitem id="menu_procurement_rules" name="Procurement Rules" parent="stock.menu_stock_configuration" action="procrules" groups="base.group_no_one"/>
<menuitem id="menu_pickingtype" name="Types of Operation" parent="stock.menu_stock_configuration" action="action_picking_type_list"/>
<record model="ir.actions.act_window" id="product_open_orderpoint"> <record model="ir.actions.act_window" id="product_open_orderpoint">

View File

@ -54,11 +54,10 @@ class stock_location(osv.osv):
class stock_quant(osv.osv): class stock_quant(osv.osv):
_inherit = "stock.quant" _inherit = "stock.quant"
def _get_inventory_value(self, cr, uid, line, prodbrow, context=None): def _get_inventory_value(self, cr, uid, quant, context=None):
#TODO: what in case of partner_id if quant.product_id.cost_method in ('real'):
if prodbrow[(line.company_id.id, line.product_id.id)].cost_method in ('real'): return quant.cost * quant.qty
return line.cost * line.qty return super(stock_quant, self)._get_inventory_value(cr, uid, quant, context=context)
return super(stock_quant, self)._get_inventory_value(cr, uid, line, prodbrow, context=context)
def _price_update(self, cr, uid, quant_ids, newprice, context=None): def _price_update(self, cr, uid, quant_ids, newprice, context=None):
''' This function is called at the end of negative quant reconciliation and does the accounting entries adjustemnts and the update of the product cost price if needed ''' This function is called at the end of negative quant reconciliation and does the accounting entries adjustemnts and the update of the product cost price if needed

View File

@ -1,7 +1,7 @@
from openerp import tools from openerp import tools
from openerp.osv import fields, osv from openerp.osv import fields, osv
from openerp.tools.translate import _
class wizard_valuation_history(osv.osv_memory): class wizard_valuation_history(osv.osv_memory):
@ -24,7 +24,7 @@ class wizard_valuation_history(osv.osv_memory):
ctx['group_by'] = ['product_id'] ctx['group_by'] = ['product_id']
return { return {
'domain': "[('date', '<=', '" + data['date'] + "')]", 'domain': "[('date', '<=', '" + data['date'] + "')]",
'name': 'Stock Valuation History', 'name': _('Stock Value At Date'),
'view_type': 'form', 'view_type': 'form',
'view_mode': 'tree', 'view_mode': 'tree',
'res_model': 'stock.history', 'res_model': 'stock.history',

View File

@ -3,7 +3,7 @@
<data> <data>
<record id="view_wizard_valuation_history" model="ir.ui.view"> <record id="view_wizard_valuation_history" model="ir.ui.view">
<field name="name">Stock Valuation History</field> <field name="name">Stock Value At Date</field>
<field name="model">wizard.valuation.history</field> <field name="model">wizard.valuation.history</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Choose your date" version="7.0"> <form string="Choose your date" version="7.0">
@ -25,7 +25,7 @@
</field> </field>
</record> </record>
<record id="action_wizard_stock_valuation_history" model="ir.actions.act_window"> <record id="action_wizard_stock_valuation_history" model="ir.actions.act_window">
<field name="name">Stock Valuation History</field> <field name="name">Stock Value At Date</field>
<field name="res_model">wizard.valuation.history</field> <field name="res_model">wizard.valuation.history</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
@ -35,10 +35,10 @@
<menuitem id="menu_action_wizard_valuation_history" action="action_wizard_stock_valuation_history" parent="stock.next_id_61"/> <menuitem id="menu_action_wizard_valuation_history" action="action_wizard_stock_valuation_history" parent="stock.next_id_61"/>
<record id="view_stock_history_report_tree" model="ir.ui.view"> <record id="view_stock_history_report_tree" model="ir.ui.view">
<field name="name">Stock Valuation History</field> <field name="name">Stock Value At Date</field>
<field name="model">stock.history</field> <field name="model">stock.history</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Stock Valuation History"> <tree string="Stock Value At Date">
<field name="location_id" invisible="1"/> <field name="location_id" invisible="1"/>
<field name="product_id" invisible="1"/> <field name="product_id" invisible="1"/>
<field name="move_id"/> <field name="move_id"/>
@ -53,7 +53,7 @@
<field name="name">stock.history.report.search</field> <field name="name">stock.history.report.search</field>
<field name="model">stock.history</field> <field name="model">stock.history</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Stock Valuation History"> <search string="Stock Value At Date">
<field name="product_id"/> <field name="product_id"/>
<field name="location_id" filter_domain="[('name', 'child_of', self)]"/> <field name="location_id" filter_domain="[('name', 'child_of', self)]"/>
<field name="company_id" groups="base.group_multi_company"/> <field name="company_id" groups="base.group_multi_company"/>