[IMP] reports on stock and purchases

bzr revid: fp@tinyerp.com-20100613155305-z4glzp5h7cq8rzw9
This commit is contained in:
Fabien Pinckaers 2010-06-13 17:53:05 +02:00
parent 1ff14e9ceb
commit 5239c16639
10 changed files with 254 additions and 462 deletions

View File

@ -171,11 +171,9 @@ class purchase_order(osv.osv):
'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True),
'picking_ids': fields.one2many('stock.picking', 'purchase_id', 'Picking List', readonly=True, help="This is the list of picking list that have been generated for this purchase"),
'shipped':fields.boolean('Received', readonly=True, select=True),
'shipped_rate': fields.function(_shipped_rate, method=True, string='Received', type='float',
store=True), # Improve the store=True or remove from report
'shipped_rate': fields.function(_shipped_rate, method=True, string='Received', type='float'),
'invoiced': fields.function(_invoiced, method=True, string='Invoiced & Paid', type='boolean'),
'invoiced_rate': fields.function(_invoiced_rate, method=True, string='Invoiced', type='float',
store=True), # Improve the store=True or remove from report
'invoiced_rate': fields.function(_invoiced_rate, method=True, string='Invoiced', type='float'),
'invoice_method': fields.selection([('manual','Manual'),('order','From Order'),('picking','From Picking')], 'Invoicing Control', required=True,
help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \
"will just have to validate this invoice for control.\n" \
@ -429,6 +427,7 @@ class purchase_order(osv.osv):
'product_uom': order_line.product_uom.id,
'product_uos': order_line.product_uom.id,
'date_planned': order_line.date_planned,
'date_expected': order_line.date_planned,
'location_id': loc_id,
'location_dest_id': dest,
'picking_id': picking_id,

View File

@ -56,13 +56,13 @@ class purchase_report(osv.osv):
'validator' : fields.many2one('res.users', 'Validated By', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'user_id':fields.many2one('res.users', 'Responsible', readonly=True),
'shipped_qty':fields.float('Received', digits=(16,2), readonly=True, group_operator='avg'),
'invoiced_qty':fields.float('Invoiced', digits=(16,2), readonly=True, group_operator='avg'),
'delay':fields.float('Days to Validate', digits=(16,2), readonly=True, group_operator="avg"),
'delay_pass':fields.float('Days to Deliver', digits=(16,2), readonly=True, group_operator="avg"),
'quantity': fields.float('# of Products', readonly=True),
'price_total': fields.float('Total Price', readonly=True),
'price_average': fields.float('Unit Price', readonly=True, group_operator="avg"),
'negociation': fields.float('Purchase-Standard Price', readonly=True, group_operator="avg"),
'price_standard': fields.float('Products Value', readonly=True, group_operator="sum"),
'nbr': fields.integer('# of PO Lines', readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'),
('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')],'Month',readonly=True),
@ -90,18 +90,20 @@ class purchase_report(osv.osv):
s.partner_id as partner_id,
s.create_uid as user_id,
s.company_id as company_id,
avg(s.shipped_rate) as shipped_qty,
avg(s.invoiced_rate) as invoiced_qty,
l.product_id,
s.location_id as location_id,
sum(l.product_qty*u.factor) as quantity,
extract(epoch from age(s.date_approve,s.date_order))/(24*60*60)::decimal(16,2) as delay,
extract(epoch from age(l.date_planned,s.date_order))/(24*60*60)::decimal(16,2) as delay_pass,
count(*) as nbr,
l.price_unit*l.product_qty*u.factor as price_total,
(l.price_unit*l.product_qty*u.factor)::decimal(16,2) as price_total,
avg(100.0 * (l.price_unit*l.product_qty*u.factor) / (t.standard_price*l.product_qty*u.factor))::decimal(16,2) as negociation,
sum(t.standard_price*l.product_qty*u.factor)::decimal(16,2) as price_standard,
(sum(l.product_qty*l.price_unit)/sum(l.product_qty*u.factor))::decimal(16,2) as price_average
from purchase_order s
left join purchase_order_line l on (s.id=l.order_id)
left join product_product p on (l.product_id=p.id)
left join product_template t on (p.product_tmpl_id=t.id)
left join product_uom u on (u.id=l.product_uom)
where l.product_id is not null
group by

View File

@ -34,11 +34,11 @@
<field name="state" invisible="1"/>
<field name="location_id" invisible="1"/>
<field name="nbr"/>
<field name="shipped_qty" widget="progressbar"/>
<field name="invoiced_qty" widget="progressbar"/>
<field name="quantity" sum="# of Products"/>
<field name="price_average" avg="Average Price"/>
<field name="price_total" sum="Total Price"/>
<field name="price_standard" sum="Products Costs"/>
<field name="negociation" widget="progressbar"/>
<field name="delay"/>
<field name="delay_pass"/>
</tree>
@ -123,23 +123,15 @@
<menuitem id="base.next_id_73" name="Reporting" parent="base.menu_purchase_root" sequence="8"/>
<menuitem action="action_purchase_order_report_all" id="menu_action_purchase_order_report_all" parent="base.next_id_73" sequence="3"/>
<record id="action_purchase_order_qty_amount_all" model="ir.actions.act_window">
<field name="name">Purchase Orders by Month</field>
<field name="res_model">purchase.report</field>
<record id="action_stock_move_report_po" model="ir.actions.act_window">
<field name="name">Receptions Analysis</field>
<field name="res_model">report.stock.move</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="context">{'group_by_no_leaf': 1, 'group_by': ['month']}</field>
<field name="domain">[('date','>=',time.strftime('%Y-01-01'))]</field>
<field name="view_mode">tree,graph</field>
<field name="context">{'search_default_month':1, 'search_default_group_product':1, 'search_default_group_partner':1, 'search_default_done':1, 'search_default_in': 1, 'group_by':[], 'group_by_no_leaf':1}</field>
</record>
<menuitem action="action_stock_move_report_po" id="menu_action_stock_move_report_po" parent="base.next_id_73" sequence="8"/>
<record id="action_purchase_order_by_user_all" model="ir.actions.act_window">
<field name="name">Purchase Orders by Supplier</field>
<field name="res_model">purchase.report</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree</field>
<field name="context">{'group_by_no_leaf': 1, 'group_by': ['partner_id']}</field>
<field name="domain">[('date','>=',time.strftime('%Y-01-01'))]</field>
</record>
</data>
</openerp>

View File

@ -64,7 +64,6 @@ Thanks to the double entry management, the inventory controlling is powerful and
"partner_view.xml",
"report/report_stock_move_view.xml",
"report/report_stock_view.xml",
"report/report_stock_picking_view.xml",
"security/stock_security.xml",
"security/ir.model.access.csv",
],
@ -73,4 +72,3 @@ Thanks to the double entry management, the inventory controlling is powerful and
'active': False,
'certificate': '0055421559965',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,7 +19,6 @@
#
##############################################################################
#import lot_overview
import product_stock
import lot_location
import ups
@ -28,7 +27,4 @@ import lot_overview
import lot_overview_all
import report_stock
import report_stock_move
import report_stock_picking
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -34,19 +34,20 @@ class report_stock_move(osv.osv):
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
'partner_id':fields.many2one('res.partner.address', 'Partner', readonly=True),
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'company_id':fields.many2one('res.company', 'Company', readonly=True),
'picking_id':fields.many2one('stock.picking', 'Packing', readonly=True),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('delivery', 'Delivery')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."),
'location_id': fields.many2one('stock.location', 'Source Location', readonly=True, select=True, help="Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', readonly=True, select=True, help="Location where the system will stock the finished products."),
'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True),
'product_qty':fields.integer('Qty',readonly=True),
'value' : fields.float('Total Value', required=True),
'product_uom': fields.many2one('product.uom', 'Product UOM', readonly=True),
'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\
\nThe state is \'Waiting\' if the move is waiting for another one.'),
'day_diff':fields.integer('Expected Performance',readonly=True),
'day_diff2':fields.float('Delay (Days)',readonly=True, digits=(16,2), group_operator="avg"),
'day_diff1':fields.float('Planned (Days)',readonly=True, digits=(16,2), group_operator="avg"),
'day_diff':fields.float('Real (Days)',readonly=True, digits=(16,2), group_operator="avg"),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_move')
cr.execute("""
@ -56,8 +57,13 @@ class report_stock_move(osv.osv):
to_char(date_trunc('day',m.date_planned), 'YYYY') as year,
to_char(date_trunc('day',m.date_planned), 'MM') as month,
to_char(date_trunc('day',m.date_planned), 'YYYY-MM-DD') as day,
(date(m.date_planned)-date(m.date_expected)) as day_diff,
avg(date(m.date_planned)-date(m.create_date)) as day_diff,
avg(date(m.date_expected)-date(m.create_date)) as day_diff1,
avg(date(m.date_planned)-date(m.date_expected)) as day_diff2,
m.address_id as partner_id,
m.picking_id as picking_id,
m.company_id as company_id,
p.type as type,
m.location_id as location_id,
m.location_dest_id as location_dest_id,
m.product_id as product_id,
@ -65,11 +71,83 @@ class report_stock_move(osv.osv):
m.product_uom as product_uom,
sum(m.product_qty) as product_qty,
pt.standard_price * sum(m.product_qty) as value
from stock_move m ,product_product pp,product_template pt
where
m.product_id=pp.id and pp.product_tmpl_id=pt.id
from
stock_move m
left join stock_picking p on (m.picking_id=p.id)
left join product_product pp on (m.product_id=pp.id)
left join product_template pt on (pp.product_tmpl_id=pt.id)
group by
m.id, m.product_id,m.address_id, m.location_id, m.location_dest_id,
m.date_planned, m.state, m.product_uom,pt.standard_price,m.date_expected )
m.date_planned, m.state, m.product_uom,pt.standard_price,
m.picking_id, p.type, m.company_id
)
""")
report_stock_move()
class report_stock_inventory(osv.osv):
_name = "report.stock.inventory"
_description = "Stock Statistics"
_auto = False
_columns = {
'date_planned': fields.datetime('Date', readonly=True),
'partner_id':fields.many2one('res.partner.address', 'Partner', readonly=True),
'product_id':fields.many2one('product.product', 'Product', readonly=True),
'location_id': fields.many2one('stock.location', 'Location', readonly=True),
'prodlot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'product_qty':fields.float('Qty', digits=(16,2), readonly=True),
'value' : fields.float('Total Value', digits=(16,2), required=True),
'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, select=True,
help='When the stock move is created it is in the \'Draft\' state.\n After that it is set to \'Confirmed\' state.\n If stock is available state is set to \'Avaiable\'.\n When the picking it done the state is \'Done\'.\
\nThe state is \'Waiting\' if the move is waiting for another one.'),
'location_type': fields.selection([('supplier', 'Supplier Location'), ('view', 'View'), ('internal', 'Internal Location'), ('customer', 'Customer Location'), ('inventory', 'Inventory'), ('procurement', 'Procurement'), ('production', 'Production'), ('transit', 'Transit Location for Inter-Companies Transfers')], 'Location Type', required=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_inventory')
cr.execute("""
create or replace view report_stock_inventory as (
(select
min(m.id) as id, m.date_planned as date_planned,
m.address_id as partner_id, m.location_id as location_id,
m.product_id as product_id, l.usage as location_type,
m.company_id,
m.state as state, m.prodlot_id as prodlot_id,
sum(-m.product_qty*u.factor)::decimal(16,2) as product_qty,
sum(-pt.standard_price * m.product_qty * u.factor)::decimal(16,2) as value
from
stock_move m
left join stock_picking p on (m.picking_id=p.id)
left join product_product pp on (m.product_id=pp.id)
left join product_template pt on (pp.product_tmpl_id=pt.id)
left join product_uom u on (m.product_uom=u.id)
left join stock_location l on (m.location_id=l.id)
group by
m.id, m.product_id, m.address_id, m.location_id, m.prodlot_id,
m.date_planned, m.state, l.usage, m.company_id
) union all (
select
-m.id as id, m.date_planned as date_planned,
m.address_id as partner_id, m.location_dest_id as location_id,
m.product_id as product_id, l.usage as location_type,
m.company_id,
m.state as state, m.prodlot_id as prodlot_id,
sum(m.product_qty*u.factor)::decimal(16,2) as product_qty,
sum(pt.standard_price * m.product_qty * u.factor)::decimal(16,2) as value
from
stock_move m
left join stock_picking p on (m.picking_id=p.id)
left join product_product pp on (m.product_id=pp.id)
left join product_template pt on (pp.product_tmpl_id=pt.id)
left join product_uom u on (m.product_uom=u.id)
left join stock_location l on (m.location_dest_id=l.id)
group by
m.id, m.product_id, m.address_id, m.location_id, m.location_dest_id,
m.prodlot_id, m.date_planned, m.state, l.usage, m.company_id
)
);
""")
report_stock_inventory()

View File

@ -1,25 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem
id="stock.next_id_61"
name="Reporting"
parent="stock.menu_stock_root"/>
<record id="view_stock_tree" model="ir.ui.view">
<field name="name">report.stock.move.tree</field>
<field name="model">report.stock.move</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Stock Orders Statistics">
<field name="date_planned"/>
<field name="day_diff"/>
<tree string="Moves Analysis">
<field name="date_planned" invisible="1"/>
<field name="year" invisible="1" />
<field name="state" invisible="1"/>
<field name="month" invisible="1"/>
<field name="day" invisible="1"/>
<field name="type" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1" context="{'contact_display':'partner'}" />
<field name="picking_id" invisible="1"/>
<field name="location_id" invisible="1"/>
<field name="location_dest_id" invisible="1"/>
<field name="product_id"/>
<field name="partner_id"/>
<field name="product_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="value"/>
<field name="day_diff"/>
<field name="day_diff1"/>
<field name="day_diff2"/>
</tree>
</field>
</record>
@ -29,9 +39,9 @@
<field name="model">report.stock.move</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Stock Moves Statistics" type="bar">
<graph string="Moves Analysis" type="bar">
<field name="product_id"/>
<field name="product_qty"/>
<field name="day_diff2" operator="avg"/>
</graph>
</field>
</record>
@ -41,50 +51,50 @@
<field name="model">report.stock.move</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Stock Move">
<search string="Moves Analysis">
<group>
<filter icon="terp-go-year"
string="This Year"
domain="[('year','=',time.strftime('%%Y'))]"
help="Stock Moves of the year"/>
<filter icon="terp-go-month"
name="month"
name="month"
string="This Month"
domain="[('month','=',time.strftime('%%m'))]"
help="Stock Moves of this month"/>
<filter icon="terp-go-today"
<filter icon="terp-go-today"
string="Today"
separator="1"
domain="[('date_planned','&gt;=', time.strftime('%%Y-%%m-%%d')), ('date_planned','&lt;',(datetime.date.today()-datetime.timedelta(days=1)).strftime('%%Y-%%m-%%d'))]"
domain="[('date_planned','=', time.strftime('%%Y-%%m-%%d'))]"
help="Stock Moves of today"/>
<separator orientation="vertical"/>
<filter string="Future"
icon="terp-camera_test"
domain="[('state','in',('assigned','done','waiting','confirmed'))]"
help = "Future Stock-Moves"/>
<filter string="Done"
name="done"
icon="terp-dialog-close"
domain="[('state','=','done')]"
help = "Completed Stock-Moves"/>
name="done"
icon="terp-dialog-close"
domain="[('state','=','done')]"
help = "Completed Stock-Moves"/>
<filter string="Todo"
icon="terp-camera_test"
domain="[('state','in',('assigned','waiting','confirmed'))]"
help = "Future Stock-Moves"/>
<separator orientation="vertical"/>
<filter icon="terp-go-home" string="Internal" domain="[('location_id.usage','=','internal')]"/>
<filter icon="terp-go-home" string="Scrap" domain="[('location_id.scrap_location','=',1)]"/>
<filter icon="terp-go-home" name="in" string="Receptions" domain="[('type','=','in')]"/>
<filter icon="terp-go-home" name="internal" string="Internals" domain="[('type','=','internal')]"/>
<filter icon="terp-go-home" name="out" string="Packings" domain="[('type','=','out')]"/>
<filter icon="terp-go-home" name="delivery" string="Deliveries" domain="[('type','=','delivery')]"/>
<separator orientation="vertical"/>
<field name="product_id"/>
<field name="partner_id" context="{'contact_display':'partner'}"/>
<field name="date_planned"/>
</group>
<newline/>
<group expand="1" string="Group By..." >
<filter string="Partner" name="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter name="product" string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/>
<group expand="1" string="Group By...">
<filter name="group_partner" string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/>
<filter name="group_product" string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/>
<filter name="group_picking" string="Packing" icon="terp-accessories-archiver" context="{'group_by':'picking_id'}"/>
<separator orientation="vertical"/>
<filter name="src_location" string="Source Location" icon="terp-gtk-jump-to-rtl" context="{'group_by':'location_id'}"/>
<filter string="Dest. Location" icon="terp-gtk-jump-to-ltr" context="{'group_by':'location_dest_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<filter string="Type" name="group_type" icon="terp-gtk-jump-to-rtl" context="{'group_by':'type'}"/>
<filter string="Source Location" name="src_location" icon="terp-gtk-jump-to-rtl" context="{'group_by':'location_id'}"/>
<filter string="Dest. Location" name="dest_location" icon="terp-gtk-jump-to-ltr" context="{'group_by':'location_dest_id'}"/>
<filter string="State" name="group_state" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
<separator orientation="vertical"/>
<filter string="Day" icon="terp-go-month" context="{'group_by':'day'}"/>
<filter string="Month" icon="terp-go-month" context="{'group_by':'date_planned'}"/>
@ -92,9 +102,9 @@
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
<field name="location_id" widget = "selection"/>
<field name="location_dest_id" widget = "selection"/>
<field name="date_planned"/>
<field name="location_id" widget = "selection"/>
<field name="location_dest_id" widget = "selection"/>
<field name="state"/>
</group>
</search>
@ -102,20 +112,110 @@
</record>
<record id="action_stock_move_report" model="ir.actions.act_window">
<field name="name">Stock Moves</field>
<field name="name">Moves Analysis</field>
<field name="res_model">report.stock.move</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="search_view_id" ref="view_stock_search"/>
<field name="context">{'search_default_product':1, 'search_default_src_location':1,'search_default_done':1,'group_by':[], 'group_by_no_leaf':1}</field>
<field name="search_view_id" ref="view_stock_search"/>
<field name="context">{'contact_display': 'partner', 'search_default_month':1, 'search_default_group_product':1,'search_default_done':1,'group_by':[], 'group_by_no_leaf':1}</field>
</record>
<menuitem action="action_stock_move_report" id="menu_action_stock_move_report" parent="next_id_61" sequence="5"/>
<!-- Inventory Control -->
<record id="view_stock_inventory_tree" model="ir.ui.view">
<field name="name">report.stock.inventory.tree</field>
<field name="model">report.stock.inventory</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Inventory Analysis">
<field name="date_planned" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="location_type" invisible="1"/>
<field name="location_id" invisible="1"/>
<field name="partner_id" invisible="1" context="{'contact_display':'partner'}"/>
<field name="product_id" invisible="1"/>
<field name="prodlot_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="product_qty"/>
<field name="value"/>
</tree>
</field>
</record>
<menuitem
id="stock.next_id_61"
name="Reporting"
parent="stock.menu_stock_root" groups="base.group_user"/>
<record id="view_stock_inventory_graph" model="ir.ui.view">
<field name="name">report.stock.inventory.graph</field>
<field name="model">report.stock.inventory</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Inventory Analysis" type="bar">
<field name="product_id"/>
<field name="product_qty"/>
</graph>
</field>
</record>
<record id="view_stock_inventory_search" model="ir.ui.view">
<field name="name">report.stock.inventory.search</field>
<field name="model">report.stock.inventory</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Inventory Analysis">
<group col="16">
<filter string="Real"
name="real"
icon="terp-dialog-close"
domain="[('state','=','done')]"
help="Analysis on real stock."/>
<filter string="Virtual"
icon="terp-camera_test"
domain="[('state','in',('assigned','done','waiting','confirmed'))]"
help = "Analysis including future operations."/>
<separator orientation="vertical"/>
<filter icon="terp-go-home" name="location_type_internal" string="Internal" domain="[('location_type','=','internal')]"/>
<filter icon="terp-go-home" name="location_type_scrap" string="Scrap" domain="[('location_type','=','scrap')]"/>
<separator orientation="vertical"/>
<field name="date_planned"/>
<field name="product_id"/>
<field name="location_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<newline/>
<group expand="1" string="Group By..." >
<filter string="Partner" name="group_partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter name="group_product" string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/>
<separator orientation="vertical"/>
<filter name="group_company" string="Company" context="{'group_by':'company_id'}"/>
<filter name="group_location" string="Location" context="{'group_by':'location_id'}"/>
<filter name="group_lot" string="Lot" context="{'group_by':'prodlot_id'}"/>
<separator orientation="vertical"/>
<filter string="Date" icon="terp-go-month" context="{'group_by':'date_planned'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
<field name="partner_id" context="{'contact_display':'partner'}"/>
<field name="prodlot_id"/>
<field name="state"/>
<field name="location_type"/>
</group>
</search>
</field>
</record>
<record id="action_stock_inventory_report" model="ir.actions.act_window">
<field name="name">Inventory Analysis</field>
<field name="res_model">report.stock.inventory</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="search_view_id" eval="False"/>
<field name="context">{'contact_display': 'partner', 'search_default_real':1, 'search_default_location_type_internal':1,'search_default_group_product':1,'search_default_group_location':1,'group_by':[], 'group_by_no_leaf':1}</field>
</record>
<menuitem action="action_stock_inventory_report" id="menu_action_stock_inventory_report" parent="next_id_61" sequence="5"/>
<menuitem action="action_stock_move_report" id="menu_action_stock_move_report" parent="next_id_61" sequence="5"/>
</data>
</openerp>

View File

@ -1,110 +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 osv import fields,osv
import tools
class report_stock_picking(osv.osv):
_name = "report.stock.picking"
_description = "Stock Picking Report"
_auto = False
_columns = {
'year': fields.char('Year',size=64,required=False, readonly=True),
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'), ('05','May'), ('06','June'),
('07','July'), ('08','August'), ('09','September'), ('10','October'), ('11','November'), ('12','December')],'Month',readonly=True),
'day': fields.char('Day', size=128, readonly=True),
'nbr': fields.integer('# of Lines', readonly=True),
'nbp': fields.integer('# of Picking', readonly=True),
'partner_id':fields.many2one('res.partner', 'Partner', readonly=True),
'product_qty': fields.float('# of Products', readonly=True),
'product_uos_qty': fields.float('# of Products', readonly=True),
'product_id': fields.many2one('product.product', 'Product', readonly=True),
'date': fields.date('Date', readonly=True),
'avg_days_to_deliver': fields.float('Avg Days to Deliver', digits=(16,2), readonly=True, group_operator="avg",
help="Number of Avg Days to deliver"),
'state': fields.selection([('draft', 'Draft'),('auto', 'Waiting'),('confirmed', 'Confirmed'),('assigned', 'Available'),('done', 'Done'),('cancel', 'Cancelled')], 'State'),
'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('delivery', 'Delivery')], 'Shipping Type', required=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
'invoice_state': fields.selection([
("invoiced", "Invoiced"),
("2binvoiced", "To Be Invoiced"),
("none", "Not from Picking")], "Invoice Status",readonly=True),
'min_date': fields.date('Expected Date',help="Expected date for Picking. Default it takes current date"),
'order_date': fields.date('Order Date', help="Date of Order"),
'date_done': fields.date('Date Done', help="Date of completion"),
'location_id': fields.many2one('stock.location', 'Source Location', help="Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations."),
'location_dest_id': fields.many2one('stock.location', 'Dest. Location', help="Location where the system will stock the finished products."),
'max_date': fields.date('Max.Expected Date'),
'product_uos': fields.many2one('product.uom', 'Product UOS'),
'product_uom': fields.many2one('product.uom', 'Product UOM'),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_picking')
cr.execute("""
create or replace view report_stock_picking as (
select
min(sm.id) as id,
date_trunc('day',sp.min_date) as min_date,
date_trunc('day',sp.date) as order_date,
date_trunc('day',sp.date_done) as date_done,
date_trunc('day',sp.max_date) as max_date,
to_char(sp.create_date, 'YYYY') as year,
to_char(sp.create_date, 'MM') as month,
to_char(sp.create_date, 'YYYY-MM-DD') as day,
sp.address_id as partner_id,
to_date(to_char(sp.create_date, 'MM-dd-YYYY'),'MM-dd-YYYY') as date,
count(sm.id) as nbr,
count(distinct sp.id) as nbp,
sum(sm.product_qty) as product_qty,
sum(sm.product_uos_qty) as product_uos_qty,
sm.product_id as product_id,
sm.location_dest_id as location_dest_id,
sm.location_id as location_id,
sp.type,
sm.product_uos,
sm.product_uom,
sp.invoice_state,
sp.company_id as company_id,
avg(extract('epoch' from (sp.date_done-sp.create_date)))/(3600*24) as avg_days_to_deliver,
sp.state
from stock_move as sm
left join stock_picking as sp ON (sm.picking_id=sp.id)
group by sp.type,
sp.create_date,
sp.address_id,
sm.product_id,
to_char(sp.create_date, 'YYYY'),
sm.location_dest_id,
sm.location_id,
to_char(sp.create_date, 'MM'),
to_char(sp.create_date, 'YYYY-MM-DD'),
sm.product_uos,
sm.product_uom,
date_trunc('day',sp.min_date),
date_trunc('day',sp.date),
date_trunc('day',sp.date_done),
date_trunc('day',sp.max_date),
sp.invoice_state,
sp.company_id,
sp.state
)""")
report_stock_picking()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Stock Picking Report
-->
<record id="view_report_report_stock_picking_tree" model="ir.ui.view">
<field name="name">report.stock.picking.tree</field>
<field name="model">report.stock.picking</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Picking">
<field name="year" invisible="1"/>
<field name="month" invisible="1"/>
<field name="day" invisible="1"/>
<field name="date" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="product_id" invisible="1"/>
<field name="min_date" invisible="1"/>
<field name="order_date" invisible="1"/>
<field name="date_done" invisible="1"/>
<field name="max_date" invisible="1"/>
<field name="type" invisible="1"/>
<field name="invoice_state" invisible="1"/>
<field name="state" invisible="1"/>
<field name="product_qty" sum="# of Products" />
<field name="nbp" sum="# of Pickings" />
<field name="nbr" sum="# of Lines" />
<field name="avg_days_to_deliver" avg='Avg Days to Deliver'/>
</tree>
</field>
</record>
<record id="view_report_report_stock_picking_graph" model="ir.ui.view">
<field name="name">report.stock.picking.graph</field>
<field name="model">report.stock.picking</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph orientation="horizontal" string="Picking" type="bar">
<field name="partner_id"/>
<field name="nbr" operator="+"/>
<field name="product_qty" operator="+"/>
<field name="nbp" operator="+"/>
</graph>
</field>
</record>
<record id="view_report_report_stock_picking_filter" model="ir.ui.view">
<field name="name">report.stock.picking.select</field>
<field name="model">report.stock.picking</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search">
<group col="16" colspan="6">
<filter icon="terp-go-year" string=" 365 Days "
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')),('date','&gt;',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%%Y-%%m-%%d'))]"
help="Picking in last 365 days"/>
<filter icon="terp-go-month" string=" 30 Days "
name="month"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=30)).strftime('%%Y-%%m-%%d'))]"
help="Picking in last 30 days"/>
<filter icon="terp-go-week"
string=" 7 Days "
separator="1"
domain="[('date','&lt;=', time.strftime('%%Y-%%m-%%d')), ('date','&gt;',(datetime.date.today()-datetime.timedelta(days=7)).strftime('%%Y-%%m-%%d'))]"
help="Picking during last 7 days"/>
<separator orientation="vertical"/>
<filter string="Todo" icon="terp-gtk-go-back-rtl" domain="[('state','in',('draft','auto','confirmed','assigned'))]"/>
<filter string="Done" icon="terp-dialog-close" domain="[('state','=','done')]"/>
<separator orientation="vertical"/>
<field name="partner_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group>
<newline/>
<group expand="0" string="Group By...">
<filter string="Partner" name="Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
<filter string="Company" icon="terp-go-home" domain="[]" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Shipping Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
<separator orientation="vertical"/>
<filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<filter string="Invoice Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'invoice_state'}"/>
<separator orientation="vertical"/>
<filter string="Day" icon="terp-go-month" domain="[]" context="{'group_by':'day'}"/>
<filter string="Month" icon="terp-go-month" domain="[]" context="{'group_by':'month'}"/>
<filter string="Year" icon="terp-go-year" domain="[]" context="{'group_by':'year'}"/>
</group>
<newline/>
<group expand="0" string="Extended options..." groups="base.group_extended">
<field name="type"/>
<separator orientation="vertical"/>
<field name="min_date"/>
<separator orientation="vertical"/>
<field name="max_date"/>
<newline/>
<field name="invoice_state"/>
<separator orientation="vertical"/>
<field name="order_date"/>
<separator orientation="vertical"/>
<field name="date_done"/>
</group>
</search>
</field>
</record>
<record id="action_report_report_stock_picking" model="ir.actions.act_window">
<field name="name">Picking</field>
<field name="res_model">report.stock.picking</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="view_id" ref="view_report_report_stock_picking_tree"/>
<field name="search_view_id" ref="view_report_report_stock_picking_filter"/>
<field name="context">{'search_default_Partner':1,'search_default_month':1,'group_by_no_leaf':1,'group_by':[]}</field>
</record>
<record model="ir.actions.act_window.view" id="action_report_report_stock_picking_tree">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_report_report_stock_picking_tree"/>
<field name="act_window_id" ref="action_report_report_stock_picking"/>
</record>
<record model="ir.actions.act_window.view" id="action_report_report_stock_picking_graph">
<field name="sequence" eval="2"/>
<field name="view_mode">graph</field>
<field name="view_id" ref="view_report_report_stock_picking_graph"/>
<field name="act_window_id" ref="action_report_report_stock_picking"/>
</record>
<menuitem name="Picking" action="action_report_report_stock_picking" id="menu_report_report_stock_pickings_tree" parent="next_id_61"/>
</data>
</openerp>

View File

@ -2,104 +2,6 @@
<openerp>
<data>
<record id="view_stock_report_prodlots_filter" model="ir.ui.view">
<field name="name">stock.report.prodlots.filter</field>
<field name="model">stock.report.prodlots</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Location">
<group col="10" colspan="4">
<filter icon="terp-go-home" name="internal_locations" string="Internal Locations" domain="[('location_id.usage', '=', 'internal')]" help="Internal Locations"/>
<filter icon="terp-go-home" string="Customer Locations" domain="[('location_id.usage', '=', 'customer')]" help="Customer Locations" />
<filter icon="terp-go-home" string="Supplier Locations" domain="[('location_id.usage', '=', 'supplier')]" help="Supplier Locations" />
<separator orientation="vertical"/>
<field name="location_id"/>
<field name="product_id"/>
</group>
<newline/>
<group expand="1" string="Group By..." colspan="4" col="10">
<filter string="Location" icon="terp-go-home" domain="[]" context="{'group_by':'location_id'}"/>
<filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by':'product_id'}"/>
</group>
</search>
</field>
</record>
<record id="stock_report_prodlots_form" model="ir.ui.view">
<field name="name">stock.report.prodlots.view</field>
<field name="model">stock.report.prodlots</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Stock by Lots">
<field name="location_id"/>
<field name="product_id"/>
<field name="prodlot_id" groups="base.group_extended"/>
<field name="name"/>
</form>
</field>
</record>
<record id="stock_report_prodlots_tree" model="ir.ui.view">
<field name="name">stock.report.prodlots.view</field>
<field name="model">stock.report.prodlots</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Stock by Lots">
<field name="location_id"/>
<field name="product_id"/>
<field name="prodlot_id" groups="base.group_extended"/>
<field name="name"/>
</tree>
</field>
</record>
<record id="stock_report_prodlots_graph" model="ir.ui.view">
<field name="name">stock.report.prodlots.view</field>
<field name="model">stock.report.prodlots</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Stock by Lots" type="bar">
<field name="product_id"/>
<field name="name"/>
</graph>
</field>
</record>
<record id="action_stock_report_prodlots_form" model="ir.actions.act_window">
<field name="name">Inventory by Location</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.report.prodlots</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context">{'full':'1','search_default_internal_locations':1}</field>
<field name="search_view_id" ref="view_stock_report_prodlots_filter" />
</record>
<record id="stock_report_tracklots_tree" model="ir.ui.view">
<field name="name">stock.report.tracklots.view</field>
<field name="model">stock.report.tracklots</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Stock by Lots">
<field name="location_id"/>
<field name="product_id"/>
<field name="tracking_id"/>
<field name="name"/>
</tree>
</field>
</record>
<menuitem
id="next_id_61"
name="Reporting"
parent="stock.menu_stock_root" sequence="5"/>
<!-- <menuitem-->
<!-- id="next_id_62"-->
<!-- name="Traceability"-->
<!-- parent="next_id_61"/>-->
<act_window
context="{'product_id': active_id}"
id="act_stock_product_location_open"
@ -108,28 +10,6 @@
src_model="product.product"
groups="base.group_extended"/>
<act_window
domain="[('location_id', 'child_of', [active_id])]"
id="act_stock_location_2_stock_report_prodlots"
name="Stock by Lots"
res_model="stock.report.prodlots"
src_model="stock.location"
/>
<act_window
domain="[('product_id','=',active_id)]"
id="act_product_product_2_stock_report_prodlots"
name="Stock by Lots"
res_model="stock.report.prodlots"
src_model="product.product"
groups="base.group_extended"/>
<act_window
domain="[('prodlot_id', '=', active_id)]"
id="act_stock_production_lot_2_stock_report_prodlots"
name="Stock" res_model="stock.report.prodlots"
src_model="stock.production.lot"/>
<act_window
domain="[('tracking_id', '=', active_id)]"
id="act_stock_tracking_lot_2_stock_report_tracklots"
@ -228,12 +108,5 @@
</record>
<menuitem action="action_location_tree_3" id="menu_action_location_tree_3" parent="next_id_61" sequence="1"/>
<menuitem
action="action_stock_report_prodlots_form"
id="menu_stock_report_prodlots"
parent="next_id_61" sequence="10"/>
</data>
</openerp>