X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22brouteur%22%2C%20%28%24id_rubrique%20?a=blobdiff_plain;f=wizard%2Fbalance_common.py;fp=wizard%2Fbalance_common.py;h=5225b671e5bef16c6e95b0440ee2bfb486d644c2;hb=cddef38e342c880228694525c45df3f7dd8c2148;hp=0000000000000000000000000000000000000000;hpb=bffd331c220385010fe9abad9e228fc2004a293a;p=burette%2Faccount_financial_report_webkit.git diff --git a/wizard/balance_common.py b/wizard/balance_common.py new file mode 100644 index 0000000..5225b67 --- /dev/null +++ b/wizard/balance_common.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com) +# +# Author: Guewen Baconnier (Camptocamp) +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +import time + +from lxml import etree +from datetime import datetime +from openerp.osv import fields, orm +from openerp.tools.translate import _ + + +def previous_year_date(date, nb_prev=1): + if not date: + return False + parsed_date = datetime.strptime(date, '%Y-%m-%d') + previous_date = datetime(year=parsed_date.year - nb_prev, + month=parsed_date.month, + day=parsed_date.day) + return previous_date + + +class AccountBalanceCommonWizard(orm.TransientModel): + """Will launch trial balance report and pass required args""" + + _inherit = "account.common.account.report" + _name = "account.common.balance.report" + _description = "Common Balance Report" + + # an update module should be done if changed + # in order to create fields in db + COMPARISON_LEVEL = 3 + + COMPARE_SELECTION = [('filter_no', 'No Comparison'), + ('filter_year', 'Fiscal Year'), + ('filter_date', 'Date'), + ('filter_period', 'Periods'), + ('filter_opening', 'Opening Only')] + + M2O_DYNAMIC_FIELDS = [f % index for f in ["comp%s_fiscalyear_id", + "comp%s_period_from", + "comp%s_period_to"] + for index in range(COMPARISON_LEVEL)] + SIMPLE_DYNAMIC_FIELDS = [f % index for f in ["comp%s_filter", + "comp%s_date_from", + "comp%s_date_to"] + for index in range(COMPARISON_LEVEL)] + DYNAMIC_FIELDS = M2O_DYNAMIC_FIELDS + SIMPLE_DYNAMIC_FIELDS + + def _get_account_ids(self, cr, uid, context=None): + res = False + if context.get('active_model', False) == 'account.account' and context.get('active_ids', False): + res = context['active_ids'] + return res + + _columns = { + 'account_ids': fields.many2many('account.account', string='Filter on accounts', + help="Only selected accounts will be printed. Leave empty to print all accounts."), + 'filter': fields.selection([('filter_no', 'No Filters'), + ('filter_date', 'Date'), + ('filter_period', 'Periods'), + ('filter_opening', 'Opening Only')], + "Filter by", + required=True, + help='Filter by date: no opening balance will be displayed. ' + '(opening balance can only be computed based on period to be correct).'), + } + + for index in range(COMPARISON_LEVEL): + _columns.update( + {"comp%s_filter" % index: fields.selection(COMPARE_SELECTION, string='Compare By', required=True), + "comp%s_fiscalyear_id" % index: fields.many2one('account.fiscalyear', 'Fiscal Year'), + "comp%s_period_from" % index: fields.many2one('account.period', 'Start Period'), + "comp%s_period_to" % index: fields.many2one('account.period', 'End Period'), + "comp%s_date_from" % index: fields.date("Start Date"), + "comp%s_date_to" % index: fields.date("End Date")}) + + _defaults = { + 'account_ids': _get_account_ids, + } + + def _check_fiscalyear(self, cr, uid, ids, context=None): + obj = self.read(cr, uid, ids[0], ['fiscalyear_id', 'filter'], context=context) + if not obj['fiscalyear_id'] and obj['filter'] == 'filter_no': + return False + return True + + _constraints = [ + (_check_fiscalyear, 'When no Fiscal year is selected, you must choose to filter by periods or by date.', ['filter']), + ] + + def default_get(self, cr, uid, fields, context=None): + """ + To get default values for the object. + + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param fields: List of fields for which we want default values + @param context: A standard dictionary + + @return: A dictionary which of fields with values. + + """ + res = super(AccountBalanceCommonWizard, self).default_get(cr, uid, fields, context=context) + for index in range(self.COMPARISON_LEVEL): + field = "comp%s_filter" % (index,) + if not res.get(field, False): + res[field] = 'filter_no' + return res + + def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): + res = super(AccountBalanceCommonWizard, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu) + + res['fields'].update(self.fields_get(cr, uid, + allfields=self.DYNAMIC_FIELDS, + context=context, write_access=True)) + + eview = etree.fromstring(res['arch']) + placeholder = eview.xpath("//page[@name='placeholder']") + if placeholder: + placeholder = placeholder[0] + for index in range(self.COMPARISON_LEVEL): + page = etree.Element( + 'page', + {'name': "comp%s" % index, + 'string': _("Comparison %s") % (index + 1, )}) + group = etree.Element('group') + page.append(group) + + def modifiers_and_append(elem): + orm.setup_modifiers(elem) + group.append(elem) + + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_filter" % index, + 'on_change': "onchange_comp_filter(%(index)s, filter, comp%(index)s_filter, fiscalyear_id, date_from, date_to)" % {'index': index}})) + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_fiscalyear_id" % index, + 'attrs': + "{'required': [('comp%(index)s_filter','in',('filter_year','filter_opening'))]," \ + " 'invisible': [('comp%(index)s_filter','not in',('filter_year','filter_opening'))]}" % {'index': index}})) + + dates_attrs = "{'required': [('comp%(index)s_filter','=','filter_date')], " \ + " 'invisible': [('comp%(index)s_filter','!=','filter_date')]}" % {'index': index} + modifiers_and_append(etree.Element( + 'separator', + {'string': _('Dates'), + 'colspan': '4', + 'attrs': dates_attrs})) + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_date_from" % index, + 'attrs': dates_attrs})) + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_date_to" % index, + 'attrs': dates_attrs})) + + periods_attrs = "{'required': [('comp%(index)s_filter','=','filter_period')]," \ + " 'invisible': [('comp%(index)s_filter','!=','filter_period')]}" % {'index': index} + periods_domain = "[('special', '=', False)]" + modifiers_and_append(etree.Element( + 'separator', + {'string': _('Periods'), + 'colspan': '4', + 'attrs': periods_attrs})) + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_period_from" % index, + 'attrs': periods_attrs, + 'domain': periods_domain})) + modifiers_and_append(etree.Element( + 'field', + {'name': "comp%s_period_to" % index, + 'attrs': periods_attrs, + 'domain': periods_domain})) + + placeholder.addprevious(page) + placeholder.getparent().remove(placeholder) + res['arch'] = etree.tostring(eview) + return res + + def onchange_filter(self, cr, uid, ids, filter='filter_no', fiscalyear_id=False, context=None): + res = {} + if filter == 'filter_no': + res['value'] = {'period_from': False, 'period_to': False, 'date_from': False, 'date_to': False} + if filter == 'filter_date': + if fiscalyear_id: + fyear = self.pool.get('account.fiscalyear').browse(cr, uid, fiscalyear_id, context=context) + date_from = fyear.date_start + date_to = fyear.date_stop > time.strftime('%Y-%m-%d') and time.strftime('%Y-%m-%d') or fyear.date_stop + else: + date_from, date_to = time.strftime('%Y-01-01'), time.strftime('%Y-%m-%d') + res['value'] = {'period_from': False, 'period_to': False, 'date_from': date_from, 'date_to': date_to} + if filter == 'filter_period' and fiscalyear_id: + start_period = end_period = False + cr.execute(''' + SELECT * FROM (SELECT p.id + FROM account_period p + LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) + WHERE f.id = %s + AND COALESCE(p.special, FALSE) = FALSE + ORDER BY p.date_start ASC + LIMIT 1) AS period_start + UNION ALL + SELECT * FROM (SELECT p.id + FROM account_period p + LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) + WHERE f.id = %s + AND p.date_start < NOW() + AND COALESCE(p.special, FALSE) = FALSE + ORDER BY p.date_stop DESC + LIMIT 1) AS period_stop''', (fiscalyear_id, fiscalyear_id)) + periods = [i[0] for i in cr.fetchall()] + if periods: + start_period = end_period = periods[0] + if len(periods) > 1: + end_period = periods[1] + res['value'] = {'period_from': start_period, 'period_to': end_period, 'date_from': False, 'date_to': False} + return res + + def onchange_comp_filter(self, cr, uid, ids, index, main_filter='filter_no', comp_filter='filter_no', fiscalyear_id=False, start_date=False, stop_date=False, context=None): + res = {} + fy_obj = self.pool.get('account.fiscalyear') + last_fiscalyear_id = False + if fiscalyear_id: + fiscalyear = fy_obj.browse(cr, uid, fiscalyear_id, context=context) + last_fiscalyear_ids = fy_obj.search(cr, uid, [('date_stop', '<', fiscalyear.date_start)], + limit=self.COMPARISON_LEVEL, order='date_start desc', context=context) + if last_fiscalyear_ids: + if len(last_fiscalyear_ids) > index: + last_fiscalyear_id = last_fiscalyear_ids[index] # first element for the comparison 1, second element for the comparison 2 + + fy_id_field = "comp%s_fiscalyear_id" % (index,) + period_from_field = "comp%s_period_from" % (index,) + period_to_field = "comp%s_period_to" % (index,) + date_from_field = "comp%s_date_from" % (index,) + date_to_field = "comp%s_date_to" % (index,) + + if comp_filter == 'filter_no': + res['value'] = { + fy_id_field: False, + period_from_field: False, + period_to_field: False, + date_from_field: False, + date_to_field: False + } + if comp_filter in ('filter_year', 'filter_opening'): + res['value'] = { + fy_id_field: last_fiscalyear_id, + period_from_field: False, + period_to_field: False, + date_from_field: False, + date_to_field: False + } + if comp_filter == 'filter_date': + dates = {} + if main_filter == 'filter_date': + dates = { + 'date_start': previous_year_date(start_date, index + 1).strftime('%Y-%m-%d'), + 'date_stop': previous_year_date(stop_date, index + 1).strftime('%Y-%m-%d'), + } + elif last_fiscalyear_id: + dates = fy_obj.read(cr, uid, last_fiscalyear_id, ['date_start', 'date_stop'], context=context) + + res['value'] = {fy_id_field: False, period_from_field: False, period_to_field: False, date_from_field: dates.get('date_start', False), date_to_field: dates.get('date_stop', False)} + if comp_filter == 'filter_period' and last_fiscalyear_id: + start_period = end_period = False + cr.execute(''' + SELECT * FROM (SELECT p.id + FROM account_period p + LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) + WHERE f.id = %(fiscalyear)s + AND COALESCE(p.special, FALSE) = FALSE + ORDER BY p.date_start ASC + LIMIT 1) AS period_start + UNION ALL + SELECT * FROM (SELECT p.id + FROM account_period p + LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) + WHERE f.id = %(fiscalyear)s + AND p.date_start < NOW() + AND COALESCE(p.special, FALSE) = FALSE + ORDER BY p.date_stop DESC + LIMIT 1) AS period_stop''', {'fiscalyear': last_fiscalyear_id}) + periods = [i[0] for i in cr.fetchall()] + if periods and len(periods) > 1: + start_period = end_period = periods[0] + if len(periods) > 1: + end_period = periods[1] + res['value'] = {fy_id_field: False, + period_from_field: start_period, + period_to_field: end_period, + date_from_field: False, + date_to_field: False} + return res + + def pre_print_report(self, cr, uid, ids, data, context=None): + data = super(AccountBalanceCommonWizard, self).pre_print_report( + cr, uid, ids, data, context) + if context is None: + context = {} + + # will be used to attach the report on the main account + data['ids'] = [data['form']['chart_account_id']] + + fields_to_read = ['account_ids', ] + fields_to_read += self.DYNAMIC_FIELDS + vals = self.read(cr, uid, ids, fields_to_read, context=context)[0] + + # extract the id from the m2o tuple (id, name) + for field in self.M2O_DYNAMIC_FIELDS: + if isinstance(vals[field], tuple): + vals[field] = vals[field][0] + + vals['max_comparison'] = self.COMPARISON_LEVEL + data['form'].update(vals) + return data