diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 1b378e15e93..d1726d164b6 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -98,6 +98,7 @@ module named account_voucher. 'wizard/account_reconcile_view.xml', 'wizard/account_reconcile_partner_process_view.xml', 'wizard/account_automatic_reconcile_view.xml', + 'wizard/account_financial_report_view.xml', 'project/wizard/project_account_analytic_line_view.xml', 'account_end_fy.xml', 'account_invoice_view.xml', diff --git a/addons/account/account.py b/addons/account/account.py index 1412cc9b61f..61e1fb021a9 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -2637,6 +2637,79 @@ class account_fiscal_position_account_template(osv.osv): account_fiscal_position_account_template() +class account_financial_report(osv.osv): + _name = "account.financial.report" + _description = "Account Report" + + def _get_level(self, cr, uid, ids, field_name, arg, context=None): + res = {} + for report in self.browse(cr, uid, ids, context=context): + level = 0 + if report.parent_id: + level = report.parent_id.level + 1 + res[report.id] = level + return res + + def _get_children_by_order(self, cr, uid, ids, context=None): + res = [] + for id in ids: + res.append(id) + ids2 = self.search(cr, uid, [('parent_id', '=', id)], order='sequence ASC', context=context) + res += self._get_children_by_order(cr, uid, ids2, context=context) + return res + + def _get_balance(self, cr, uid, ids, name, args, context=None): + res = {} + res_all = {} + for report in self.browse(cr, uid, ids, context=context): + balance = 0.0 + if report.id in res_all: + balance = res_all[report.id] + elif report.type == 'accounts': + # it's the sum of balance of the linked accounts + for a in report.account_ids: + balance += a.balance + elif report.type == 'account_report' and report.account_report_id: + # it's the amount of the linked report + res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context) + res_all.update(res2) + for key, value in res2.items(): + balance += value + elif report.type == 'sum': + # it's the sum of balance of the children of this account.report + #for child in report.children_ids: + res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], 'balance', False, context=context) + res_all.update(res2) + for key, value in res2.items(): + balance += value + res[report.id] = balance + res_all[report.id] = balance + return res + + _columns = { + 'name': fields.char('Report Name', size=128, required=True), + 'parent_id': fields.many2one('account.financial.report', 'Parent'), + 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'), + 'sequence': fields.integer('Sequence'), + 'type': fields.selection([ + ('sum','Sum'), + ('accounts','Accounts'), + ('account_report','Account Report'), + ],'Type'), + 'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'), + 'note': fields.text('Notes'), + 'account_report_id': fields.many2one('account.financial.report', 'Account Report'), + 'balance': fields.function(_get_balance, 'Balance'), + 'display_detail': fields.boolean('Display the account list'), + 'level': fields.function(_get_level, string='Level', store=True, type='integer'), + } + + _defaults = { + 'type': 'sum', + } + +account_financial_report() + # Multi charts of Accounts wizard class wizard_multi_charts_accounts(osv.osv_memory): diff --git a/addons/account/account_menuitem.xml b/addons/account/account_menuitem.xml index 062e1f6382b..89538603ae7 100644 --- a/addons/account/account_menuitem.xml +++ b/addons/account/account_menuitem.xml @@ -30,6 +30,7 @@ + + + + + account.financial.report.form + account.financial.report + form + +
+ + + + + + + + + + + + +
+ + + account.financial.report.tree + account.financial.report + tree + + + + + + + + + + + + account.financial.report.search + account.financial.report + search + + + + + + + + + + + + + + + + + + + Account Reports + ir.actions.act_window + account.financial.report + form + tree,form + + + Makes a generic system to draw financial reports easily. + + + + + + account.report.hierarchy + account.financial.report + tree + children_ids + + + + + + + + + + + Account Reports Hierarchy + account.financial.report + tree + + [('parent_id','=',False)] + + + + diff --git a/addons/account/report/__init__.py b/addons/account/report/__init__.py index 7c09027f3ca..c9e49c2e02d 100644 --- a/addons/account/report/__init__.py +++ b/addons/account/report/__init__.py @@ -42,6 +42,7 @@ import account_analytic_entries_report import account_balance_sheet import account_profit_loss import account_treasury_report +import account_financial_report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/report/account_financial_report.py b/addons/account/report/account_financial_report.py new file mode 100644 index 00000000000..6b0ada74708 --- /dev/null +++ b/addons/account/report/account_financial_report.py @@ -0,0 +1,90 @@ +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +import time + +from report import report_sxw +from common_report_header import common_report_header +from tools.translate import _ + +class report_account_common(report_sxw.rml_parse, common_report_header): + + def __init__(self, cr, uid, name, context=None): + super(report_account_common, self).__init__(cr, uid, name, context=context) + self.localcontext.update( { + 'get_lines': self.get_lines, + 'time': time, + 'get_fiscalyear': self._get_fiscalyear, + 'get_account': self._get_account, + 'get_start_period': self.get_start_period, + 'get_end_period': self.get_end_period, + 'get_filter': self._get_filter, + 'get_start_date':self._get_start_date, + 'get_end_date':self._get_end_date, + }) + self.context = context + + def set_context(self, objects, data, ids, report_type=None): + new_ids = ids + if (data['model'] == 'ir.ui.menu'): + new_ids = 'chart_account_id' in data['form'] and [data['form']['chart_account_id']] or [] + objects = self.pool.get('account.account').browse(self.cr, self.uid, new_ids) + return super(report_account_common, self).set_context(objects, data, new_ids, report_type=report_type) + + def get_lines(self, data): + lines = [] + account_obj = self.pool.get('account.account') + currency_obj = self.pool.get('res.currency') + ids2 = self.pool.get('account.financial.report')._get_children_by_order(self.cr, self.uid, [data['form']['account_report_id'][0]], context=data['form']['used_context']) + for report in self.pool.get('account.financial.report').browse(self.cr, self.uid, ids2, context=data['form']['used_context']): + vals = { + 'name': report.name, + 'balance': report.balance, + 'type': 'report', + 'level': report.level, + } + if data['form']['enable_filter']: + vals['balance_cmp'] = self.pool.get('account.financial.report').browse(self.cr, self.uid, report.id, context=data['form']['comparison_context']).balance + lines.append(vals) + if report.type == 'accounts' and report.display_detail and report.account_ids: + account_ids = account_obj._get_children_and_consol(self.cr, self.uid, [x.id for x in report.account_ids]) + for account in account_obj.browse(self.cr, self.uid, account_ids, context=data['form']['used_context']): + if account.type != 'view': + flag = False + vals = { + 'name': account.code + ' ' + account.name, + 'balance': account.balance, + 'type': 'account', + 'level': 6, + 'account_type': account.type, + } + if not currency_obj.is_zero(self.cr, self.uid, account.company_id.currency_id, vals['balance']): + flag = True + if data['form']['enable_filter']: + vals['balance_cmp'] = account_obj.browse(self.cr, self.uid, account.id, context=data['form']['comparison_context']).balance + if not currency_obj.is_zero(self.cr, self.uid, account.company_id.currency_id, vals['balance_cmp']): + flag = True + if flag: + lines.append(vals) + return lines + +report_sxw.report_sxw('report.account.financial.report', 'account.financial.report', + 'addons/account/report/account_financial_report.rml', parser=report_account_common, header='internal') + diff --git a/addons/account/report/account_financial_report.rml b/addons/account/report/account_financial_report.rml new file mode 100644 index 00000000000..8dd92335266 --- /dev/null +++ b/addons/account/report/account_financial_report.rml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ data['form']['account_report_id'][1] ]] + + + + + + + + + + Chart of Account + Fiscal Year + Filter By [[ get_filter(data)!='No Filter' and get_filter(data) ]] + + + [[ get_account(data) or removeParentNode('para') ]] + [[ get_fiscalyear(data) or '' ]] + [[ get_filter(data)=='No Filter' and get_filter(data) or removeParentNode('para') ]] + [[ get_filter(data)=='Date' or removeParentNode('blockTable') ]] + + Start Date + End Date + + + [[ formatLang(get_start_date(data),date=True) ]] + [[ formatLang(get_end_date(data),date=True) ]] + + + [[ get_filter(data)=='Periods' or removeParentNode('blockTable') ]] + + Start Period + End Period + + + [[ get_start_period(data) or removeParentNode('para') ]] + [[ get_end_period(data) or removeParentNode('para') ]] + + + + + + + + + + + + + [[ data['form']['enable_filter'] == 0 or removeParentNode('blockTable') ]] + + + Name + + + Balance + + + + [[ repeatIn(get_lines(data), 'a') ]] + [[ (a.get('level') <> 0) or removeParentNode('tr') ]] + [[ setTag('tr','tr',{'style': 'Table'+str(min(3,'level' in a and a.get('level') or 1))}) ]] + [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_name'}) ]] [[ a.get('name') ]] + [[ a.get('level') == 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance'))]] [[company.currency_id.symbol]] + [[ a.get('level') <> 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance'))]] [[company.currency_id.symbol]] + + + + + + + [[ data['form']['enable_filter'] == 1 or removeParentNode('blockTable') ]] + + + Name + + + Balance + + + [[ data['form']['label_filter'] ]] + + + + [[ repeatIn(get_lines(data), 'a') ]] + [[ (a.get('level') <> 0) or removeParentNode('tr') ]] + [[ setTag('tr','tr',{'style': 'Table'+str(min(3,'level' in a and a.get('level') or 1))}) ]] + [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_name'}) ]] [[ a.get('name') ]] + [[ a.get('level') == 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance'))]] [[company.currency_id.symbol]] + [[ a.get('level') <> 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance'))]] [[company.currency_id.symbol]] + [[ a.get('level') == 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance_cmp'))]] [[company.currency_id.symbol]] + [[ a.get('level') <> 4 or removeParentNode('td') ]][[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a['level']))+'_balance'}) ]][[ formatLang(a.get('balance_cmp'))]] [[company.currency_id.symbol]] + + + + + + + diff --git a/addons/account/security/ir.model.access.csv b/addons/account/security/ir.model.access.csv index cd945a2248d..442898c9092 100644 --- a/addons/account/security/ir.model.access.csv +++ b/addons/account/security/ir.model.access.csv @@ -127,4 +127,7 @@ "access_account_sequence_fiscal_year_sale_user","account.sequence.fiscalyear.sale.user","model_account_sequence_fiscalyear","base.group_sale_salesman",1,1,1,0 "access_account_sequence_fiscal_year_sale_manager","account.sequence.fiscalyear.sale.manager","model_account_sequence_fiscalyear","base.group_sale_manager",1,1,1,1 "access_account_treasury_report_manager","account.treasury.report.manager","model_account_treasury_report","account.group_account_manager",1,0,0,0 +"access_account_financial_report","account.financial.report","model_account_financial_report","account.group_account_user",1,1,1,1 +"access_account_financial_report_invoice","account.financial.report invoice","model_account_financial_report","account.group_account_invoice",1,0,0,0 +"access_account_financial_report_manager","account.financial.report","model_account_financial_report","account.group_account_manager",1,1,1,1 diff --git a/addons/account/wizard/__init__.py b/addons/account/wizard/__init__.py index caed6fc3977..d82eff62142 100644 --- a/addons/account/wizard/__init__.py +++ b/addons/account/wizard/__init__.py @@ -47,6 +47,7 @@ import account_open_closed_fiscalyear import account_invoice_state import account_chart import account_tax_chart +import account_financial_report #TODO: remove this file no moe used # also remove related view fiel diff --git a/addons/account/wizard/account_financial_report.py b/addons/account/wizard/account_financial_report.py new file mode 100644 index 00000000000..de9cae3a00c --- /dev/null +++ b/addons/account/wizard/account_financial_report.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +from osv import fields, osv + +class accounting_report(osv.osv_memory): + _name = "accounting.report" + _inherit = "account.common.report" + _description = "Accounting Report" + + _columns = { + 'enable_filter': fields.boolean('Enable Comparison'), + 'account_report_id': fields.many2one('account.financial.report', 'Account Reports', required=True), + 'label_filter': fields.char('Column Label', size=32, help="This label will be displayed on report to show the balance computed for the given comparison filter."), + 'fiscalyear_id_cmp': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Keep empty for all open fiscal year'), + 'filter_cmp': fields.selection([('filter_no', 'No Filters'), ('filter_date', 'Date'), ('filter_period', 'Periods')], "Filter by", required=True), + 'period_from_cmp': fields.many2one('account.period', 'Start Period'), + 'period_to_cmp': fields.many2one('account.period', 'End Period'), + 'date_from_cmp': fields.date("Start Date"), + 'date_to_cmp': fields.date("End Date"), + } + + _defaults = { + 'filter_cmp': 'filter_no', + 'target_move': 'posted', + } + + def _build_comparison_context(self, cr, uid, ids, data, context=None): + if context is None: + context = {} + result = {} + result['fiscalyear'] = 'fiscalyear_id_cmp' in data['form'] and data['form']['fiscalyear_id_cmp'] or False + result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False + result['chart_account_id'] = 'chart_account_id' in data['form'] and data['form']['chart_account_id'] or False + if data['form']['filter_cmp'] == 'filter_date': + result['date_from'] = data['form']['date_from_cmp'] + result['date_to'] = data['form']['date_to_cmp'] + elif data['form']['filter_cmp'] == 'filter_period': + if not data['form']['period_from_cmp'] or not data['form']['period_to_cmp']: + raise osv.except_osv(_('Error'),_('Select a starting and an ending period')) + result['period_from'] = data['form']['period_from_cmp'] + result['period_to'] = data['form']['period_to_cmp'] + return result + + def check_report(self, cr, uid, ids, context=None): + if context is None: + context = {} + res = super(accounting_report, self).check_report(cr, uid, ids, context=context) + data = {} + data['form'] = self.read(cr, uid, ids, ['account_report_id', 'date_from_cmp', 'date_to_cmp', 'fiscalyear_id_cmp', 'journal_ids', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'chart_account_id', 'target_move'], context=context)[0] + for field in ['fiscalyear_id_cmp', 'chart_account_id', 'period_from_cmp', 'period_to_cmp', 'account_report_id']: + if isinstance(data['form'][field], tuple): + data['form'][field] = data['form'][field][0] + comparison_context = self._build_comparison_context(cr, uid, ids, data, context=context) + res['datas']['form']['comparison_context'] = comparison_context + return res + + def _print_report(self, cr, uid, ids, data, context=None): + data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter'], context=context)[0]) + return { + 'type': 'ir.actions.report.xml', + 'report_name': 'account.financial.report', + 'datas': data, + } + +accounting_report() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/wizard/account_financial_report_view.xml b/addons/account/wizard/account_financial_report_view.xml new file mode 100644 index 00000000000..2083fd0ed53 --- /dev/null +++ b/addons/account/wizard/account_financial_report_view.xml @@ -0,0 +1,52 @@ + + + + + + Accounting Report + accounting.report + form + + + + + + + + + + + + + + + + + + + + + + + + + + Financial Report + accounting.report + ir.actions.act_window + form + form + + new + + + + + +