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 ' )
user_currency_id = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context ) . company_id . currency_id . id
currency_rate_id = currency_rate_obj . search ( cr , uid , [ ( ' rate ' , ' = ' , 1 ) ] , limit = 1 , context = context ) [ 0 ]
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 ) ,
2010-03-10 09:41:29 +00:00
' product_qty ' : fields . float ( ' Qty ' , 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 ) ,
2010-03-10 09:41:29 +00:00
' nbr ' : fields . integer ( ' # of Lines ' , readonly = True ) ,
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
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 ,
sub . fiscal_position , sub . user_id , sub . company_id , sub . nbr , sub . type , sub . state ,
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 ,
CASE
WHEN u . uom_type : : text < > ' reference ' : : text
THEN ( SELECT product_uom . name
FROM product_uom
WHERE product_uom . uom_type : : text = ' reference ' : : text
AND product_uom . active
AND product_uom . category_id = u . category_id LIMIT 1 )
ELSE u . name
END AS uom_name ,
ai . currency_id , ai . journal_id , ai . fiscal_position , ai . user_id , ai . company_id ,
count ( ail . * ) AS nbr ,
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 ] )
THEN ( - ail . quantity ) / u . factor
ELSE ail . quantity / u . factor
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
WHEN SUM ( ail . quantity / u . factor ) < > 0 : : numeric
THEN CASE
WHEN ai . type : : text = ANY ( ARRAY [ ' out_refund ' : : character varying : : text , ' in_invoice ' : : character varying : : text ] )
THEN SUM ( ( - ail . quantity ) / u . factor )
ELSE SUM ( ail . quantity / u . factor )
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
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 ,
ai . partner_id , ai . payment_term , ai . period_id , u . name , ai . currency_id , ai . journal_id ,
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 ,
2013-05-14 12:05:18 +00:00
ai . amount_total , u . uom_type , u . category_id , 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 (
% s
FROM (
% s % s % s
2012-11-29 10:12:28 +00:00
) AS sub
JOIN res_currency_rate cr ON ( cr . currency_id = sub . currency_id )
WHERE
cr . id IN ( SELECT id
FROM res_currency_rate cr2
WHERE ( cr2 . currency_id = sub . currency_id )
2013-03-21 18:55:41 +00:00
AND ( ( sub . date IS NOT NULL AND cr2 . name < = sub . date )
OR ( sub . date IS NULL AND cr2 . name < = NOW ( ) ) )
2012-11-29 13:48:42 +00:00
ORDER BY name DESC LIMIT 1 )
) """ % (
2012-11-21 10:19:09 +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: