2010-03-10 09:41:29 +00:00
# -*- 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/>.
#
##############################################################################
2012-12-06 14:56:32 +00:00
from openerp import tools
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2012-12-06 14:56:32 +00:00
from openerp . osv import fields , osv
2010-03-10 09:41:29 +00:00
class account_invoice_report ( osv . osv ) :
_name = " account.invoice.report "
_description = " Invoices Statistics "
_auto = False
_rec_name = ' date '
2012-10-15 11:25:30 +00:00
def _compute_amounts_in_user_currency ( self , cr , uid , ids , field_names , args , context = None ) :
""" Compute the amounts in the currency of the user
"""
if context is None :
context = { }
currency_obj = self . pool . get ( ' res.currency ' )
currency_rate_obj = self . pool . get ( ' res.currency.rate ' )
2014-10-27 15:27:53 +00:00
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
user_currency_id = user . company_id . currency_id . id
currency_rate_id = currency_rate_obj . search (
cr , uid , [
( ' rate ' , ' = ' , 1 ) ,
' | ' ,
2015-02-10 08:41:08 +00:00
( ' currency_id.company_id ' , ' = ' , user . company_id . id ) ,
2014-10-27 15:27:53 +00:00
( ' currency_id.company_id ' , ' = ' , False )
] , limit = 1 , context = context ) [ 0 ]
2012-10-15 11:25:30 +00:00
base_currency_id = currency_rate_obj . browse ( cr , uid , currency_rate_id , context = context ) . currency_id . id
res = { }
ctx = context . copy ( )
for item in self . browse ( cr , uid , ids , context = context ) :
ctx [ ' date ' ] = item . date
price_total = currency_obj . compute ( cr , uid , base_currency_id , user_currency_id , item . price_total , context = ctx )
price_average = currency_obj . compute ( cr , uid , base_currency_id , user_currency_id , item . price_average , context = ctx )
residual = currency_obj . compute ( cr , uid , base_currency_id , user_currency_id , item . residual , context = ctx )
res [ item . id ] = {
' user_currency_price_total ' : price_total ,
' user_currency_price_average ' : price_average ,
' user_currency_residual ' : residual ,
}
return res
2010-03-10 09:41:29 +00:00
_columns = {
' date ' : fields . date ( ' Date ' , readonly = True ) ,
2010-08-14 03:25:58 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , readonly = True ) ,
2014-08-21 10:53:47 +00:00
' product_qty ' : fields . float ( ' Product Quantity ' , readonly = True ) ,
2012-04-25 07:08:25 +00:00
' uom_name ' : fields . char ( ' Reference Unit of Measure ' , size = 128 , readonly = True ) ,
2010-06-16 11:51:39 +00:00
' payment_term ' : fields . many2one ( ' account.payment.term ' , ' Payment Term ' , readonly = True ) ,
' period_id ' : fields . many2one ( ' account.period ' , ' Force Period ' , domain = [ ( ' state ' , ' <> ' , ' done ' ) ] , readonly = True ) ,
2010-10-09 16:01:43 +00:00
' fiscal_position ' : fields . many2one ( ' account.fiscal.position ' , ' Fiscal Position ' , readonly = True ) ,
2010-04-07 09:07:16 +00:00
' currency_id ' : fields . many2one ( ' res.currency ' , ' Currency ' , readonly = True ) ,
2010-05-31 10:18:33 +00:00
' categ_id ' : fields . many2one ( ' product.category ' , ' Category of Product ' , readonly = True ) ,
2010-06-16 11:51:39 +00:00
' journal_id ' : fields . many2one ( ' account.journal ' , ' Journal ' , readonly = True ) ,
2010-08-14 03:25:58 +00:00
' partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' , readonly = True ) ,
2013-04-22 15:34:49 +00:00
' commercial_partner_id ' : fields . many2one ( ' res.partner ' , ' Partner Company ' , help = " Commercial Entity " ) ,
2010-08-14 03:25:58 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , readonly = True ) ,
2012-05-04 12:13:26 +00:00
' user_id ' : fields . many2one ( ' res.users ' , ' Salesperson ' , readonly = True ) ,
2010-08-14 03:25:58 +00:00
' price_total ' : fields . float ( ' Total Without Tax ' , readonly = True ) ,
2012-10-15 11:25:30 +00:00
' user_currency_price_total ' : fields . function ( _compute_amounts_in_user_currency , string = " Total Without Tax " , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) , multi = " _compute_amounts " ) ,
2010-08-31 07:01:48 +00:00
' price_average ' : fields . float ( ' Average Price ' , readonly = True , group_operator = " avg " ) ,
2012-10-15 11:25:30 +00:00
' user_currency_price_average ' : fields . function ( _compute_amounts_in_user_currency , string = " Average Price " , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) , multi = " _compute_amounts " ) ,
2010-09-08 09:24:35 +00:00
' currency_rate ' : fields . float ( ' Currency Rate ' , readonly = True ) ,
2014-08-21 10:53:47 +00:00
' nbr ' : fields . integer ( ' # of Invoices ' , readonly = True ) , # TDE FIXME master: rename into nbr_lines
2010-03-10 11:05:01 +00:00
' type ' : fields . selection ( [
( ' out_invoice ' , ' Customer Invoice ' ) ,
( ' in_invoice ' , ' Supplier Invoice ' ) ,
( ' out_refund ' , ' Customer Refund ' ) ,
( ' in_refund ' , ' Supplier Refund ' ) ,
] , ' Type ' , readonly = True ) ,
2010-03-10 09:41:29 +00:00
' state ' : fields . selection ( [
( ' draft ' , ' Draft ' ) ,
( ' proforma ' , ' Pro-forma ' ) ,
( ' proforma2 ' , ' Pro-forma ' ) ,
( ' open ' , ' Open ' ) ,
( ' paid ' , ' Done ' ) ,
( ' cancel ' , ' Cancelled ' )
2012-10-12 11:42:58 +00:00
] , ' Invoice Status ' , readonly = True ) ,
2010-04-29 08:27:53 +00:00
' date_due ' : fields . date ( ' Due Date ' , readonly = True ) ,
' account_id ' : fields . many2one ( ' account.account ' , ' Account ' , readonly = True ) ,
2011-04-13 07:32:11 +00:00
' account_line_id ' : fields . many2one ( ' account.account ' , ' Account Line ' , readonly = True ) ,
2010-07-19 13:47:09 +00:00
' partner_bank_id ' : fields . many2one ( ' res.partner.bank ' , ' Bank Account ' , readonly = True ) ,
2010-08-14 03:25:58 +00:00
' residual ' : fields . float ( ' Total Residual ' , readonly = True ) ,
2012-10-15 11:25:30 +00:00
' user_currency_residual ' : fields . function ( _compute_amounts_in_user_currency , string = " Total Residual " , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) , multi = " _compute_amounts " ) ,
2013-05-14 12:05:18 +00:00
' country_id ' : fields . many2one ( ' res.country ' , ' Country of the Partner Company ' ) ,
2010-03-10 09:41:29 +00:00
}
_order = ' date desc '
2012-11-21 10:19:09 +00:00
2014-07-08 13:32:38 +00:00
_depends = {
' account.invoice ' : [
' account_id ' , ' amount_total ' , ' commercial_partner_id ' , ' company_id ' ,
' currency_id ' , ' date_due ' , ' date_invoice ' , ' fiscal_position ' ,
' journal_id ' , ' partner_bank_id ' , ' partner_id ' , ' payment_term ' ,
' period_id ' , ' residual ' , ' state ' , ' type ' , ' user_id ' ,
] ,
' account.invoice.line ' : [
' account_id ' , ' invoice_id ' , ' price_subtotal ' , ' product_id ' ,
' quantity ' , ' uos_id ' ,
] ,
' product.product ' : [ ' product_tmpl_id ' ] ,
' product.template ' : [ ' categ_id ' ] ,
' product.uom ' : [ ' category_id ' , ' factor ' , ' name ' , ' uom_type ' ] ,
' res.currency.rate ' : [ ' currency_id ' , ' name ' ] ,
' res.partner ' : [ ' country_id ' ] ,
}
2012-11-21 10:19:09 +00:00
def _select ( self ) :
select_str = """
2014-01-29 16:03:48 +00:00
SELECT sub . id , sub . date , sub . product_id , sub . partner_id , sub . country_id ,
2012-11-29 10:12:28 +00:00
sub . payment_term , sub . period_id , sub . uom_name , sub . currency_id , sub . journal_id ,
2014-08-22 11:53:46 +00:00
sub . fiscal_position , sub . user_id , sub . company_id , sub . nbr , sub . type , sub . state ,
2012-11-29 10:12:28 +00:00
sub . categ_id , sub . date_due , sub . account_id , sub . account_line_id , sub . partner_bank_id ,
sub . product_qty , sub . price_total / cr . rate as price_total , sub . price_average / cr . rate as price_average ,
2013-04-22 15:34:49 +00:00
cr . rate as currency_rate , sub . residual / cr . rate as residual , sub . commercial_partner_id as commercial_partner_id
2012-11-29 13:48:42 +00:00
"""
return select_str
def _sub_select ( self ) :
select_str = """
2012-11-29 10:12:28 +00:00
SELECT min ( ail . id ) AS id ,
ai . date_invoice AS date ,
ail . product_id , ai . partner_id , ai . payment_term , ai . period_id ,
2015-02-04 19:22:07 +00:00
u2 . name AS uom_name ,
2012-11-29 10:12:28 +00:00
ai . currency_id , ai . journal_id , ai . fiscal_position , ai . user_id , ai . company_id ,
2014-08-22 11:53:46 +00:00
count ( ail . * ) AS nbr ,
2012-11-29 10:12:28 +00:00
ai . type , ai . state , pt . categ_id , ai . date_due , ai . account_id , ail . account_id AS account_line_id ,
ai . partner_bank_id ,
SUM ( CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
2015-01-31 18:10:22 +00:00
THEN ( - ail . quantity ) / u . factor * u2 . factor
ELSE ail . quantity / u . factor * u2 . factor
2012-11-29 10:12:28 +00:00
END ) AS product_qty ,
SUM ( CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
THEN - ail . price_subtotal
ELSE ail . price_subtotal
END ) AS price_total ,
CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
THEN SUM ( - ail . price_subtotal )
ELSE SUM ( ail . price_subtotal )
END / CASE
2015-02-04 19:22:07 +00:00
WHEN SUM ( ail . quantity / u . factor * u2 . factor ) < > 0 : : numeric
2012-11-29 10:12:28 +00:00
THEN CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
2015-02-04 19:22:07 +00:00
THEN SUM ( ( - ail . quantity ) / u . factor * u2 . factor )
ELSE SUM ( ail . quantity / u . factor * u2 . factor )
2012-11-29 10:12:28 +00:00
END
ELSE 1 : : numeric
END AS price_average ,
CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
THEN - ai . residual
ELSE ai . residual
2015-02-11 12:10:54 +00:00
END / ( SELECT count ( * ) FROM account_invoice_line l where invoice_id = ai . id ) *
2015-02-11 15:39:11 +00:00
count ( * ) AS residual ,
2013-05-14 12:05:18 +00:00
ai . commercial_partner_id as commercial_partner_id ,
partner . country_id
2012-11-29 13:48:42 +00:00
"""
return select_str
def _from ( self ) :
from_str = """
2012-11-29 10:12:28 +00:00
FROM account_invoice_line ail
JOIN account_invoice ai ON ai . id = ail . invoice_id
2013-05-14 12:05:18 +00:00
JOIN res_partner partner ON ai . commercial_partner_id = partner . id
2012-11-29 10:12:28 +00:00
LEFT JOIN product_product pr ON pr . id = ail . product_id
left JOIN product_template pt ON pt . id = pr . product_tmpl_id
LEFT JOIN product_uom u ON u . id = ail . uos_id
2015-02-04 19:22:07 +00:00
LEFT JOIN product_uom u2 ON u2 . id = pt . uom_id
2012-11-29 13:48:42 +00:00
"""
return from_str
def _group_by ( self ) :
group_by_str = """
2012-11-29 10:12:28 +00:00
GROUP BY ail . product_id , ai . date_invoice , ai . id ,
2015-02-04 19:22:07 +00:00
ai . partner_id , ai . payment_term , ai . period_id , u2 . name , u2 . id , ai . currency_id , ai . journal_id ,
2012-11-29 10:12:28 +00:00
ai . fiscal_position , ai . user_id , ai . company_id , ai . type , ai . state , pt . categ_id ,
ai . date_due , ai . account_id , ail . account_id , ai . partner_bank_id , ai . residual ,
2015-02-04 19:22:07 +00:00
ai . amount_total , ai . commercial_partner_id , partner . country_id
2012-11-29 13:48:42 +00:00
"""
return group_by_str
def init ( self , cr ) :
# self._table = account_invoice_report
tools . drop_view_if_exists ( cr , self . _table )
cr . execute ( """ CREATE or REPLACE VIEW %s as (
2015-04-29 21:56:58 +00:00
WITH currency_rate ( currency_id , rate , date_start , date_end ) AS (
SELECT r . currency_id , r . rate , r . name AS date_start ,
( SELECT name FROM res_currency_rate r2
WHERE r2 . name > r . name AND
r2 . currency_id = r . currency_id
ORDER BY r2 . name ASC
LIMIT 1 ) AS date_end
FROM res_currency_rate r
)
2012-11-29 13:48:42 +00:00
% s
FROM (
% s % s % s
2012-11-29 10:12:28 +00:00
) AS sub
2015-04-29 21:56:58 +00:00
JOIN currency_rate cr ON
( cr . currency_id = sub . currency_id AND
cr . date_start < = COALESCE ( sub . date , NOW ( ) ) AND
( cr . date_end IS NULL OR cr . date_end > COALESCE ( sub . date , NOW ( ) ) ) )
2012-11-29 13:48:42 +00:00
) """ % (
2014-08-21 10:53:47 +00:00
self . _table ,
2012-11-29 13:48:42 +00:00
self . _select ( ) , self . _sub_select ( ) , self . _from ( ) , self . _group_by ( ) ) )
2010-08-14 03:25:58 +00:00
2010-09-08 09:24:35 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: