From 0eb99442224bb12bedc7150139796e8de64a7e1f Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Mon, 24 Mar 2014 09:50:46 +0100
Subject: [PATCH 01/57] [IMP] refactoring of readgroup method. It should have
the same functionality, but is much simpler. This is necessary to implement
eager groupby (orm.py)
bzr revid: ged@openerp.com-20140324085046-zpfpcostivf8454q
---
openerp/osv/orm.py | 230 ++++++++++++++++++++-------------------------
1 file changed, 100 insertions(+), 130 deletions(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index 64fa06783ab..cc8e7aa066b 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2222,7 +2222,7 @@ class BaseModel(object):
self._name, order_part)
return groupby_terms, orderby_terms
- def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
+ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context={}, orderby=False):
"""
Get the list of records in list view grouped by the given ``groupby`` fields
@@ -2252,91 +2252,80 @@ class BaseModel(object):
* if user tries to bypass access rules for read on the requested object
"""
- context = context or {}
self.check_access_rights(cr, uid, 'read')
- if not fields:
- fields = self._columns.keys()
- query = self._where_calc(cr, uid, domain, context=context)
- self._apply_ir_rules(cr, uid, query, 'read', context=context)
-
- # Take care of adding join(s) if groupby is an '_inherits'ed field
- groupby_list = groupby
- qualified_groupby_field = groupby
- if groupby:
- if isinstance(groupby, list):
- groupby = groupby[0]
- splitted_groupby = groupby.split(':')
- if len(splitted_groupby) == 2:
- groupby = splitted_groupby[0]
- groupby_function = splitted_groupby[1]
- else:
- groupby_function = False
- qualified_groupby_field = self._inherits_join_calc(groupby, query)
-
- if groupby:
- assert not groupby or groupby in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
- groupby_def = self._columns.get(groupby) or (self._inherit_fields.get(groupby) and self._inherit_fields.get(groupby)[2])
- assert groupby_def and groupby_def._classic_write, "Fields in 'groupby' must be regular database-persisted fields (no function or related fields), or function fields with store=True"
-
- # TODO it seems fields_get can be replaced by _all_columns (no need for translation)
+ # Step 0 : preparing some useful variables
+ fields = fields or self._columns.keys()
fget = self.fields_get(cr, uid, fields)
- group_by_params = {}
- select_terms = []
- groupby_type = None
- if groupby:
- if fget.get(groupby):
- groupby_type = fget[groupby]['type']
- if groupby_type in ('date', 'datetime'):
- if groupby_function:
- interval = groupby_function
- else:
- interval = 'month'
+ if isinstance(groupby, basestring):
+ groupby = [groupby]
+ split_groupby = groupby[0].split(':') if groupby else None
+ first_groupby = split_groupby[0] if split_groupby else None
+ groupby_function = split_groupby[1] if split_groupby and len(split_groupby) == 2 else None
+ interval = groupby_function if groupby_function else 'month'
+ groupby_type = fget[first_groupby]['type'] if first_groupby else None
+ if groupby_type in ('date', 'datetime'):
+ dt_format = DEFAULT_SERVER_DATETIME_FORMAT if groupby_type == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
+ tz_convert = groupby_type == 'datetime' and context.get('tz') in pytz.all_timezones
+ time_display_format = {
+ 'day': 'dd MMM YYYY',
+ 'week': "'W'w YYYY",
+ 'month': 'MMMM YYYY',
+ 'quarter': 'QQQ YYYY',
+ 'year': 'YYYY'}[interval]
+ time_interval = {
+ 'day': dateutil.relativedelta.relativedelta(months=3),
+ 'week': datetime.timedelta(days=7),
+ 'month': dateutil.relativedelta.relativedelta(months=1),
+ 'quarter': dateutil.relativedelta.relativedelta(months=3),
+ 'year': dateutil.relativedelta.relativedelta(years=1)}[interval]
- if interval == 'day':
- display_format = 'dd MMM YYYY'
- elif interval == 'week':
- display_format = "'W'w YYYY"
- elif interval == 'month':
- display_format = 'MMMM YYYY'
- elif interval == 'quarter':
- display_format = 'QQQ YYYY'
- elif interval == 'year':
- display_format = 'YYYY'
+ query = self._where_calc(cr, uid, domain, context=context)
- if groupby_type == 'datetime' and context.get('tz') in pytz.all_timezones:
- # Convert groupby result to user TZ to avoid confusion!
- # PostgreSQL is compatible with all pytz timezone names, so we can use them
- # directly for conversion, starting with timestamps stored in UTC.
- timezone = context.get('tz', 'UTC')
- qualified_groupby_field = "timezone('%s', timezone('UTC',%s))" % (timezone, qualified_groupby_field)
- qualified_groupby_field = "date_trunc('%s', %s)" % (interval, qualified_groupby_field)
- elif groupby_type == 'boolean':
- qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field
- select_terms.append("%s as %s " % (qualified_groupby_field, groupby))
- else:
+ # Step 1: security stuff
+ # add relevant ir_rules to the where clause, perform some basic sanity checks
+ self._apply_ir_rules(cr, uid, query, 'read', context=context)
+ if first_groupby:
+ assert first_groupby in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
+ groupby_def = self._columns.get(first_groupby) or (self._inherit_fields.get(first_groupby) and self._inherit_fields.get(first_groupby)[2])
+ assert groupby_def and groupby_def._classic_write, "Fields in 'groupby' must be regular database-persisted fields (no function or related fields), or function fields with store=True"
+ if not (first_groupby in fget):
# Don't allow arbitrary values, as this would be a SQL injection vector!
raise except_orm(_('Invalid group_by'),
- _('Invalid group_by specification: "%s".\nA group_by specification must be a list of valid fields.')%(groupby,))
+ _('Invalid group_by specification: "%s".\nA group_by specification must be a list of valid fields.')%(first_groupby,))
+ # Step 2: preparing the query:
+ # compute aggregated fields, format groupbys, adjust timezone, ...
aggregated_fields = [
f for f in fields
if f not in ('id', 'sequence', groupby)
if fget[f]['type'] in ('integer', 'float')
if (f in self._all_columns and getattr(self._all_columns[f].column, '_classic_write'))]
- for f in aggregated_fields:
- group_operator = fget[f].get('group_operator', 'sum')
- qualified_field = self._inherits_join_calc(f, query)
- select_terms.append("%s(%s) AS %s" % (group_operator, qualified_field, f))
- order = orderby or groupby or ''
- groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, groupby, qualified_groupby_field, query, groupby_type)
+ field_formatter = lambda f: (fget[f].get('group_operator', 'sum'), self._inherits_join_calc(f, query), f)
+ select_terms = ["%s(%s) AS %s" % field_formatter(f) for f in aggregated_fields]
+
+ qualified_groupby_field = self._inherits_join_calc(first_groupby, query) if first_groupby else None
+
+ if groupby_type in ('date', 'datetime'):
+ if tz_convert:
+ # Convert groupby result to user TZ to avoid confusion!
+ # PostgreSQL is compatible with all pytz timezone names, so we can use them
+ # directly for conversion, starting with timestamps stored in UTC.
+ timezone = context.get('tz', 'UTC')
+ qualified_groupby_field = "timezone('%s', timezone('UTC',%s))" % (timezone, qualified_groupby_field)
+ qualified_groupby_field = "date_trunc('%s', %s)" % (interval, qualified_groupby_field)
+
+ if groupby_type == 'boolean':
+ qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field
+
+ if first_groupby:
+ select_terms.append("%s as %s " % (qualified_groupby_field, first_groupby))
+
+ order = orderby or first_groupby or ''
+ groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, first_groupby, qualified_groupby_field, query, groupby_type)
from_clause, where_clause, where_clause_params = query.get_sql()
- if len(groupby_list) < 2 and context.get('group_by_no_leaf'):
- count_field = '_'
- else:
- count_field = groupby
prefix_terms = lambda prefix, terms: (prefix + " " + ",".join(terms)) if terms else ''
prefix_term = lambda prefix, term: ('%s %s' % (prefix, term)) if term else ''
@@ -2352,7 +2341,7 @@ class BaseModel(object):
%(offset)s
""" % {
'table': self._table,
- 'count_field': count_field,
+ 'count_field': '_' if (len(groupby) < 2 and context.get('group_by_no_leaf')) else first_groupby,
'extra_fields': prefix_terms(',', select_terms),
'from': from_clause,
'where': prefix_term('WHERE', where_clause),
@@ -2362,73 +2351,54 @@ class BaseModel(object):
'offset': prefix_term('OFFSET', int(offset) if limit else None),
}
cr.execute(query, where_clause_params)
- alldata = {}
- fetched_data = cr.dictfetchall()
- data_ids = []
- for r in fetched_data:
- for fld, val in r.items():
- if val is None: r[fld] = False
- alldata[r['id']] = r
- data_ids.append(r['id'])
- del r['id']
+ if not first_groupby:
+ return {r.pop('id'): r for r in cr.dictfetchall() }
- if groupby:
- data = self.read(cr, uid, data_ids, [groupby], context=context)
- # restore order of the search as read() uses the default _order (this is only for groups, so the footprint of data should be small):
- data_dict = dict((d['id'], d[groupby] ) for d in data)
- result = [{'id': i, groupby: data_dict[i]} for i in data_ids]
- else:
- result = [{'id': i} for i in data_ids]
+ none_to_false = lambda record: {k: (False if v is None else v) for k,v in record.iteritems() }
+ fetched_data = map(none_to_false, cr.dictfetchall())
- for d in result:
- if groupby:
- d['__domain'] = [(groupby, '=', alldata[d['id']][groupby] or False)] + domain
- if not isinstance(groupby_list, (str, unicode)):
- if groupby or not context.get('group_by_no_leaf', False):
- d['__context'] = {'group_by': groupby_list[1:]}
- if groupby and groupby in fget:
- groupby_type = fget[groupby]['type']
- if d[groupby] and groupby_type in ('date', 'datetime'):
- groupby_datetime = alldata[d['id']][groupby]
- if isinstance(groupby_datetime, basestring):
- _default = datetime.datetime(1970, 1, 1) # force starts of month
- groupby_datetime = dateutil.parser.parse(groupby_datetime, default=_default)
- tz_convert = groupby_type == 'datetime' and context.get('tz') in pytz.all_timezones
- if tz_convert:
- groupby_datetime = pytz.timezone(context['tz']).localize(groupby_datetime)
- d[groupby] = babel.dates.format_date(
- groupby_datetime, format=display_format, locale=context.get('lang', 'en_US'))
- domain_dt_begin = groupby_datetime
- if interval == 'quarter':
- domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=3)
- elif interval == 'month':
- domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(months=1)
- elif interval == 'week':
- domain_dt_end = groupby_datetime + datetime.timedelta(days=7)
- elif interval == 'day':
- domain_dt_end = groupby_datetime + datetime.timedelta(days=1)
- else:
- domain_dt_end = groupby_datetime + dateutil.relativedelta.relativedelta(years=1)
- if tz_convert:
- # the time boundaries were all computed in the apparent TZ of the user,
- # so we need to convert them to UTC to have proper server-side values.
- domain_dt_begin = domain_dt_begin.astimezone(pytz.utc)
- domain_dt_end = domain_dt_end.astimezone(pytz.utc)
- dt_format = DEFAULT_SERVER_DATETIME_FORMAT if groupby_type == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
- d['__domain'] = [(groupby, '>=', domain_dt_begin.strftime(dt_format)),
- (groupby, '<', domain_dt_end.strftime(dt_format))] + domain
- del alldata[d['id']][groupby]
- d.update(alldata[d['id']])
- del d['id']
+ data_ids = [r['id'] for r in fetched_data]
+ data_dict = {d['id']: d[first_groupby] for d in self.read(cr, uid, data_ids, [first_groupby], context=context)}
+ sorted_data = [{first_groupby: data_dict[id]} for id in data_ids]
- if groupby and groupby in self._group_by_full:
- result = self._read_group_fill_results(cr, uid, domain, groupby, groupby_list,
+ def format_result (fromquery, fromread):
+ result = {
+ '__domain': [(first_groupby, '=', fromquery[first_groupby] or False)] + domain,
+ '__context': {'group_by': groupby[1:]}
+ }
+ result.update(fromquery)
+ result.update(fromread)
+
+ if groupby_type in ('date', 'datetime') and fromquery[first_groupby]:
+ groupby_datetime = fromquery[first_groupby]
+ if isinstance(groupby_datetime, basestring):
+ groupby_datetime = datetime.datetime.strptime(groupby_datetime, dt_format)
+ if tz_convert:
+ groupby_datetime = pytz.timezone(context['tz']).localize(groupby_datetime)
+ result[first_groupby] = babel.dates.format_date(
+ groupby_datetime, format=time_display_format, locale=context.get('lang', 'en_US'))
+ domain_dt_begin = groupby_datetime
+ domain_dt_end = groupby_datetime + time_interval
+ if tz_convert:
+ # the time boundaries were all computed in the apparent TZ of the user,
+ # so we need to convert them to UTC to have proper server-side values.
+ domain_dt_begin = domain_dt_begin.astimezone(pytz.utc)
+ domain_dt_end = domain_dt_end.astimezone(pytz.utc)
+ result['__domain'] = [(first_groupby, '>=', domain_dt_begin.strftime(dt_format)),
+ (first_groupby, '<', domain_dt_end.strftime(dt_format))] + domain
+ del result['id']
+ return result
+
+ result = map(format_result, fetched_data, sorted_data)
+
+ if first_groupby in self._group_by_full:
+ result = self._read_group_fill_results(cr, uid, domain, first_groupby, groupby,
aggregated_fields, result, read_group_order=order,
context=context)
-
return result
+
def _inherits_join_add(self, current_model, parent_model_name, query):
"""
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
From 30e787511f743648c7c86d932e215a854b7a5448 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Tue, 25 Mar 2014 17:11:04 +0100
Subject: [PATCH 02/57] [IMP] refactoring of readgroup method, to make it
eager. Still incomplete, but it is mostly working (orm.py)
bzr revid: ged@openerp.com-20140325161104-d0xgof4bcskh4ie6
---
openerp/osv/orm.py | 217 +++++++++++++++++++++++++--------------------
1 file changed, 119 insertions(+), 98 deletions(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index cc8e7aa066b..ac07a6f5bca 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -55,7 +55,7 @@ import traceback
import types
import babel.dates
-import dateutil.parser
+import dateutil.relativedelta
import psycopg2
from lxml import etree
@@ -2185,20 +2185,21 @@ class BaseModel(object):
r['__fold'] = folded.get(r[groupby] and r[groupby][0], False)
return result
- def _read_group_prepare(self, orderby, aggregated_fields, groupby, qualified_groupby_field, query, groupby_type=None):
+ def _read_group_prepare(self, orderby, aggregated_fields, annotated_groupbys, query, fget):
"""
Prepares the GROUP BY and ORDER BY terms for the read_group method. Adds the missing JOIN clause
to the query if order should be computed against m2o field.
:param orderby: the orderby definition in the form "%(field)s %(order)s"
:param aggregated_fields: list of aggregated fields in the query
:param groupby: the current groupby field name
- :param qualified_groupby_field: the fully qualified SQL name for the grouped field
+ :param qualified_field: the fully qualified SQL name for the grouped field
:param osv.Query query: the query under construction
:param groupby_type: the type of the grouped field
:return: (groupby_terms, orderby_terms)
"""
orderby_terms = []
- groupby_terms = [qualified_groupby_field] if groupby else []
+ groupby_terms = [gb['qualified_field'] for gb in annotated_groupbys]
+ groupby_fields = [gb['field'] for gb in annotated_groupbys]
if not orderby:
return groupby_terms, orderby_terms
@@ -2206,8 +2207,9 @@ class BaseModel(object):
for order_part in orderby.split(','):
order_split = order_part.split()
order_field = order_split[0]
- if order_field == groupby:
- if groupby_type == 'many2one':
+ if order_field in groupby_fields:
+
+ if fget[order_field]['type'] == 'many2one':
order_clause = self._generate_order_by(order_part, query).replace('ORDER BY ', '')
if order_clause:
orderby_terms.append(order_clause)
@@ -2222,7 +2224,7 @@ class BaseModel(object):
self._name, order_part)
return groupby_terms, orderby_terms
- def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context={}, orderby=False):
+ def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context={}, orderby=False, lazy=True):
"""
Get the list of records in list view grouped by the given ``groupby`` fields
@@ -2242,6 +2244,9 @@ class BaseModel(object):
overriding the natural sort ordering of the
groups, see also :py:meth:`~osv.osv.osv.search`
(supported only for many2one fields currently)
+ :param bool lazy: if true, the results are only grouped by the first groupby and the
+ remaining groupbys are put in the __context key. If false, all the groupbys are
+ done in one call.
:return: list of dictionaries(one dictionary for each record) containing:
* the values of fields grouped by the fields in ``groupby`` argument
@@ -2253,86 +2258,84 @@ class BaseModel(object):
"""
self.check_access_rights(cr, uid, 'read')
-
- # Step 0 : preparing some useful variables
+ query = self._where_calc(cr, uid, domain, context=context)
fields = fields or self._columns.keys()
fget = self.fields_get(cr, uid, fields)
- if isinstance(groupby, basestring):
- groupby = [groupby]
- split_groupby = groupby[0].split(':') if groupby else None
- first_groupby = split_groupby[0] if split_groupby else None
- groupby_function = split_groupby[1] if split_groupby and len(split_groupby) == 2 else None
- interval = groupby_function if groupby_function else 'month'
- groupby_type = fget[first_groupby]['type'] if first_groupby else None
- if groupby_type in ('date', 'datetime'):
- dt_format = DEFAULT_SERVER_DATETIME_FORMAT if groupby_type == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
- tz_convert = groupby_type == 'datetime' and context.get('tz') in pytz.all_timezones
- time_display_format = {
- 'day': 'dd MMM YYYY',
- 'week': "'W'w YYYY",
- 'month': 'MMMM YYYY',
- 'quarter': 'QQQ YYYY',
- 'year': 'YYYY'}[interval]
- time_interval = {
- 'day': dateutil.relativedelta.relativedelta(months=3),
- 'week': datetime.timedelta(days=7),
- 'month': dateutil.relativedelta.relativedelta(months=1),
- 'quarter': dateutil.relativedelta.relativedelta(months=3),
- 'year': dateutil.relativedelta.relativedelta(years=1)}[interval]
+ groupby = [groupby] if isinstance(groupby, basestring) else groupby
+ display_formats = {
+ 'day': 'dd MMM YYYY',
+ 'week': "'W'w YYYY",
+ 'month': 'MMMM YYYY',
+ 'quarter': 'QQQ YYYY',
+ 'year': 'YYYY'
+ }
+ time_intervals = {
+ 'day': dateutil.relativedelta.relativedelta(months=3),
+ 'week': datetime.timedelta(days=7),
+ 'month': dateutil.relativedelta.relativedelta(months=1),
+ 'quarter': dateutil.relativedelta.relativedelta(months=3),
+ 'year': dateutil.relativedelta.relativedelta(years=1)
+ }
- query = self._where_calc(cr, uid, domain, context=context)
+ def process_groupby (gb):
+ split = gb.split(':')
+ field_type = fget[split[0]]['type']
+ gb_function = split[1] if len(split) == 2 else None
+ temporal = field_type in ('date', 'datetime')
+ tz_convert = field_type == 'datetime' and context.get('tz') in pytz.all_timezones
+ qualified_field = self._inherits_join_calc(split[0], query)
+ if temporal:
+ if tz_convert:
+ qualified_field = "timezone('%s', timezone('UTC',%s))" % (context.get('tz', 'UTC'), qualified_field)
+ qualified_field = "date_trunc('%s', %s)" % (gb_function or 'month', qualified_field)
+ if field_type == 'boolean':
+ qualified_field = "coalesce(%s,false)" % qualified_field
+ return {
+ 'field': split[0],
+ 'type': field_type,
+ 'display_format': display_formats[gb_function or 'month'] if temporal else None,
+ 'interval': time_intervals[gb_function or 'month'] if temporal else None,
+ 'tz_convert': tz_convert,
+ 'qualified_field': qualified_field
+ }
+
+ annotated_groupbys = map(process_groupby, groupby[:1] if lazy else groupby)
+ groupby_fields = [g['field'] for g in annotated_groupbys]
+ order = orderby or ','.join(groupby_fields)
+ groupby_dict = {gb['field']: gb for gb in annotated_groupbys}
- # Step 1: security stuff
- # add relevant ir_rules to the where clause, perform some basic sanity checks
self._apply_ir_rules(cr, uid, query, 'read', context=context)
- if first_groupby:
- assert first_groupby in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
- groupby_def = self._columns.get(first_groupby) or (self._inherit_fields.get(first_groupby) and self._inherit_fields.get(first_groupby)[2])
+ for gb in groupby_fields:
+ assert gb in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
+ groupby_def = self._columns.get(gb) or (self._inherit_fields.get(gb) and self._inherit_fields.get(gb)[2])
assert groupby_def and groupby_def._classic_write, "Fields in 'groupby' must be regular database-persisted fields (no function or related fields), or function fields with store=True"
- if not (first_groupby in fget):
+ if not (gb in fget):
# Don't allow arbitrary values, as this would be a SQL injection vector!
raise except_orm(_('Invalid group_by'),
- _('Invalid group_by specification: "%s".\nA group_by specification must be a list of valid fields.')%(first_groupby,))
+ _('Invalid group_by specification: "%s".\nA group_by specification must be a list of valid fields.')%(gb,))
- # Step 2: preparing the query:
- # compute aggregated fields, format groupbys, adjust timezone, ...
aggregated_fields = [
f for f in fields
- if f not in ('id', 'sequence', groupby)
+ if f not in ('id', 'sequence')
+ if f not in groupby_fields
if fget[f]['type'] in ('integer', 'float')
if (f in self._all_columns and getattr(self._all_columns[f].column, '_classic_write'))]
field_formatter = lambda f: (fget[f].get('group_operator', 'sum'), self._inherits_join_calc(f, query), f)
select_terms = ["%s(%s) AS %s" % field_formatter(f) for f in aggregated_fields]
- qualified_groupby_field = self._inherits_join_calc(first_groupby, query) if first_groupby else None
-
- if groupby_type in ('date', 'datetime'):
- if tz_convert:
- # Convert groupby result to user TZ to avoid confusion!
- # PostgreSQL is compatible with all pytz timezone names, so we can use them
- # directly for conversion, starting with timestamps stored in UTC.
- timezone = context.get('tz', 'UTC')
- qualified_groupby_field = "timezone('%s', timezone('UTC',%s))" % (timezone, qualified_groupby_field)
- qualified_groupby_field = "date_trunc('%s', %s)" % (interval, qualified_groupby_field)
-
- if groupby_type == 'boolean':
- qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field
-
- if first_groupby:
- select_terms.append("%s as %s " % (qualified_groupby_field, first_groupby))
-
- order = orderby or first_groupby or ''
- groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, first_groupby, qualified_groupby_field, query, groupby_type)
+ for gb in annotated_groupbys:
+ select_terms.append("%s as %s " % (gb['qualified_field'], gb['field']))
+ groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, annotated_groupbys, query, fget)
from_clause, where_clause, where_clause_params = query.get_sql()
+ count_field = groupby_fields[0] if (len(groupby_fields) == 1 and context.get('group_by_no_leaf')) else '_'
prefix_terms = lambda prefix, terms: (prefix + " " + ",".join(terms)) if terms else ''
prefix_term = lambda prefix, term: ('%s %s' % (prefix, term)) if term else ''
query = """
- SELECT min(%(table)s.id) AS id, count(%(table)s.id) AS %(count_field)s_count
- %(extra_fields)s
+ SELECT min(%(table)s.id) AS id, count(%(table)s.id) AS %(count_field)s_count %(extra_fields)s
FROM %(from)s
%(where)s
%(groupby)s
@@ -2341,7 +2344,7 @@ class BaseModel(object):
%(offset)s
""" % {
'table': self._table,
- 'count_field': '_' if (len(groupby) < 2 and context.get('group_by_no_leaf')) else first_groupby,
+ 'count_field': count_field,
'extra_fields': prefix_terms(',', select_terms),
'from': from_clause,
'where': prefix_term('WHERE', where_clause),
@@ -2352,53 +2355,71 @@ class BaseModel(object):
}
cr.execute(query, where_clause_params)
- if not first_groupby:
+ if not groupby_fields:
return {r.pop('id'): r for r in cr.dictfetchall() }
- none_to_false = lambda record: {k: (False if v is None else v) for k,v in record.iteritems() }
- fetched_data = map(none_to_false, cr.dictfetchall())
+ def prepare_data(key, value):
+ value = False if value is None else value
+ gb = groupby_dict.get(key)
+ if gb and gb['type'] in ('date', 'datetime') and value:
+ if isinstance(value, basestring):
+ dt_format = DEFAULT_SERVER_DATETIME_FORMAT if gb['type'] == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
+ value = datetime.datetime.strptime(value, dt_format)
+ if gb['tz_convert']:
+ value = pytz.timezone(context['tz']).localize(value)
+ return value
- data_ids = [r['id'] for r in fetched_data]
- data_dict = {d['id']: d[first_groupby] for d in self.read(cr, uid, data_ids, [first_groupby], context=context)}
- sorted_data = [{first_groupby: data_dict[id]} for id in data_ids]
+ fetched_data = cr.dictfetchall()
- def format_result (fromquery, fromread):
- result = {
- '__domain': [(first_groupby, '=', fromquery[first_groupby] or False)] + domain,
- '__context': {'group_by': groupby[1:]}
- }
- result.update(fromquery)
- result.update(fromread)
+ many2onefields = [gb['field'] for gb in annotated_groupbys if gb['type'] == 'many2one']
+ if many2onefields:
+ data_ids = [r['id'] for r in fetched_data]
+ data_dict = {d['id']: d for d in self.read(cr, uid, data_ids, many2onefields, context=context)}
+ for d in fetched_data:
+ d.update(data_dict[d['id']])
- if groupby_type in ('date', 'datetime') and fromquery[first_groupby]:
- groupby_datetime = fromquery[first_groupby]
- if isinstance(groupby_datetime, basestring):
- groupby_datetime = datetime.datetime.strptime(groupby_datetime, dt_format)
- if tz_convert:
- groupby_datetime = pytz.timezone(context['tz']).localize(groupby_datetime)
- result[first_groupby] = babel.dates.format_date(
- groupby_datetime, format=time_display_format, locale=context.get('lang', 'en_US'))
- domain_dt_begin = groupby_datetime
- domain_dt_end = groupby_datetime + time_interval
- if tz_convert:
- # the time boundaries were all computed in the apparent TZ of the user,
- # so we need to convert them to UTC to have proper server-side values.
+ data = map(lambda r: {k: prepare_data(k,v) for k,v in r.iteritems()}, fetched_data)
+
+ def get_domain(gb, value):
+ if gb['type'] in ('date', 'datetime') and value:
+ dt_format = DEFAULT_SERVER_DATETIME_FORMAT if gb['type'] == 'datetime' else DEFAULT_SERVER_DATE_FORMAT
+ domain_dt_begin = value
+ domain_dt_end = value + gb['interval']
+ if gb['tz_convert']:
domain_dt_begin = domain_dt_begin.astimezone(pytz.utc)
domain_dt_end = domain_dt_end.astimezone(pytz.utc)
- result['__domain'] = [(first_groupby, '>=', domain_dt_begin.strftime(dt_format)),
- (first_groupby, '<', domain_dt_end.strftime(dt_format))] + domain
+ return [(gb['field'], '>=', domain_dt_begin.strftime(dt_format)),
+ (gb['field'], '<', domain_dt_end.strftime(dt_format))]
+ if gb['type'] == 'many2one' and value:
+ value = value[0]
+ return [(gb['field'], '=', value)]
+
+ def format_result (fromquery):
+ domain_group = [dom for gb in annotated_groupbys for dom in get_domain(gb, fromquery[gb['field']])]
+ result = {
+ '__domain': domain_group + domain,
+ '__context': {'group_by': groupby[len(annotated_groupbys):]}
+ }
+ result.update(fromquery)
+ for k,v in result.iteritems():
+ gb = groupby_dict.get(k)
+ if gb and gb['type'] in ('date', 'datetime') and v:
+ result[k] = babel.dates.format_date(v, format=gb['display_format'], locale=context.get('lang', 'en_US'))
del result['id']
return result
- result = map(format_result, fetched_data, sorted_data)
+ for gb in groupby_fields:
+ if gb in self._group_by_full:
+ print "DING"
+ result = map(format_result, data)
- if first_groupby in self._group_by_full:
- result = self._read_group_fill_results(cr, uid, domain, first_groupby, groupby,
- aggregated_fields, result, read_group_order=order,
- context=context)
+ # TO DO!!!!!!!!!!!!
+ # if first_groupby in self._group_by_full:
+ # result = self._read_group_fill_results(cr, uid, domain, first_groupby, groupby,
+ # aggregated_fields, result, read_group_order=order,
+ # context=context)
return result
-
def _inherits_join_add(self, current_model, parent_model_name, query):
"""
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
From c771903c3baf11aef0b6d0b6b0bdf9fa870125d3 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 27 Mar 2014 19:25:20 +0100
Subject: [PATCH 03/57] [IMP] account* reports: removed rml, added qweb
template, changed the wizard to return qweb actions
bzr revid: sle@openerp.com-20140327182520-uu7ezsqic30x7mqo
---
addons/account/__openerp__.py | 21 +-
addons/account/account_invoice.py | 12 +-
addons/account/account_report.xml | 187 ++++-
addons/account/project/project_report.xml | 65 +-
.../project/report/analytic_balance.rml | 234 ------
.../project/report/analytic_journal.rml | 346 ---------
addons/account/project/report/cost_ledger.rml | 305 --------
.../report/inverted_analytic_balance.rml | 229 ------
.../project/report/quantity_cost_ledger.rml | 281 --------
.../project/views/report_analyticbalance.xml | 62 ++
.../views/report_analyticcostledger.xml | 90 +++
.../report_analyticcostledgerquantity.xml | 87 +++
.../project/views/report_analyticjournal.xml | 90 +++
.../views/report_invertedanalyticbalance.xml | 91 +++
.../wizard/account_analytic_balance_report.py | 20 +-
...analytic_cost_ledger_for_journal_report.py | 20 +-
.../account_analytic_cost_ledger_report.py | 19 +-
...ccount_analytic_inverted_balance_report.py | 20 +-
.../wizard/account_analytic_journal_report.py | 19 +-
addons/account/report/__init__.py | 4 -
.../report/account_aged_partner_balance.rml | 285 --------
addons/account/report/account_balance.rml | 313 ---------
.../report/account_central_journal.rml | 338 ---------
.../report/account_financial_report.rml | 303 --------
.../report/account_general_journal.rml | 387 ----------
.../account/report/account_general_ledger.rml | 619 ----------------
.../account_general_ledger_landscape.rml | 658 -----------------
addons/account/report/account_journal.rml | 311 --------
.../report/account_journal_sale_purchase.rml | 346 ---------
.../report/account_partner_balance.rml | 257 -------
.../account/report/account_partner_ledger.rml | 658 -----------------
.../report/account_partner_ledger_other.rml | 665 ------------------
.../account/report/account_print_invoice.py | 37 -
.../account/report/account_print_invoice.rml | 373 ----------
.../account/report/account_print_overdue.rml | 290 --------
.../views/report_agedpartnerbalance.xml | 133 ++++
.../account/views/report_centraljournal.xml | 93 +++
addons/account/views/report_financial.xml | 128 ++++
.../account/views/report_generaljournal.xml | 98 +++
addons/account/views/report_generalledger.xml | 133 ++++
addons/account/views/report_invoice.xml | 153 ++++
addons/account/views/report_journal.xml | 88 +++
addons/account/views/report_overdue.xml | 113 +++
.../account/views/report_partnerbalance.xml | 125 ++++
addons/account/views/report_partnerledger.xml | 131 ++++
.../views/report_partnerledgerother.xml | 131 ++++
.../views/report_salepurchasejournal.xml | 107 +++
addons/account/views/report_trialbalance.xml | 94 +++
.../wizard/account_financial_report.py | 12 +-
.../wizard/account_report_account_balance.py | 3 +-
.../account_report_aged_partner_balance.py | 8 +-
.../wizard/account_report_central_journal.py | 9 +-
.../wizard/account_report_general_journal.py | 5 +-
.../wizard/account_report_general_ledger.py | 8 +-
.../wizard/account_report_partner_balance.py | 9 +-
.../wizard/account_report_partner_ledger.py | 19 +-
.../wizard/account_report_print_journal.py | 10 +-
addons/account/wizard/account_vat.py | 3 +-
addons/account_analytic_plans/__openerp__.py | 4 +-
.../account_analytic_plans_report.xml | 13 +-
.../report/crossovered_analytic.rml | 304 --------
.../views/report_crossoveredanalyticplans.xml | 66 ++
.../wizard/account_crossovered_analytic.py | 7 +-
.../__openerp__.py | 1 +
.../account_bank_statement_report.xml | 23 +-
.../report/bank_statement_balance_report.rml | 145 ----
.../views/report_bankstatementbalance.xml | 35 +
addons/account_budget/__openerp__.py | 8 +-
.../account_budget/account_budget_report.xml | 48 +-
.../report/analytic_account_budget_report.rml | 226 ------
.../account_budget/report/budget_report.rml | 188 -----
.../report/crossovered_budget_report.rml | 203 ------
.../views/report_analyticaccountbudget.xml | 69 ++
addons/account_budget/views/report_budget.xml | 77 ++
.../views/report_crossoveredbudget.xml | 81 +++
.../wizard/account_budget_analytic.py | 21 +-
.../account_budget_crossovered_report.py | 17 +-
...count_budget_crossovered_summary_report.py | 20 +-
.../wizard/account_budget_report.py | 20 +-
addons/account_check_writing/__openerp__.py | 4 +-
.../account_check_writing_report.xml | 36 +-
.../data/report_paperformat.xml | 20 +
.../report/check_print_bottom.rml | 318 ---------
.../report/check_print_middle.rml | 356 ----------
.../report/check_print_top.rml | 336 ---------
.../views/report_check.xml | 48 ++
addons/account_followup/__openerp__.py | 3 +-
addons/account_followup/account_followup.py | 17 +-
.../account_followup_reports.xml | 14 +
.../account_followup_view.xml | 1 -
.../report/account_followup_print.rml | 238 -------
.../tests/test_account_followup.py | 4 +-
.../views/report_followup.xml | 58 ++
addons/account_payment/__openerp__.py | 2 +
.../account_payment_report.xml | 9 +-
addons/account_payment/report/order.rml | 290 --------
.../views/report_paymentorder.xml | 104 +++
addons/account_test/__openerp__.py | 15 +-
addons/account_test/account_test_report.xml | 21 +-
addons/account_test/report/account_test.rml | 78 --
.../account_test/views/report_accounttest.xml | 23 +
addons/account_voucher/__openerp__.py | 4 +-
.../report/account_voucher.rml | 446 ------------
.../report/account_voucher_print.rml | 331 ---------
addons/report/controllers/main.py | 9 +-
addons/report/models/report.py | 26 +-
addons/report/models/report_paperformat.py | 4 +-
addons/report/views/layouts.xml | 6 +-
addons/report_intrastat/__init__.py | 2 -
addons/report_intrastat/__openerp__.py | 5 +-
addons/report_intrastat/intrastat_report.xml | 20 +-
addons/report_intrastat/report/__init__.py | 22 -
addons/report_intrastat/report/invoice.py | 35 -
addons/report_intrastat/report/invoice.rml | 401 -----------
.../views/report_intrastatinvoice.xml | 149 ++++
115 files changed, 3172 insertions(+), 11514 deletions(-)
delete mode 100644 addons/account/project/report/analytic_balance.rml
delete mode 100644 addons/account/project/report/analytic_journal.rml
delete mode 100644 addons/account/project/report/cost_ledger.rml
delete mode 100644 addons/account/project/report/inverted_analytic_balance.rml
delete mode 100644 addons/account/project/report/quantity_cost_ledger.rml
create mode 100644 addons/account/project/views/report_analyticbalance.xml
create mode 100644 addons/account/project/views/report_analyticcostledger.xml
create mode 100644 addons/account/project/views/report_analyticcostledgerquantity.xml
create mode 100644 addons/account/project/views/report_analyticjournal.xml
create mode 100644 addons/account/project/views/report_invertedanalyticbalance.xml
delete mode 100644 addons/account/report/account_aged_partner_balance.rml
delete mode 100644 addons/account/report/account_balance.rml
delete mode 100644 addons/account/report/account_central_journal.rml
delete mode 100644 addons/account/report/account_financial_report.rml
delete mode 100644 addons/account/report/account_general_journal.rml
delete mode 100644 addons/account/report/account_general_ledger.rml
delete mode 100644 addons/account/report/account_general_ledger_landscape.rml
delete mode 100644 addons/account/report/account_journal.rml
delete mode 100644 addons/account/report/account_journal_sale_purchase.rml
delete mode 100644 addons/account/report/account_partner_balance.rml
delete mode 100644 addons/account/report/account_partner_ledger.rml
delete mode 100644 addons/account/report/account_partner_ledger_other.rml
delete mode 100644 addons/account/report/account_print_invoice.py
delete mode 100644 addons/account/report/account_print_invoice.rml
delete mode 100644 addons/account/report/account_print_overdue.rml
create mode 100644 addons/account/views/report_agedpartnerbalance.xml
create mode 100644 addons/account/views/report_centraljournal.xml
create mode 100644 addons/account/views/report_financial.xml
create mode 100644 addons/account/views/report_generaljournal.xml
create mode 100644 addons/account/views/report_generalledger.xml
create mode 100644 addons/account/views/report_invoice.xml
create mode 100644 addons/account/views/report_journal.xml
create mode 100644 addons/account/views/report_overdue.xml
create mode 100644 addons/account/views/report_partnerbalance.xml
create mode 100644 addons/account/views/report_partnerledger.xml
create mode 100644 addons/account/views/report_partnerledgerother.xml
create mode 100644 addons/account/views/report_salepurchasejournal.xml
create mode 100644 addons/account/views/report_trialbalance.xml
delete mode 100644 addons/account_analytic_plans/report/crossovered_analytic.rml
create mode 100644 addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
delete mode 100644 addons/account_bank_statement_extensions/report/bank_statement_balance_report.rml
create mode 100644 addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml
delete mode 100644 addons/account_budget/report/analytic_account_budget_report.rml
delete mode 100644 addons/account_budget/report/budget_report.rml
delete mode 100644 addons/account_budget/report/crossovered_budget_report.rml
create mode 100644 addons/account_budget/views/report_analyticaccountbudget.xml
create mode 100644 addons/account_budget/views/report_budget.xml
create mode 100644 addons/account_budget/views/report_crossoveredbudget.xml
create mode 100644 addons/account_check_writing/data/report_paperformat.xml
delete mode 100644 addons/account_check_writing/report/check_print_bottom.rml
delete mode 100644 addons/account_check_writing/report/check_print_middle.rml
delete mode 100644 addons/account_check_writing/report/check_print_top.rml
create mode 100644 addons/account_check_writing/views/report_check.xml
create mode 100644 addons/account_followup/account_followup_reports.xml
delete mode 100644 addons/account_followup/report/account_followup_print.rml
create mode 100644 addons/account_followup/views/report_followup.xml
delete mode 100644 addons/account_payment/report/order.rml
create mode 100644 addons/account_payment/views/report_paymentorder.xml
delete mode 100644 addons/account_test/report/account_test.rml
create mode 100644 addons/account_test/views/report_accounttest.xml
delete mode 100644 addons/account_voucher/report/account_voucher.rml
delete mode 100644 addons/account_voucher/report/account_voucher_print.rml
delete mode 100644 addons/report_intrastat/report/__init__.py
delete mode 100644 addons/report_intrastat/report/invoice.py
delete mode 100644 addons/report_intrastat/report/invoice.rml
create mode 100644 addons/report_intrastat/views/report_intrastatinvoice.xml
diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py
index 95ecdc8c35a..83434893ac7 100644
--- a/addons/account/__openerp__.py
+++ b/addons/account/__openerp__.py
@@ -126,6 +126,24 @@ for a particular financial year and for preparation of vouchers there is a modul
'account_pre_install.yml',
'views/report_vat.xml',
+ 'views/report_invoice.xml',
+ 'views/report_trialbalance.xml',
+ 'views/report_centraljournal.xml',
+ 'views/report_overdue.xml',
+ 'views/report_generaljournal.xml',
+ 'views/report_journal.xml',
+ 'views/report_salepurchasejournal.xml',
+ 'views/report_partnerbalance.xml',
+ 'views/report_agedpartnerbalance.xml',
+ 'views/report_partnerledger.xml',
+ 'views/report_partnerledgerother.xml',
+ 'views/report_financial.xml',
+ 'views/report_generalledger.xml',
+ 'project/views/report_analyticbalance.xml',
+ 'project/views/report_analyticjournal.xml',
+ 'project/views/report_analyticcostledgerquantity.xml',
+ 'project/views/report_analyticcostledger.xml',
+ 'project/views/report_invertedanalyticbalance.xml',
],
'js': [
'static/src/js/account_move_reconciliation.js',
@@ -157,8 +175,6 @@ for a particular financial year and for preparation of vouchers there is a modul
'test/account_period_close.yml',
'test/account_use_model.yml',
'test/account_validate_account_move.yml',
- #'test/account_bank_statement.yml',
- #'test/account_cash_statement.yml',
'test/test_edi_invoice.yml',
'test/account_report.yml',
'test/account_fiscalyear_close.yml', #last test, as it will definitively close the demo fiscalyear
@@ -166,4 +182,5 @@ for a particular financial year and for preparation of vouchers there is a modul
'installable': True,
'auto_install': False,
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py
index 06e59232ac9..5f7c2b66400 100644
--- a/addons/account/account_invoice.py
+++ b/addons/account/account_invoice.py
@@ -409,17 +409,7 @@ class account_invoice(osv.osv):
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
self.write(cr, uid, ids, {'sent': True}, context=context)
- datas = {
- 'ids': ids,
- 'model': 'account.invoice',
- 'form': self.read(cr, uid, ids[0], context=context)
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.invoice',
- 'datas': datas,
- 'nodestroy' : True
- }
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_invoice', context=context)
def action_invoice_sent(self, cr, uid, ids, context=None):
'''
diff --git a/addons/account/account_report.xml b/addons/account/account_report.xml
index 4f9ad1b5c56..90d2c1637fb 100644
--- a/addons/account/account_report.xml
+++ b/addons/account/account_report.xml
@@ -1,45 +1,168 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ parent="account.menu_finance_generic_reporting"
+ sequence="3"
+ />
diff --git a/addons/account/project/project_report.xml b/addons/account/project/project_report.xml
index 3ee449e01b5..de2e2feee5a 100644
--- a/addons/account/project/project_report.xml
+++ b/addons/account/project/project_report.xml
@@ -1,29 +1,54 @@
-
+
-
+
-
+
-
-
-
+
+
diff --git a/addons/account/project/report/analytic_balance.rml b/addons/account/project/report/analytic_balance.rml
deleted file mode 100644
index 1754988f7d6..00000000000
--- a/addons/account/project/report/analytic_balance.rml
+++ /dev/null
@@ -1,234 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Code
-
-
- Account Name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Quantity
-
-
-
-
-
-
-
-
- Analytic Balance - [[ company.currency_id.name ]]
-
-
-
-
-
-
-
-
-
- Code
-
-
- Account Name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Quantity
-
-
-
-
-
-
- Total
-
-
-
-
-
-
-
- [[ formatLang(sum_all(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'],'debit')) ]]
-
-
- [[ formatLang(sum_all(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'],'credit')) ]]
-
-
- [[ formatLang(sum_balance(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]
-
-
- [[ formatLang(sum_all(get_objects(data['form']['empty_acc']),data['form']['date1'],data['form']['date2'],'quantity')) ]]
-
-
-
-
- [[ repeatIn(get_objects(data['form']['empty_acc']),'o') ]]
-
-
-
- [[ o['code'] ]]
-
-
- [[ o['complete_name'] ]]
-
-
- [[ formatLang(move_sum(o['id'],data['form']['date1'],data['form']['date2'],'debit')) ]]
-
-
- [[ formatLang(move_sum(o['id'],data['form']['date1'],data['form']['date2'],'credit')) ]]
-
-
- [[ formatLang(move_sum_balance(o['id'],data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]
-
-
- [[ formatLang(move_sum(o['id'],data['form']['date1'],data['form']['date2'],'quantity')) ]]
-
-
-
-
- [[ repeatIn(lines_g(o['id'],data['form']['date1'],data['form']['date2']),'move_g') ]]
-
-
-
- [[ move_g['code'] ]]
-
-
- [[ move_g['name'] ]]
-
-
- [[ formatLang(move_g['debit'])]]
-
-
- [[ formatLang(move_g['credit']) ]]
-
-
- [[ formatLang(move_g['balance'], currency_obj = company.currency_id) ]]
-
-
- [[ formatLang(move_g['quantity']) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addons/account/project/report/analytic_journal.rml b/addons/account/project/report/analytic_journal.rml
deleted file mode 100644
index 719851252b5..00000000000
--- a/addons/account/project/report/analytic_journal.rml
+++ /dev/null
@@ -1,346 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'o') ]]
-
-
-
- Analytic Journal
-
-
-
-
-
-
- Period from
-
-
- Period to
-
-
- Currency
-
-
-
-
-
-
- [[ formatLang(data['form']['date1'],date=True) ]]
-
-
- [[ formatLang(data['form']['date2'],date=True) ]]
-
-
- [[ company.currency_id.name ]]
-
-
-
-
-
-
-
-
-
- Date
-
-
- Code
-
-
- Move Name
-
-
- Account n°
-
-
- General
-
-
- Analytic
-
-
-
-
-
-
-
-
-
- [[ o.code ]] - [[ o.name ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ formatLang(sum_general(o.id,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang(sum_analytic(o.id,data['form']['date1'],data['form']['date2'])) ]]
-
-
-
-
-
-
-
- [[ repeatIn(lines(o.id,data['form']['date1'],data['form']['date2']), 'move') ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ move.name ]] KI
-
-
- [[ move.account_id.code ]] [[ move.account_id.name ]]
-
-
- [[ formatLang(move.debit-move.credit) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(lines_a(move.id,o.id,data['form']['date1'],data['form']['date2']),'move_a') ]]
-
-
-
- [[ (not move_a) and removeParentNode('blockTable') ]] [[ formatLang(move_a.date,date = True) ]]
-
-
- [[ move_a.code ]]
-
-
- [[ move_a.name ]]
-
-
- [[ move_a.account_id.code ]] - [[ move_a.account_id.name ]]
-
-
-
-
-
-
-
- [[ formatLang( move_a.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(lines_a(False,o.id,data['form']['date1'],data['form']['date2']),'move_a') ]]
-
-
-
- [[ (not move_a) and removeParentNode('blockTable') ]] [[ formatLang(move_a.date,date = True) ]]
-
-
- [[ move_a.code ]]
-
-
- [[ move_a.name ]]
-
-
- [[ move_a.account_id.code ]] - [[ move_a.account_id.name ]]
-
-
-
-
-
-
-
- [[ formatLang( move_a.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/project/report/cost_ledger.rml b/addons/account/project/report/cost_ledger.rml
deleted file mode 100644
index 1099a8b8b4e..00000000000
--- a/addons/account/project/report/cost_ledger.rml
+++ /dev/null
@@ -1,305 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Date/Code
-
-
- J.C. /Move name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
-
-
-
-
-
-
-
-
- Cost Ledger
-
-
-
-
-
-
-
-
-
-
-
- Period from
-
-
- Period to
-
-
- Printing date
-
-
-
-
-
-
- [[ formatLang(data['form']['date1'],date = True) ]]
-
-
- [[ formatLang(data['form']['date2'],date = True) ]]
-
-
- [[ formatLang(time.strftime('%Y-%m-%d %H:%M:%S'),date_time = True) ]]
-
-
-
-
-
-
-
-
-
- Date/Code
-
-
- J.C. /Move name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
-
-
- Total:
-
-
-
-
-
-
-
- [[ formatLang (sum_debit(objects,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang (sum_credit(objects,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang (sum_balance(objects,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id) ]]
-
-
-
-
- [[ repeatIn(objects,'account') ]]
-
-
-
- [[ account.code ]]
-
-
- [[ account.complete_name ]]
-
-
- [[ formatLang (account_sum_debit(account,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang (account_sum_credit(account,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang (account_sum_balance(account,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id) ]]
-
-
-
-
- [[ repeatIn(lines_g(account,data['form']['date1'],data['form']['date2']),'move_g') ]]
-
-
-
- [[ move_g['code'] ]]
-
-
- [[ move_g['name'] ]]
-
-
- [[ formatLang( move_g['debit']) ]]
-
-
- [[ formatLang( move_g['credit']) ]]
-
-
- [[ formatLang( move_g['balance'], currency_obj = company.currency_id) ]]
-
-
-
-
- [[ repeatIn(lines_a(move_g,account,data['form']['date1'],data['form']['date2']),'move_a') ]]
-
-
-
- [[ formatLang(move_a['date'],date = True) ]]
-
-
- [[ move_a['cj'] ]]
-
-
- [[ move_a['name'] ]]
-
-
- [[ formatLang( move_a['debit'] )]]
-
-
- [[ formatLang( move_a['credit']) ]]
-
-
- [[ formatLang( move_a['balance'], currency_obj = company.currency_id)]]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/project/report/inverted_analytic_balance.rml b/addons/account/project/report/inverted_analytic_balance.rml
deleted file mode 100644
index 54b6878c407..00000000000
--- a/addons/account/project/report/inverted_analytic_balance.rml
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Code
-
-
- Name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Quantity
-
-
-
-
-
-
-
- Inverted Analytic Balance - [[ company.currency_id.name ]]
-
-
-
-
-
-
-
-
-
- Code
-
-
- Name
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Quantity
-
-
-
-
-
-
-
-
-
- Total
-
-
-
-
-
-
-
- [[ formatLang(sum_debit(objects,data['form']['date1'],data['form']['date2'])) ]]
-
-
- [[ formatLang(sum_credit(objects,data['form']['date1'],data['form']['date2']))]]
-
-
- [[ formatLang(sum_balance(objects,data['form']['date1'],data['form']['date2']), currency_obj = company.currency_id)]]
-
-
- [[ formatLang(sum_quantity(objects,data['form']['date1'],data['form']['date2'])) ]]
-
-
-
-
- [[ repeatIn(lines_g(objects,data['form']['date1'],data['form']['date2']),'move_g') ]]
-
-
-
- [[ (not move_g) and removeParentNode('blockTable') ]] [[ move_g['code'] ]]
-
-
- [[ move_g['name'] ]]
-
-
- [[ formatLang(move_g['debit'])]]
-
-
- [[formatLang(move_g['credit'])]]
-
-
- [[ formatLang(move_g['balance'], currency_obj = company.currency_id)]]
-
-
- [[formatLang(move_g['quantity']) ]]
-
-
-
-
- [[ repeatIn(lines_a(objects,move_g['id'],data['form']['date1'],data['form']['date2']),'move_a') ]]
-
-
-
- [[ (not move_a) and removeParentNode('blockTable') ]] [[ move_a['code'] ]]
-
-
- [[ move_a['complete_name'] ]]
-
-
- [[ formatLang(move_a['debit']) ]]
-
-
- [[ formatLang(move_a['credit']) ]]
-
-
- [[ formatLang(move_a['balance'], currency_obj = company.currency_id)]]
-
-
- [[ formatLang(move_a['quantity']) ]]
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addons/account/project/report/quantity_cost_ledger.rml b/addons/account/project/report/quantity_cost_ledger.rml
deleted file mode 100644
index 9f99f50ccc2..00000000000
--- a/addons/account/project/report/quantity_cost_ledger.rml
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Code/Date
-
-
- J.C./Move name
-
-
- Quantity
-
-
- Total
-
-
-
-
-
-
-
-
-
-
-
-
- Cost Ledger
-
-
-
-
-
-
-
-
-
-
-
- Period from
-
-
- Period to
-
-
- Printing date
-
-
-
-
-
-
- [[ formatLang(data['form']['date1'],date = True) ]]
-
-
- [[ formatLang(data['form']['date2'],date = True) ]]
-
-
- [[ formatLang(time.strftime('%Y-%m-%d %H:%M:%S'),date_time = True) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Code/Date
-
-
- J.C./Move name
-
-
- Quantity
-
-
- Total
-
-
-
-
-
-
- Total:
-
-
-
-
-
-
-
-
-
-
-
-
- [[ formatLang (sum_quantity(objects,data['form']['date1'],data['form']['date2'], data['form']['journal']) ) ]]
-
-
-
-
- [[ repeatIn(objects,'o') ]]
-
-
-
- [[ o.code ]]
-
-
- [[ o.complete_name ]]
-
-
- Max Qty: [[ formatLang (o.quantity_max )]]
-
-
- [[ formatLang (account_sum_quantity(o.id,data['form']['date1'],data['form']['date2'], data['form']['journal']) )]]
-
-
-
-
- [[ repeatIn(lines_g(o.id,data['form']['date1'],data['form']['date2'],data['form']['journal']),'move_g') ]]
-
-
-
- [[ move_g['code'] ]]
-
-
- [[ move_g['name'] ]]
-
-
- [[ formatLang (move_g['quantity']) ]]
-
-
-
-
-
-
- [[ repeatIn(lines_a(move_g['id'],o.id,data['form']['date1'],data['form']['date2'],data['form']['journal']),'move_a') ]]
- [[ formatLang(move_a['date'],date = True) ]]
-
-
- [[ move_a['cj'] ]]
-
-
- [[ move_a['name'] ]]
-
-
- [[ formatLang (move_a['quantity'] )]]
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addons/account/project/views/report_analyticbalance.xml b/addons/account/project/views/report_analyticbalance.xml
new file mode 100644
index 00000000000..96f692eda3d
--- /dev/null
+++ b/addons/account/project/views/report_analyticbalance.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
Analytic Balance -
+
+
+
+
+ Code
+ Account Name
+ Debit
+ Credit
+ Balance
+ Quantity
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/project/views/report_analyticcostledger.xml b/addons/account/project/views/report_analyticcostledger.xml
new file mode 100644
index 00000000000..fd99c637411
--- /dev/null
+++ b/addons/account/project/views/report_analyticcostledger.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
Cost Ledger
+
+
+
+
+
+
+ Date/Code
+ J.C. /Move
+ Name
+ Debit
+ Credit
+ Balance
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/account/project/views/report_analyticcostledgerquantity.xml b/addons/account/project/views/report_analyticcostledgerquantity.xml
new file mode 100644
index 00000000000..1098a7627f3
--- /dev/null
+++ b/addons/account/project/views/report_analyticcostledgerquantity.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
Cost Ledger
+
+
+
+
+
+
+ Date/Code
+ J.C./Move
+ Name
+ Quantity
+ Total
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Max quantity :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/account/project/views/report_analyticjournal.xml b/addons/account/project/views/report_analyticjournal.xml
new file mode 100644
index 00000000000..ce2f216e419
--- /dev/null
+++ b/addons/account/project/views/report_analyticjournal.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
Analytic Journal
+
+
+
+
+
+
+ Date
+ Code
+ Move Name
+ Account n°
+ General
+ Analytic
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/project/views/report_invertedanalyticbalance.xml b/addons/account/project/views/report_invertedanalyticbalance.xml
new file mode 100644
index 00000000000..7ed8f4f84f3
--- /dev/null
+++ b/addons/account/project/views/report_invertedanalyticbalance.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
Inverted Analytic Balance -
+
+
+
+
+ Code
+ Account Name
+ Debit
+ Credit
+ Balance
+ Quantity
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/project/wizard/account_analytic_balance_report.py b/addons/account/project/wizard/account_analytic_balance_report.py
index 02b2eb6e95d..3a3c301cffc 100644
--- a/addons/account/project/wizard/account_analytic_balance_report.py
+++ b/addons/account/project/wizard/account_analytic_balance_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_analytic_balance(osv.osv_memory):
_name = 'account.analytic.balance'
_description = 'Account Analytic Balance'
@@ -42,16 +43,13 @@ class account_analytic_balance(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.analytic.account',
- 'form': data
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.balance',
- 'datas': datas,
- }
+ 'ids': context.get('active_ids', []),
+ 'model': 'account.analytic.account',
+ 'form': data
+ }
+ datas['form']['active_ids'] = context.get('active_ids', False)
+
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticbalance', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
index 814cbb8cacc..b3c2d1bec12 100644
--- a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_analytic_cost_ledger_journal_report(osv.osv_memory):
_name = 'account.analytic.cost.ledger.journal.report'
_description = 'Account Analytic Cost Ledger For Journal Report'
@@ -42,14 +43,13 @@ class account_analytic_cost_ledger_journal_report(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.analytic.account',
- 'form': data
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.quantity_cost_ledger',
- 'datas': datas,
- }
+ 'ids': context.get('active_ids', []),
+ 'model': 'account.analytic.account',
+ 'form': data
+ }
+
+ datas['form']['active_ids'] = context.get('active_ids', False)
+
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticcostledgerquantity', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_cost_ledger_report.py b/addons/account/project/wizard/account_analytic_cost_ledger_report.py
index ffd56352382..5f00c3c9ac5 100644
--- a/addons/account/project/wizard/account_analytic_cost_ledger_report.py
+++ b/addons/account/project/wizard/account_analytic_cost_ledger_report.py
@@ -20,9 +20,9 @@
##############################################################################
import time
-
from openerp.osv import osv, fields
+
class account_analytic_cost_ledger(osv.osv_memory):
_name = 'account.analytic.cost.ledger'
_description = 'Account Analytic Cost Ledger'
@@ -42,14 +42,13 @@ class account_analytic_cost_ledger(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.analytic.account',
- 'form': data
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.cost_ledger',
- 'datas': datas,
- }
+ 'ids': context.get('active_ids',[]),
+ 'model': 'account.analytic.account',
+ 'form': data
+ }
+
+ datas['form']['active_ids'] = context.get('active_ids', False)
+
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticcostledger', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_inverted_balance_report.py b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
index 9e54f4f848d..3b03ad2da56 100644
--- a/addons/account/project/wizard/account_analytic_inverted_balance_report.py
+++ b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_analytic_inverted_balance(osv.osv_memory):
_name = 'account.analytic.inverted.balance'
_description = 'Account Analytic Inverted Balance'
@@ -41,14 +42,13 @@ class account_analytic_inverted_balance(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.analytic.account',
- 'form': data
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.inverted.balance',
- 'datas': datas,
- }
+ 'ids': context.get('active_ids', []),
+ 'model': 'account.analytic.account',
+ 'form': data
+ }
+
+ datas['form']['active_ids'] = context.get('active_ids', False)
+
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_invertedanalyticbalance', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_journal_report.py b/addons/account/project/wizard/account_analytic_journal_report.py
index 61fe2cd318a..ab7e553435d 100644
--- a/addons/account/project/wizard/account_analytic_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_journal_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_analytic_journal_report(osv.osv_memory):
_name = 'account.analytic.journal.report'
_description = 'Account Analytic Journal'
@@ -49,16 +50,12 @@ class account_analytic_journal_report(osv.osv_memory):
for analytic_record in record.analytic_account_journal_id:
ids_list.append(analytic_record.id)
datas = {
- 'ids': ids_list,
- 'model': 'account.analytic.journal',
- 'form': data
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.journal',
- 'datas': datas,
- }
-
+ 'ids': ids_list,
+ 'model': 'account.analytic.journal',
+ 'form': data
+ }
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticjournal', data=datas, context=context)
+
def default_get(self, cr, uid, fields, context=None):
if context is None:
context = {}
diff --git a/addons/account/report/__init__.py b/addons/account/report/__init__.py
index 544aa9e262e..ed8cc0aa8b3 100644
--- a/addons/account/report/__init__.py
+++ b/addons/account/report/__init__.py
@@ -26,12 +26,8 @@ import account_balance
import account_partner_balance
import account_general_ledger
import account_partner_ledger
-#import invoice
-import account_print_invoice
-#import overdue
import account_print_overdue
import account_aged_partner_balance
-#import tax_report
import report_vat
import account_invoice_report
import account_report
diff --git a/addons/account/report/account_aged_partner_balance.rml b/addons/account/report/account_aged_partner_balance.rml
deleted file mode 100644
index 5b5404e9c86..00000000000
--- a/addons/account/report/account_aged_partner_balance.rml
+++ /dev/null
@@ -1,285 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Aged Trial Balance
-
-
-
-
-
-
- Chart of Accounts
-
-
- Fiscal Year
-
-
- Start Date
-
-
- Period Length(days)
-
-
- Partner's
-
-
- Analysis Direction
-
-
- Target Moves
-
-
-
-
- [[ get_account(data) or '' ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- [[ formatLang(data['form']['date_from'],date=True) ]]
-
-
- [[ data['form']['period_length'] ]]
-
-
- Receivable Accounts[[ data['form']['result_selection'] == 'customer' or removeParentNode('para') ]]
- Payable Accounts[[ data['form']['result_selection'] == 'supplier' or removeParentNode('para') ]]
- Receivable and Payable Accounts[[ data['form']['result_selection'] == 'customer_supplier' or removeParentNode('para') ]]
-
-
- [[ data['form']['direction_selection'] ]]
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
-
- Partners
-
-
- Due[[ data['form']['direction_selection'] == 'future' and ' ' or removeParentNode('para') ]]
- Not due[[ data['form']['direction_selection'] != 'future' and ' ' or removeParentNode('para') ]]
-
-
- [[ data['form']['4']['name'] ]]
-
-
- [[ data['form']['3']['name'] ]]
-
-
- [[ data['form']['2']['name'] ]]
-
-
- [[ data['form']['1']['name'] ]]
-
-
- [[ data['form']['0']['name'] ]]
-
-
- Total
-
-
-
-
-
-
- [[ (get_lines(data['form']), 'partner') == False or removeParentNode('para') ]]
- [[ (get_lines_with_out_partner(data['form']), 'not_partner') == False or removeParentNode('para') ]]
- Account Total
-
-
- [[ formatLang(get_direction('6'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_for_period('4'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_for_period('3'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_for_period('2'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_for_period('1'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_for_period('0'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(get_total('5'), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ repeatIn(get_lines(data['form']), 'partner') ]]
- [[ partner['name'] ]]
-
-
- [[ formatLang(partner['direction'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['4'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['3'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['2'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['1'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['0'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(partner['total'], currency_obj=company.currency_id) ]]
-
-
-
-
- [[ repeatIn(get_lines_with_out_partner(data['form']), 'not_partner') ]]
- [[ not_partner['name'] ]]
-
-
- [[ formatLang(not_partner['direction'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['4'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['3'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['2'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['1'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['0'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(not_partner['total'], currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_balance.rml b/addons/account/report/account_balance.rml
deleted file mode 100644
index 08c05c65fa8..00000000000
--- a/addons/account/report/account_balance.rml
+++ /dev/null
@@ -1,313 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Trial Balance
-
-
-
-
-
-
-
-
-
-
-
-
- Company[[ data['model']=='account.account' and ' ' or removeParentNode('para') ]]
- Chart of Accounts[[ data['model']=='ir.ui.menu' and ' ' or removeParentNode('para') ]]
-
-
- Fiscal Year
-
-
- Display Account
-
-
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
-
-
- Target Moves
-
-
-
-
- [[ get_account(data) or '' ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- All[[ data['form']['display_account']=='all' and ' ' or removeParentNode('para') ]]
- With movements[[ data['form']['display_account']=='movement' and ' ' or removeParentNode('para') ]]
- With balance is not equal to 0[[ data['form']['display_account']=='not_zero' and ' ' or removeParentNode('para') ]]
-
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- Start Date
-
-
- End Date
-
-
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
-
-
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- Start Period
-
-
- End Period
-
-
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
-
-
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
-
-
-
- Code
- Account
- Debit
- Credit
- Balance
-
-
- [[ repeatIn(lines(data['form']), 'a') ]][[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]] [[ a['code'] or removeParentNode('tr') ]]
- [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]] [[ '..'*(a['level']-1) ]] [[ a['name'] ]]
- [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]] [[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['debit']) ]] [[ a['type']<>'view' and removeParentNode('font') ]] [[formatLang(a['debit']) ]]
- [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font')]] [[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['credit']) ]] [[ a['type']<>'view' and removeParentNode('font') ]] [[ formatLang(a['credit']) ]]
- [[ (a['type']<>'view' and setTag('para','para',{'fontName':"Helvetica"})) or removeParentNode('font') ]] [[ a['type']=='view' and removeParentNode('font') ]][[ formatLang(a['balance'], currency_obj=company.currency_id) ]] [[ a['type']<>'view' and removeParentNode('font') ]] [[ formatLang(a['balance'], currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_central_journal.rml b/addons/account/report/account_central_journal.rml
deleted file mode 100644
index 6d350b5fe8f..00000000000
--- a/addons/account/report/account_central_journal.rml
+++ /dev/null
@@ -1,338 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects, 'o') ]]
-
-
-
-
- Centralized Journal
-
-
-
-
-
- Chart of Accounts
- Fiscal Year
- Journal
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
- Target Moves
-
-
- [[ get_account(data) or removeParentNode('para') ]]
- [[ get_fiscalyear(data) or '' ]]
- [[o.journal_id.name ]]
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
- Start Date
- End Date
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
- Start Period
- End Period
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
- A/C No.
- Account Name
- Debit
- Credit
- Balance
-
-
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
- A/C No.
- Account Name
- Debit
- Credit
- Balance
- Currency
-
-
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
- Total:
-
- [[ formatLang( sum_debit(o.period_id.id, o.journal_id.id)) ]]
- [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)) ]]
- [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id ) ]]
-
-
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
- Total:
-
- [[ formatLang( sum_debit(o.period_id.id, o.journal_id.id)) ]]
- [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)) ]]
- [[ formatLang( sum_credit(o.period_id.id, o.journal_id.id)-sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id ) ]]
-
-
-
-
- [[ repeatIn(lines(o.period_id.id,o.journal_id.id),'line') ]]
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
- [[ line['code'] ]]
- [[ line['name'] ]]
- [[ formatLang(line['debit']) ]]
- [[ formatLang(line['credit'])]]
- [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]]
-
-
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
- [[ line['code'] ]]
- [[ line['name'] ]]
- [[ formatLang(line['debit']) ]]
- [[ formatLang(line['credit'])]]
- [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]]
- [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]]
-
-
-
-
-
-
diff --git a/addons/account/report/account_financial_report.rml b/addons/account/report/account_financial_report.rml
deleted file mode 100644
index 7949077e43f..00000000000
--- a/addons/account/report/account_financial_report.rml
+++ /dev/null
@@ -1,303 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ data['form']['account_report_id'][1] ]]
-
-
-
-
-
-
-
-
-
- Chart of Accounts
- Fiscal Year
- Filter By [[ get_filter(data)!='No Filters' and get_filter(data) ]]
- Target Moves
-
-
- [[ get_account(data) or removeParentNode('para') ]]
- [[ get_fiscalyear(data) or '' ]]
- [[ get_filter(data)=='No Filters' 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') ]]
-
-
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- [[ data['form']['debit_credit'] == 1 or removeParentNode('blockTable') ]]
-
-
- Name
-
-
- Debit
-
-
- Credit
-
-
- 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.get('level')))+'_name'}) ]][[ a.get('name') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('debit',0.0), currency_obj = company.currency_id) ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('credit',0.0), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') =='view' and a.get('level') <> 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') <>'view' or a.get('level') == 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
-
-
-
-
-
- [[ (not data['form']['enable_filter'] and not data['form']['debit_credit']) 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.get('level')))+'_name'}) ]][[ a.get('name') ]]
- [[ (a.get('account_type') =='view' and a.get('level') <> 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') <>'view' or a.get('level') == 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
-
-
-
-
-
-
-
-
- [[ (data['form']['enable_filter'] == 1 and not data['form']['debit_credit']) 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.get('level')))+'_name'}) ]][[ a.get('name') ]]
- [[ (a.get('account_type') =='view' and a.get('level') <> 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') <>'view' or a.get('level') == 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance'), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') =='view' and a.get('level') <> 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance_cmp'), currency_obj = company.currency_id) ]]
- [[ (a.get('account_type') <>'view' or a.get('level') == 1) or removeParentNode('td') ]]
- [[ setTag('para','para',{'style': 'terp_level_'+str(min(6,a.get('level')))+'_balance'}) ]][[ formatLang(a.get('balance_cmp'), currency_obj = company.currency_id) ]]
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_general_journal.rml b/addons/account/report/account_general_journal.rml
deleted file mode 100644
index dce30e59918..00000000000
--- a/addons/account/report/account_general_journal.rml
+++ /dev/null
@@ -1,387 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn( periods(objects), 'o') ]]
-
-
-
-
-
-
-
-
-
- General Journal
-
-
-
-
-
-
-
-
-
-
- Company[[ data['model']=='account.journal.period' and ' ' or removeParentNode('para') ]]
- Chart of Accounts[[ data['model']=='ir.ui.menu' and ' ' or removeParentNode('para') ]]
- Fiscal Year
- Journals
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
- Target Moves
-
-
- [[ get_account(data) or removeParentNode('para') ]]
- [[ get_fiscalyear(data) or '' ]]
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
- Start Date
- End Date
-
-
- [[ formatLang(get_start_date(data),date=True)]]
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
- Start Period
- End Period
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
- [[ display_currency(data)==False or removeParentNode('blockTable') ]]
-
- Code
- Journal Name
- Debit
- Credit
- Balance
-
-
- Total:
-
- [[ formatLang(sum_debit()) ]]
- [[ formatLang( sum_credit()) ]]
- [[ formatLang( sum_debit()- sum_credit(), currency_obj=company.currency_id) ]]
-
-
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
- Code
- Journal Name
- Debit
- Credit
- Balance
- Currency
-
-
- Total:
-
- [[ formatLang(sum_debit()) ]]
- [[ formatLang( sum_credit()) ]]
- [[ formatLang( sum_credit()- sum_debit(), currency_obj=company.currency_id) ]]
-
-
-
-
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
-
- [[ o.name ]] :
-
-
-
-
-
-
- [[ formatLang(sum_debit_period(o.id)) ]]
-
-
- [[ formatLang(sum_credit_period(o.id)) ]]
-
-
- [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
- [[ display_currency(data)==False or removeParentNode('blockTable') ]]
-
-
- [[ o.name ]] :
-
-
-
-
-
-
- [[ formatLang(sum_debit_period(o.id)) ]]
-
-
- [[ formatLang(sum_credit_period(o.id)) ]]
-
-
- [[ formatLang(sum_credit_period(o.id)-sum_debit_period(o.id), currency_obj=company.currency_id) ]]
-
-
-
-
- [[ repeatIn(lines(o.id),'line')]]
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
-
- [[ line['code'] ]]
-
-
- [[ line['name'] ]]
-
-
- [[ formatLang(line['debit'] )]]
-
-
- [[ formatLang(line['credit']) ]]
-
-
- [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]]
-
-
-
-
-
- [[ repeatIn(lines(o.id),'line')]]
- [[ display_currency(data) or removeParentNode('blockTable') ]]
-
- [[ line['code'] ]]
- [[ line['name'] ]]
- [[ formatLang(line['debit'] )]]
- [[ formatLang(line['credit']) ]]
- [[ formatLang(line['credit']-line['debit'], currency_obj=company.currency_id ) ]]
- [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_general_ledger.rml b/addons/account/report/account_general_ledger.rml
deleted file mode 100644
index 6897e15078d..00000000000
--- a/addons/account/report/account_general_ledger.rml
+++ /dev/null
@@ -1,619 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- Date
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
- [[ repeatIn(objects, 'a') ]]
- General Ledger
-
-
-
-
-
-
- Chart of Accounts
-
-
- Fiscal Year
-
-
- Journals
-
-
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
-
-
- Target Moves
-
-
-
-
-
-
- [[ get_account(data) or '' ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
-
-
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- Start Date
-
-
- End Date
-
-
-
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
-
-
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- Start Period
-
-
- End Period
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
-
-
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- Date
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
- [[ repeatIn(get_children_accounts(a), 'o') ]]
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- [[ '..'*(o.level-1) ]] [[ o.code ]] [[ o.name ]]
-
-
- [[ formatLang(sum_debit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]]
-
-
- [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account'),currency_obj=o.currency_id) or '' ]]
-
-
-
-
- [[ repeatIn(lines(o), 'line') ]]
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- [[ formatLang(line['ldate'],date=True) ]]
-
-
- [[ line['lcode'] ]]
-
-
- [[ strip_name(line['partner_name'],10) ]]
-
-
- [[ line['lref'] and strip_name(line['lref'],9) ]]
-
-
- [[ strip_name(line['move'],9) ]]
-
-
- [[ strip_name(line['lname'],10) ]]
-
-
- [[ strip_name(line['line_corresp'].replace(', ',','),10) ]]
-
-
- [[ formatLang(line['debit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]]
-
-
- [[ (line.has_key('currency_id') and line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'])]] [[ line['currency_code'] or '']]
-
-
-
-
-
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
- [[ repeatIn(get_children_accounts(a), 'o') ]]
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- [[ '..'*(o.level-1) ]] [[ o.code ]] [[ o.name ]]
-
-
- [[ formatLang(sum_debit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]]
-
-
-
-
- [[ repeatIn(lines(o), 'line') ]]
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(line['ldate'],date=True) ]]
-
-
- [[ line['lcode'] ]]
-
-
- [[ strip_name(line['partner_name'],20) ]]
-
-
- [[ line['lref'] and strip_name(line['lref'],9) ]]
-
-
- [[ strip_name(line['move'],9) ]]
-
-
- [[ strip_name(line['lname'],18) ]]
-
-
- [[ strip_name(line['line_corresp'].replace(', ',','),20) ]]
-
-
- [[ formatLang(line['debit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_general_ledger_landscape.rml b/addons/account/report/account_general_ledger_landscape.rml
deleted file mode 100644
index c5d24343148..00000000000
--- a/addons/account/report/account_general_ledger_landscape.rml
+++ /dev/null
@@ -1,658 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- Date
-
-
- Period
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- Period
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
- [[ repeatIn(objects, 'a') ]]
- General Ledger
-
-
-
-
-
-
- Company[[ data['model']=='account.account' and ' ' or removeParentNode('para') ]]
- Chart of Accounts[[ data['model']=='ir.ui.menu' and ' ' or removeParentNode('para') ]]
-
- Fiscal Year
-
-
- Journals
-
-
- Display Account
-
-
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
-
-
- Entries Sorted By
-
-
- Target Moves
-
-
-
-
-
-
- [[ get_account(data) or removeParentNode('para') ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
-
-
- All[[ data['form']['display_account']=='all' and ' ' or removeParentNode('para') ]]
- With movements[[ data['form']['display_account']=='movement' and ' ' or removeParentNode('para') ]]
- With balance is not equal to 0[[ data['form']['display_account']=='not_zero' and ' ' or removeParentNode('para') ]]
-
-
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- Start Date
-
-
- End Date
-
-
-
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
-
-
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- Start Period
-
-
- End Period
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
-
-
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
-
-
- [[ get_sortby(data) ]]
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- Date
-
-
- Period
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
- [[ repeatIn(get_children_accounts(a), 'o') ]]
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- [[ '..'*(o.level-1) ]] [[ o.code ]] [[ o.name ]]
-
-
- [[ formatLang(sum_debit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'), currency_obj= company.currency_id) ]]
-
-
- [[ o.currency_id and formatLang(sum_currency_amount_account(o), digits=get_digits(dp='Account'),currency_obj=o.currency_id) or '' ]]
-
-
-
-
- [[ repeatIn(lines(o), 'line') ]]
- [[data['form']['amount_currency'] == True or removeParentNode('blockTable')]]
-
-
- [[ formatLang(line['ldate'],date=True) ]]
-
-
- [[ line['period_code'] ]]
-
-
- [[ line['lcode'] ]]
-
-
- [[ strip_name(line['partner_name'],20) ]]
-
-
- [[ line['lref'] and strip_name(line['lref'],17) ]]
-
-
- [[ line['move'] ]]
-
-
- [[ strip_name(line['lname'],22) ]]
-
-
- [[ strip_name(line['line_corresp'],18) ]]
-
-
- [[ formatLang(line['debit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['progress'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ (line.has_key('currency_id') and line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'])]] [[ line['currency_code'] or '']]
-
-
-
-
-
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- Period
-
-
- JRNL
-
-
- Partner
-
-
- Ref
-
-
- Move
-
-
- Entry Label
-
-
- Counterpart
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
- [[ repeatIn(get_children_accounts(a), 'o') ]]
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- [[ '..'*(o.level-1) ]] [[ o.code ]] [[ o.name ]]
-
-
- [[ formatLang(sum_debit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_credit_account(o), digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(sum_balance_account(o), digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
-
-
- [[ repeatIn(lines(o), 'line') ]]
- [[ data['form']['amount_currency'] == False or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(line['ldate'],date=True) ]]
-
-
- [[ line['period_code'] ]]
-
-
- [[ line['lcode'] ]]
-
-
- [[ strip_name(line['partner_name'],24) ]]
-
-
- [[ strip_name(line['lref'],21) ]]
-
-
- [[ line['move'] ]]
-
-
- [[ strip_name(line['lname'],28) ]]
-
-
- [[ strip_name(line['line_corresp'],23) ]]
-
-
- [[ formatLang(line['debit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['credit'], digits=get_digits(dp='Account')) ]]
-
-
- [[ formatLang(line['progress'], digits=get_digits(dp='Account'),currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_journal.rml b/addons/account/report/account_journal.rml
deleted file mode 100644
index 6d606ed1937..00000000000
--- a/addons/account/report/account_journal.rml
+++ /dev/null
@@ -1,311 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects, 'o') ]]
-
-
-
- Journal
-
-
-
-
-
-
-
- Company[[ data['model']=='account.journal.period'and ' ' or removeParentNode('para') ]]
- Chart of Accounts[[ data['model']=='ir.ui.menu' and ' ' or removeParentNode('para') ]]
- Fiscal Year
- Journal
- Period
- Entries Sorted By
- Target Moves
-
-
- [[ get_account(data) or '' ]]
- [[ get_fiscalyear(data) or '' ]]
- [[ o.journal_id.name ]]
- [[ o.period_id.name ]]
-
- Date[[ data['form'].get('sort_selection', 'date') == 'date' and ' ' or removeParentNode('para') ]]
- Reference Number[[ data['form'].get('sort_selection', 'date') == 'ref' and ' ' or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
-
- [[ set_last_move_id(False)]]
-
- [[ display_currency(data) == False or removeParentNode('section') ]]
-
-
- Move
- Date
- Account
- Partner
- Label
- Debit
- Credit
-
-
-
- [[ repeatIn(lines(o.period_id.id, o.journal_id.id), 'line') ]]
-
-
- [[ not check_last_move_id(line.move_id.id) and removeParentNode('blockTable') ]]
-
-
-
-
- [[ line.move_id.name <> '/' and line.move_id.name or ('*'+str(line.move_id.id)) ]]
- [[ formatLang(line.date,date=True) ]]
- [[ line.account_id.code ]]
- [[ line.partner_id and strip_name(line.partner_id.name,23) ]]
- [[ strip_name(line.name,35) ]]
- [[ formatLang(line.debit, currency_obj=company.currency_id) ]]
- [[ formatLang(line.credit, currency_obj=company.currency_id) ]]
-
-
- [[ set_last_move_id(line.move_id.id) ]]
-
-
-
-
-
-
-
- Total:
- [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
- [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ display_currency(data) or removeParentNode('section') ]]
-
-
- Move
- Date
- Account
- Partner
- Label
- Debit
- Credit
- Currency
-
-
-
- [[ repeatIn(lines(o.period_id.id, o.journal_id.id), 'line') ]]
-
-
- [[ not check_last_move_id(line.move_id.id) and removeParentNode('blockTable') ]]
-
-
-
-
- [[ line.move_id.name <> '/' and line.move_id.name or ('*'+str(line.move_id.id)) ]]
- [[ formatLang(line.date,date=True) ]]
- [[ line.account_id.code ]]
- [[ line.partner_id and strip_name(line.partner_id.name,17) ]]
- [[ strip_name(line.name,28) ]]
- [[ formatLang(line.debit, currency_obj=company.currency_id) ]]
- [[ formatLang(line.credit, currency_obj=company.currency_id) ]]
- [[ line.currency_id and formatLang(line.amount_currency, currency_obj=line.currency_id) or '' ]]
-
-
- [[ set_last_move_id(line.move_id.id) ]]
-
-
-
-
-
-
-
- Total:
- [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
- [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_journal_sale_purchase.rml b/addons/account/report/account_journal_sale_purchase.rml
deleted file mode 100644
index 3ee0b484c9a..00000000000
--- a/addons/account/report/account_journal_sale_purchase.rml
+++ /dev/null
@@ -1,346 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects, 'o') ]]
-
-
-
- Journal
-
-
-
-
-
-
-
- [[ data['model']=='account.journal.period'and 'Company' or removeParentNode('para') ]]
- [[ data['model']=='ir.ui.menu' and 'Chart of Accounts' or removeParentNode('para') ]]
- Fiscal Year
- Journal
- Period
- Entries Sorted By
- Target Moves
-
-
- [[ get_account(data) or '' ]]
- [[ get_fiscalyear(data) or '' ]]
- [[ o.journal_id.name ]]
- [[ o.period_id.name ]]
- [[ get_sortby(data) ]]
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
- [[ set_last_move_id(False) ]]
-
- [[ display_currency(data) == False or removeParentNode('section') ]]
-
-
- Move
- Date
- Account
- Partner
- Label
- Tax
-
- Debit
- Credit
-
-
-
- [[ repeatIn(lines(o.period_id.id, o.journal_id.id), 'line') ]]
-
-
- [[ not check_last_move_id(line.move_id.id) and removeParentNode('blockTable') ]]
-
-
-
-
- [[ line.move_id.name <> '/' and line.move_id.name or ('*'+str(line.move_id.id)) ]]
- [[ formatLang(line.date,date=True) ]]
- [[ line.account_id.code ]]
- [[ line.partner_id and strip_name(line.partner_id.name,15) ]]
- [[ strip_name(line.name,25) ]]
- [[ line.tax_code_id and line.tax_code_id.code and (line.tax_code_id.code + ':') ]]
- [[ line.tax_amount and formatLang(line.tax_amount, currency_obj=company.currency_id) ]]
- [[ formatLang(line.debit, currency_obj=company.currency_id) ]]
- [[ formatLang(line.credit, currency_obj=company.currency_id) ]]
-
-
- [[ set_last_move_id(line.move_id.id) ]]
-
-
-
-
-
-
-
-
-
- Total:
- [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
- [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ display_currency(data) or removeParentNode('section') ]]
-
-
- Move
- Date
- Account
- Partner
- Label
- Tax
-
- Debit
- Credit
- Currency
-
-
-
- [[ repeatIn(lines(o.period_id.id, o.journal_id.id), 'line') ]]
-
-
- [[ not check_last_move_id(line.move_id.id) and removeParentNode('blockTable') ]]
-
-
-
-
- [[ line.move_id.name <> '/' and line.move_id.name or ('*'+str(line.move_id.id)) ]]
- [[ formatLang(line.date,date=True) ]]
- [[ line.account_id.code ]]
- [[ line.partner_id and strip_name(line.partner_id.name,12) ]]
- [[ strip_name(line.name,16) ]]
- [[ line.tax_code_id and line.tax_code_id.code and (line.tax_code_id.code + ':') ]]
- [[ line.tax_amount and formatLang(line.tax_amount, currency_obj=company.currency_id) ]]
- [[ formatLang(line.debit, currency_obj=company.currency_id) ]]
- [[ formatLang(line.credit, currency_obj=company.currency_id) ]]
- [[ line.currency_id and formatLang(line.amount_currency, currency_obj=line.currency_id) or '' ]]
-
-
- [[ set_last_move_id(line.move_id.id) ]]
-
-
-
-
-
-
-
-
-
- Total:
- [[ formatLang(sum_debit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
- [[ formatLang(sum_credit(o.period_id.id, o.journal_id.id), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tax Declaration
-
-
-
-
- [[ repeatIn(tax_codes(o.period_id.id,o.journal_id.id), 't') ]][[ t.code + ': ' ]]
- [[ formatLang(sum_vat( o.period_id.id, o.journal_id.id, t.id)) ]]
-
- [[ t.name ]]
-
-
-
-
-
diff --git a/addons/account/report/account_partner_balance.rml b/addons/account/report/account_partner_balance.rml
deleted file mode 100644
index a99a7f062ec..00000000000
--- a/addons/account/report/account_partner_balance.rml
+++ /dev/null
@@ -1,257 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Partner Balance
-
-
-
-
-
-
-
-
- Chart of Accounts
- Fiscal Year
- Journals
- Filter By [[ data['form']['filter']!='filter_no' and get_filter(data) ]]
- Partner's
- Target Moves
-
-
- [[ get_account(data) or removeParentNode('para') ]]
- [[ get_fiscalyear(data) or '' ]]
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
-
- [[ data['form']['filter']=='filter_no' and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
- Start Date
- End Date
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
- Start Period
- End Period
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
- [[ get_partners() ]]
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
-
- Code
- (Account/Partner) Name
- Debit
- Credit
- Balance
- In dispute
-
-
- Total:
-
- [[ formatLang(sum_debit()) ]]
- [[ formatLang(sum_credit()) ]]
- [[ formatLang((sum_debit()-sum_credit()), currency_obj=company.currency_id) ]]
- [[ formatLang(sum_litige(), currency_obj=company.currency_id) ]]
-
-
- [[ repeatIn(lines(), 'a') ]][[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ a['ref'] ]] [[ a['type']==3 and a['code'] ]]
- [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ a['name'] ]]
- [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ formatLang(a['debit']) ]]
- [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ formatLang(a['credit']) ]]
- [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ formatLang(a['balance'], currency_obj=company.currency_id) ]]
- [[ (a['type']==3 and setTag('para','para',{'fontName':'Helvetica-Bold'})) or removeParentNode('font') ]] [[ formatLang(a['enlitige'] or 0.0, currency_obj=company.currency_id) ]]
-
-
-
-
diff --git a/addons/account/report/account_partner_ledger.rml b/addons/account/report/account_partner_ledger.rml
deleted file mode 100644
index 48ed6d4afe3..00000000000
--- a/addons/account/report/account_partner_ledger.rml
+++ /dev/null
@@ -1,658 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
- [[ repeatIn(objects, 'p') ]]
- [[ setLang(p.lang) ]]
-
-
-
- Partner Ledger
-
-
-
-
-
-
- Chart of Accounts
-
-
- Fiscal Year
-
-
- Journals
-
-
- Filters By [[ data['form']['filter'] not in ('filter_no','unreconciled') and get_filter(data) ]]
-
-
- Partner's
-
-
- Target Moves
-
-
-
-
-
-
- [[ get_account(data) or '' ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
-
-
- [[ data['form']['filter'] in ('filter_no','unreconciled') and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- Start Date
-
-
- End Date
-
-
-
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
-
-
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- Start Period
-
-
- End Period
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
-
-
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
- Receivable Accounts[[ data['form'].get('result_selection', 'customer') == 'customer' or removeParentNode('para') ]]
- Payable Accounts[[ data['form'].get('result_selection', 'customer') == 'supplier' or removeParentNode('para') ]]
- Receivable and Payable Accounts[[ data['form'].get('result_selection', 'customer') == 'customer_supplier' or removeParentNode('para') ]]
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
-
- [[ display_currency(data) == False or removeParentNode('section') ]]
-
-
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
-
-
- [[ p.ref ]] - [[ p.name ]]
-
-
- [[ formatLang((sum_debit_partner(p))) ]]
-
-
- [[ formatLang((sum_credit_partner(p))) ]]
-
-
- [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[data['form']['initial_balance']==True or removeParentNode('section') ]]
-
-
-
-
- Initial Balance
-
-
- [[ formatLang(get_intial_balance(p)[0][0])]]
-
-
- [[ formatLang(get_intial_balance(p)[0][1]) ]]
-
-
- [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ repeatIn(lines(p), 'line') ]]
-
-
-
- [[ formatLang(line['date'],date=True) ]]
-
-
- [[ line['code'] ]]
-
-
- [[ line['move_name'] ]]
-
-
- [[ line['a_code'] ]]
-
-
- [[ line['ref'] and strip_name(line['ref'],10) ]] - [[ strip_name(line['name'],15) ]]
-
-
- [[ formatLang((line['debit'])) ]]
-
-
- [[ formatLang((line['credit'])) ]]
-
-
- [[ formatLang((line['progress']), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
- [[ display_currency(data) == True or removeParentNode('section') ]]
-
-
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
-
-
- [[ p.ref ]] - [[ p.name ]]
-
-
- [[ formatLang((sum_debit_partner(p))) ]]
-
-
- [[ formatLang((sum_credit_partner(p))) ]]
-
-
- [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
- [[ data['form']['initial_balance']==True or removeParentNode('section') ]]
-
-
-
- Initial Balance
-
-
- [[ formatLang(get_intial_balance(p)[0][0])]]
-
-
- [[ formatLang(get_intial_balance(p)[0][1]) ]]
-
-
- [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(lines(p), 'line') ]]
-
-
-
- [[ formatLang(line['date'],date=True) ]]
-
-
- [[ line['code'] ]]
-
-
- [[ line['move_name'] ]]
-
-
- [[ line['a_code'] ]]
-
-
- [[ strip_name(line['ref'],8) ]] - [[ strip_name(line['name'],7) ]]
-
-
- [[ formatLang((line['debit'])) ]]
-
-
- [[ formatLang((line['credit'])) ]]
-
-
- [[ formatLang((line['progress']), currency_obj=company.currency_id) ]]
-
-
-
- [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]]
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_partner_ledger_other.rml b/addons/account/report/account_partner_ledger_other.rml
deleted file mode 100644
index b878ab44e47..00000000000
--- a/addons/account/report/account_partner_ledger_other.rml
+++ /dev/null
@@ -1,665 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
- [[ display_currency(data) == True or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
-
-
-
-
- Partner Ledger
-
-
-
-
-
-
- Chart of Accounts
-
-
- Fiscal Year
-
-
- Journals
-
-
- Filters By [[ data['form']['filter'] not in ('filter_no','unreconciled') and get_filter(data) ]]
-
-
- Partner's
-
-
- Target Moves
-
-
-
-
-
-
- [[ get_account(data) or '' ]]
-
-
- [[ get_fiscalyear(data) or '' ]]
-
-
- [[', '.join([ lt or '' for lt in get_journal(data) ]) ]]
-
-
- [[ data['form']['filter'] in ('filter_no','unreconciled') and get_filter(data) or removeParentNode('para') ]]
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- Start Date
-
-
- End Date
-
-
-
- [[ data['form']['filter']=='filter_date' or removeParentNode('blockTable') ]]
-
-
- [[ formatLang(get_start_date(data),date=True) ]]
-
-
- [[ formatLang(get_end_date(data),date=True) ]]
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- Start Period
-
-
- End Period
-
-
-
- [[ data['form']['filter']=='filter_period' or removeParentNode('blockTable') ]]
-
-
- [[ get_start_period(data) or removeParentNode('para') ]]
-
-
- [[ get_end_period(data) or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
- [[ get_partners() ]]
-
-
- [[ get_target_move(data) ]]
-
-
-
-
-
-
-
- [[ display_currency(data) == False or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
-
-
- [[ repeatIn(objects, 'p') ]]
- [[ setLang(p.lang) ]]
-
- [[ display_currency(data) == False or removeParentNode('section') ]]
-
-
-
-
-
- [[ p.ref ]] - [[ p.name ]]
-
-
- [[ formatLang((sum_debit_partner(p))) ]]
-
-
- [[ formatLang((sum_credit_partner(p))) ]]
-
-
- [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[data['form']['initial_balance']==True or removeParentNode('section') ]]
-
-
-
-
- Initial Balance
-
-
- [[ formatLang(get_intial_balance(p)[0][0])]]
-
-
- [[ formatLang(get_intial_balance(p)[0][1]) ]]
-
-
- [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ repeatIn(lines(p), 'line') ]]
-
-
-
- [[ formatLang(line['date'],date=True) ]]
-
-
- [[ line['code'] ]]
-
-
- [[ line['move_name'] ]]
-
-
- [[ line['a_code'] ]]
-
-
- [[ line['ref'] and strip_name(line['ref'],10) ]] - [[ strip_name(line['name'],15) ]]
-
-
- [[ formatLang((line['debit'])) ]]
-
-
- [[ formatLang((line['credit'])) ]]
-
-
- [[ formatLang((line['progress']), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
- [[ display_currency(data) == True or removeParentNode('blockTable') ]]
-
-
- Date
-
-
- JRNL
-
-
- Ref
-
-
- Account
-
-
- Entry Label
-
-
- Debit
-
-
- Credit
-
-
- Balance
-
-
- Currency
-
-
-
-
- [[ repeatIn(objects, 'p') ]]
- [[ setLang(p.lang) ]]
-
- [[ display_currency(data) == True or removeParentNode('section') ]]
-
-
-
-
-
- [[ p.ref ]] - [[ p.name ]]
-
-
- [[ formatLang((sum_debit_partner(p))) ]]
-
-
- [[ formatLang((sum_credit_partner(p))) ]]
-
-
- [[ formatLang((sum_debit_partner(p) - sum_credit_partner(p)), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
- [[ data['form']['initial_balance']==True or removeParentNode('section') ]]
-
-
-
- Initial Balance
-
-
- [[ formatLang(get_intial_balance(p)[0][0])]]
-
-
- [[ formatLang(get_intial_balance(p)[0][1]) ]]
-
-
- [[ formatLang(get_intial_balance(p)[0][2], currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(lines(p), 'line') ]]
-
-
-
- [[ formatLang(line['date'],date=True) ]]
-
-
- [[ line['code'] ]]
-
-
- [[ line['move_name'] ]]
-
-
- [[ line['a_code'] ]]
-
-
- [[ strip_name(line['ref'],8) ]] - [[ strip_name(line['name'],7) ]]
-
-
- [[ formatLang((line['debit'])) ]]
-
-
- [[ formatLang((line['credit'])) ]]
-
-
- [[ formatLang((line['progress']), currency_obj=company.currency_id) ]]
-
-
-
- [[ (line['currency_id']==None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] ) ]] [[ line['currency_code'] or '' ]]
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_print_invoice.py b/addons/account/report/account_print_invoice.py
deleted file mode 100644
index 75680810254..00000000000
--- a/addons/account/report/account_print_invoice.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-
-import time
-from openerp.report import report_sxw
-
-class account_invoice(report_sxw.rml_parse):
- def __init__(self, cr, uid, name, context):
- super(account_invoice, self).__init__(cr, uid, name, context=context)
- self.localcontext.update({
- 'time': time,
- })
-report_sxw.report_sxw(
- 'report.account.invoice',
- 'account.invoice',
- 'addons/account/report/account_print_invoice.rml',
- parser=account_invoice
-)
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_print_invoice.rml b/addons/account/report/account_print_invoice.rml
deleted file mode 100644
index 6914adfaf20..00000000000
--- a/addons/account/report/account_print_invoice.rml
+++ /dev/null
@@ -1,373 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'o') ]]
- [[ setLang(o.partner_id.lang) ]]
-
-
-
- Description
- Taxes
- Quantity
- Unit Price
- Disc.(%)
- Price
-
-
-
-
-
-
-
-
-
-
-
- [[ (o.partner_id and o.partner_id.title and o.partner_id.title.name) or '' ]] [[ (o.partner_id and o.partner_id.name) or '' ]]
- [[ display_address(o.partner_id) ]]
-
-
-
- Tel. : [[ (o.partner_id.phone) or removeParentNode('para') ]]
- Fax : [[ (o.partner_id.fax) or removeParentNode('para') ]]
- TIN : [[ (o.partner_id.vat) or removeParentNode('para') ]]
-
-
-
- Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]]
- PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]]
- Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]]
- Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]]
- Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]
- Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]
- Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]]
-
-
-
-
-
-
- Description
-
-
- Invoice Date
-
-
- Source
-
-
- Customer Code
-
-
-
-
-
-
- [[ o.name or ' ' ]]
-
-
- [[ formatLang(o.date_invoice,date=True) ]]
-
-
- [[ o.origin or '' ]]
-
-
- [[ (o.partner_id.ref) or ' ' ]]
-
-
-
-
-
-
-
-
-
- Description
-
-
- Taxes
-
-
- Quantity
-
-
- Unit Price
-
-
- Disc.(%)
-
-
- Price
-
-
-
-
- [[ repeatIn(o.invoice_line,'l') ]]
-
-
-
- [[ format(l.name) ]]
-
-
- [[ ', '.join([ lt.name or '' for lt in l.invoice_line_tax_id ]) ]]
-
-
- [[ formatLang(l.quantity)]] [[ (l.uos_id and l.uos_id.name) or '' ]]
-
-
- [[ formatLang(l.price_unit) ]]
-
-
- [[ formatLang(l.discount, dp='Account') ]]
-
-
- [[ formatLang(l.price_subtotal, dp='Account', currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Net Total:
-
-
- [[ formatLang(o.amount_untaxed, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Taxes:
-
-
- [[ formatLang(o.amount_tax, dp='Account', currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Total:
-
-
- [[ formatLang(o.amount_total, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Tax [[ o.tax_line==[] and removeParentNode('blockTable') ]]
-
-
- Base
-
-
- Amount
-
-
-
-
-
-
-
-
-
- [[ repeatIn(o.tax_line,'t') ]]
-
-
-
- [[ t.name ]]
-
-
- [[ formatLang(t.base, dp='Account', currency_obj=o.currency_id) ]]
-
-
- [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- [[ (o.comment and format(o.comment )) or removeParentNode('para') ]]
-
-
-
- [[ (o.payment_term and o.payment_term.note and format(o.payment_term and o.payment_term.note)) or removeParentNode('para') ]]
-
-
-
-
-
-
- Fiscal Position Remark :
-
-
- [[ (o.fiscal_position and o.fiscal_position.note and format(o.fiscal_position.note)) or removeParentNode('blockTable') ]]
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/report/account_print_overdue.rml b/addons/account/report/account_print_overdue.rml
deleted file mode 100644
index 9d1898572ba..00000000000
--- a/addons/account/report/account_print_overdue.rml
+++ /dev/null
@@ -1,290 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Date
-
-
- Description
-
-
- Ref
-
-
- Maturity date
-
-
- Due
-
-
- Paid
-
-
- Maturity
-
-
- Li.
-
-
-
-
- [[ repeatIn(objects,'o') ]]
- [[ setLang(o.lang) ]]
-
-
-
-
-
- [[ o.title.name or '' ]] [[ o.name ]]
- [[ display_address(o) ]]
-
-
-
- VAT: [[ o.vat or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
-
- Document: Customer account statement
- Date: [[ formatLang(time.strftime('%Y-%m-%d'),date=True) ]]
- Customer Ref: [[ o.ref or ' ']]
-
-
-
-
-
-
-
- [[ not getLines(o) and removeParentNode('section')]]
-
- [[repeatIn(message(o, company), 'message_line') ]]
- [[ message_line ]]
-
-
-
-
-
-
-
- Date
-
-
- Description
-
-
- Ref
-
-
- Maturity date
-
-
- Due
-
-
- Paid
-
-
- Maturity
-
-
- Li.
-
-
-
- [[repeatIn(getLines(o), 'line') ]]
-
-
-
- [[ formatLang(line['date'],date=True) ]]
-
-
- [[ line['name'] ]]
-
-
- [[ line['ref'] ]]
-
-
- [[ line['date_maturity'] and formatLang(line['date_maturity'],date=True) or '' ]]
-
-
- [[ (line['account_id']['type'] == 'receivable' and formatLang(line['debit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['credit'] * -1) or ' ') ]]
-
-
- [[ (line['account_id']['type'] == 'receivable' and formatLang(line['credit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['debit'] * -1) or 0) ]]
-
-
- [[ (time.strftime('%Y-%m-%d') > line['date_maturity']) and formatLang(line['debit'] - line['credit'], currency_obj = company.currency_id) ]]
-
-
- [[ line['blocked'] and 'X' or '' ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Sub-Total :
-
-
- [[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['debit'] or 0) or (y['account_id']['type'] == 'payable' and y['credit'] * -1 or 0)), getLines(o), 0))) ]]
-
-
- [[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['credit'] or 0) or (y['account_id']['type'] == 'payable' and y['debit'] * -1 or 0)), getLines(o), 0))) ]]
-
-
- [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), getLines(o)), 0)), currency_obj=company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Balance :
-
-
- [[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0)), currency_obj = company.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Total amount due: [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), getLines(o), 0)), currency_obj=company.currency_id) ]]
-
-
-
-
-
- [[ getLines(o) and removeParentNode('section')]]There is nothing due with this customer.
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account/views/report_agedpartnerbalance.xml b/addons/account/views/report_agedpartnerbalance.xml
new file mode 100644
index 00000000000..9ab05afa772
--- /dev/null
+++ b/addons/account/views/report_agedpartnerbalance.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
Aged Trial Balance
+
+
+
+
+
+
+
Period Length (days)
+
+
+
+
+
+
Partner's:
+
+ Receivable Accounts
+ Payable Accounts
+ Receivable and Payable Accounts
+
+
+
+
Analysis Direction:
+
+
+
+
+
+
+
+
+ Partners
+
+ Due
+ Not due
+
+
+
+
+
+ +
+ Total
+
+
+ Account Total
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_centraljournal.xml b/addons/account/views/report_centraljournal.xml
new file mode 100644
index 00000000000..e939fa98fc3
--- /dev/null
+++ b/addons/account/views/report_centraljournal.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
Centralized Journal
+
+
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+
+ A/C No.
+ Account Name
+ Debit
+ Credit
+ Balance
+ Currency
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_financial.xml b/addons/account/views/report_financial.xml
new file mode 100644
index 00000000000..69802331a5b
--- /dev/null
+++ b/addons/account/views/report_financial.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Name
+ Debit
+ Credit
+ Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+ Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+ Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_generaljournal.xml b/addons/account/views/report_generaljournal.xml
new file mode 100644
index 00000000000..2dd07cf87fd
--- /dev/null
+++ b/addons/account/views/report_generaljournal.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
General Journal
+
+
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Code
+ Journal Name
+ Debit
+ Credit
+ Balance
+ Currency
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_generalledger.xml b/addons/account/views/report_generalledger.xml
new file mode 100644
index 00000000000..d873571dee3
--- /dev/null
+++ b/addons/account/views/report_generalledger.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
: General ledger
+
+
+
+
+
+
+
Display Account
+
+ All accounts'
+ With movements
+ With balance not equal to zero
+
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+
+ Date
+ JRNL
+ Partner
+ Ref
+ Move
+ Entry Label
+ Counterpart
+ Debit
+ Credit
+ Progress
+ Currency
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml
new file mode 100644
index 00000000000..bc0dc5e92a2
--- /dev/null
+++ b/addons/account/views/report_invoice.xml
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+ Invoice
+ PRO-FORMA
+ Draft Invoice
+ Cancelled Invoice
+ Refund
+ Supplier Refund
+ Supplier Invoice
+
+
+
+
+
+
+
+
+ Description
+ Quantity
+ Unit of measure
+ Unit Price
+ Discount (%)
+ Taxes
+ Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total Without Taxes
+
+
+
+
+
+ Taxes
+
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tax
+ Base
+ Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Comment:
+
+
+
+ Payment Term:
+
+
+
+ Fiscal Position:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_journal.xml b/addons/account/views/report_journal.xml
new file mode 100644
index 00000000000..a9cd56b4109
--- /dev/null
+++ b/addons/account/views/report_journal.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
Journal
+
+
+
+
+
Entries Sorted By:
+
Date
+
Journal Entry Number
+
+
+
+
+
+
+
+ Move
+ Date
+ Account
+ Partner
+ Label
+ Debit
+ Credit
+ Currency
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml
new file mode 100644
index 00000000000..080de9a5615
--- /dev/null
+++ b/addons/account/views/report_overdue.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+ Document: Customer account statement
+ Date:
+ Customer ref:
+
+
+
+
+
+
+
+
+
+
+
+ Date
+ Description
+ Ref
+ Maturity Date
+ Due
+ Paid
+ Maturity
+ Li.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ x
+
+
+
+
+ Sub-Total :
+
+
+
+
+
+
+
+ Balance :
+
+
+
+
+
+
+
+
+
+
+ Total amount due:
+
+
+
+
+ There is nothing due with this customer.
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_partnerbalance.xml b/addons/account/views/report_partnerbalance.xml
new file mode 100644
index 00000000000..11948905fe9
--- /dev/null
+++ b/addons/account/views/report_partnerbalance.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
Partner Balance
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Code
+ (Account/Partner) Name
+ Debit
+ Credit
+ Balance
+ In dispute
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_partnerledger.xml b/addons/account/views/report_partnerledger.xml
new file mode 100644
index 00000000000..333fab7aa5c
--- /dev/null
+++ b/addons/account/views/report_partnerledger.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
Partner Ledger
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Date
+ JRNL
+ Ref
+ Account
+ Entry Label
+ Debit
+ Credit
+ Balance
+ Currency
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ Initial Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_partnerledgerother.xml b/addons/account/views/report_partnerledgerother.xml
new file mode 100644
index 00000000000..b8f3d525f51
--- /dev/null
+++ b/addons/account/views/report_partnerledgerother.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
Partner Ledger
+
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Date
+ JRNL
+ Ref
+ Account
+ Entry Label
+ Debit
+ Credit
+ Balance
+ Currency
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+ Initial Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_salepurchasejournal.xml b/addons/account/views/report_salepurchasejournal.xml
new file mode 100644
index 00000000000..a6441122125
--- /dev/null
+++ b/addons/account/views/report_salepurchasejournal.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
Sale/Purchase Journal
+
+
+
+
+
Entries Sorted By:
+
Journal Entry Number
+
Date
+
+
+
+
+
+
+
+ Move
+ Date
+ Account
+ Partner
+ Label
+ Tax
+ Debit
+ Credit
+ Currency
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tax Declaration
+
+
+
+ :
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/views/report_trialbalance.xml b/addons/account/views/report_trialbalance.xml
new file mode 100644
index 00000000000..6a27b957971
--- /dev/null
+++ b/addons/account/views/report_trialbalance.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
: Trial Balance
+
+
+
+
+
+
Display Account:
+
+ All accounts
+ With movements
+ With balance not equal to zero
+
+
+
+
Filter By:
+
+ Not filtered
+ Filtered by period
+ Filtered by date
+
+ Start Period:
+ End Period:
+
+
+ Date from :
+ Date to :
+
+
+
+
+
+
+
+
+
+ Code
+ Account
+ Debit
+ Credit
+ Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account/wizard/account_financial_report.py b/addons/account/wizard/account_financial_report.py
index 48bdfd33081..df1fa94ae90 100644
--- a/addons/account/wizard/account_financial_report.py
+++ b/addons/account/wizard/account_financial_report.py
@@ -21,6 +21,7 @@
from openerp.osv import fields, osv
+
class accounting_report(osv.osv_memory):
_name = "accounting.report"
_inherit = "account.common.report"
@@ -83,16 +84,13 @@ class accounting_report(osv.osv_memory):
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
+ res['data'] = {}
+ res['data']['form'] = data['form']
+ res['data']['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', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter','target_move'], context=context)[0])
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.financial.report',
- 'datas': data,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_financial', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_account_balance.py b/addons/account/wizard/account_report_account_balance.py
index fd3c966e306..3b9d3c21777 100644
--- a/addons/account/wizard/account_report_account_balance.py
+++ b/addons/account/wizard/account_report_account_balance.py
@@ -36,7 +36,6 @@ class account_balance_report(osv.osv_memory):
def _print_report(self, cr, uid, ids, data, context=None):
data = self.pre_print_report(cr, uid, ids, data, context=context)
- return {'type': 'ir.actions.report.xml', 'report_name': 'account.account.balance', 'datas': data}
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_trialbalance', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_aged_partner_balance.py b/addons/account/wizard/account_report_aged_partner_balance.py
index c483487b78f..c918a1119fd 100644
--- a/addons/account/wizard/account_report_aged_partner_balance.py
+++ b/addons/account/wizard/account_report_aged_partner_balance.py
@@ -25,6 +25,7 @@ from dateutil.relativedelta import relativedelta
from openerp.osv import fields, osv
from openerp.tools.translate import _
+
class account_aged_trial_balance(osv.osv_memory):
_inherit = 'account.common.partner.report'
_name = 'account.aged.trial.balance'
@@ -80,11 +81,6 @@ class account_aged_trial_balance(osv.osv_memory):
data['form'].update(res)
if data.get('form',False):
data['ids']=[data['form'].get('chart_account_id',False)]
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.aged_trial_balance',
- 'datas': data
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_agedpartnerbalance', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_central_journal.py b/addons/account/wizard/account_report_central_journal.py
index a6bc111fa35..9f22d49afac 100644
--- a/addons/account/wizard/account_report_central_journal.py
+++ b/addons/account/wizard/account_report_central_journal.py
@@ -32,13 +32,6 @@ class account_central_journal(osv.osv_memory):
def _print_report(self, cr, uid, ids, data, context=None):
data = self.pre_print_report(cr, uid, ids, data, context=context)
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.central.journal',
- 'datas': data,
- }
-
-
-#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_centraljournal', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_general_journal.py b/addons/account/wizard/account_report_general_journal.py
index e5e516b1f38..3d9d55b19c1 100644
--- a/addons/account/wizard/account_report_general_journal.py
+++ b/addons/account/wizard/account_report_general_journal.py
@@ -32,9 +32,6 @@ class account_general_journal(osv.osv_memory):
def _print_report(self, cr, uid, ids, data, context=None):
data = self.pre_print_report(cr, uid, ids, data, context=context)
- return {'type': 'ir.actions.report.xml', 'report_name': 'account.general.journal', 'datas': data}
-
-
-#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_generaljournal', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_general_ledger.py b/addons/account/wizard/account_report_general_ledger.py
index fae60df63fb..c75477da40a 100644
--- a/addons/account/wizard/account_report_general_ledger.py
+++ b/addons/account/wizard/account_report_general_ledger.py
@@ -21,6 +21,7 @@
from openerp.osv import fields, osv
+
class account_report_general_ledger(osv.osv_memory):
_inherit = "account.common.account.report"
_name = "account.report.general.ledger"
@@ -54,9 +55,10 @@ class account_report_general_ledger(osv.osv_memory):
data['form'].update(self.read(cr, uid, ids, ['landscape', 'initial_balance', 'amount_currency', 'sortby'])[0])
if not data['form']['fiscalyear_id']:# GTK client problem onchange does not consider in save record
data['form'].update({'initial_balance': False})
- if data['form']['landscape']:
- return { 'type': 'ir.actions.report.xml', 'report_name': 'account.general.ledger_landscape', 'datas': data}
- return { 'type': 'ir.actions.report.xml', 'report_name': 'account.general.ledger', 'datas': data}
+ if data['form']['landscape'] is False:
+ data['form'].pop('landscape')
+
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_generalledger', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_partner_balance.py b/addons/account/wizard/account_report_partner_balance.py
index fbe18f27d69..d4b5fb27d14 100644
--- a/addons/account/wizard/account_report_partner_balance.py
+++ b/addons/account/wizard/account_report_partner_balance.py
@@ -21,6 +21,7 @@
from openerp.osv import fields, osv
+
class account_partner_balance(osv.osv_memory):
"""
This wizard will provide the partner balance report by periods, between any two dates.
@@ -35,7 +36,6 @@ class account_partner_balance(osv.osv_memory):
}
_defaults = {
-# 'initial_balance': True,
'display_partner': 'non-zero_balance',
}
@@ -44,11 +44,6 @@ class account_partner_balance(osv.osv_memory):
context = {}
data = self.pre_print_report(cr, uid, ids, data, context=context)
data['form'].update(self.read(cr, uid, ids, ['display_partner'])[0])
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.partner.balance',
- 'datas': data,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerbalance', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_partner_ledger.py b/addons/account/wizard/account_report_partner_ledger.py
index fdabe49ff17..75f79512603 100644
--- a/addons/account/wizard/account_report_partner_ledger.py
+++ b/addons/account/wizard/account_report_partner_ledger.py
@@ -21,6 +21,7 @@
from openerp.osv import fields, osv
+
class account_partner_ledger(osv.osv_memory):
"""
This wizard will provide the partner Ledger report by periods, between any two dates.
@@ -37,6 +38,7 @@ class account_partner_ledger(osv.osv_memory):
'amount_currency': fields.boolean("With Currency", help="It adds the currency column on report if the currency differs from the company currency."),
'journal_ids': fields.many2many('account.journal', 'account_partner_ledger_journal_rel', 'account_id', 'journal_id', 'Journals', required=True),
}
+
_defaults = {
'initial_balance': False,
'page_split': False,
@@ -45,8 +47,8 @@ class account_partner_ledger(osv.osv_memory):
def onchange_filter(self, cr, uid, ids, filter='filter_no', fiscalyear_id=False, context=None):
res = super(account_partner_ledger, self).onchange_filter(cr, uid, ids, filter=filter, fiscalyear_id=fiscalyear_id, context=context)
if filter in ['filter_no', 'unreconciled']:
- if filter == 'unreconciled':
- res['value'].update({'fiscalyear_id': False})
+ if filter == 'unreconciled':
+ res['value'].update({'fiscalyear_id': False})
res['value'].update({'initial_balance': False, 'period_from': False, 'period_to': False, 'date_from': False ,'date_to': False})
return res
@@ -55,17 +57,6 @@ class account_partner_ledger(osv.osv_memory):
context = {}
data = self.pre_print_report(cr, uid, ids, data, context=context)
data['form'].update(self.read(cr, uid, ids, ['initial_balance', 'filter', 'page_split', 'amount_currency'])[0])
- if data['form']['page_split']:
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.third_party_ledger',
- 'datas': data,
- }
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.third_party_ledger_other',
- 'datas': data,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerledger', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_report_print_journal.py b/addons/account/wizard/account_report_print_journal.py
index 3ad45268248..3aafc63acf4 100644
--- a/addons/account/wizard/account_report_print_journal.py
+++ b/addons/account/wizard/account_report_print_journal.py
@@ -22,6 +22,7 @@
from openerp.osv import fields, osv
from lxml import etree
+
class account_print_journal(osv.osv_memory):
_inherit = "account.common.journal.report"
_name = 'account.print.journal'
@@ -60,19 +61,14 @@ class account_print_journal(osv.osv_memory):
res['arch'] = etree.tostring(doc)
return res
-
def _print_report(self, cr, uid, ids, data, context=None):
if context is None:
context = {}
data = self.pre_print_report(cr, uid, ids, data, context=context)
data['form'].update(self.read(cr, uid, ids, ['sort_selection'], context=context)[0])
if context.get('sale_purchase_only'):
- report_name = 'account.journal.period.print.sale.purchase'
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_salepurchasejournal', data=data, context=context)
else:
- report_name = 'account.journal.period.print'
- return {'type': 'ir.actions.report.xml', 'report_name': report_name, 'datas': data}
-
-
-#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_journal', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_vat.py b/addons/account/wizard/account_vat.py
index 6fbfcc9ddf5..5cc5c678df1 100644
--- a/addons/account/wizard/account_vat.py
+++ b/addons/account/wizard/account_vat.py
@@ -21,6 +21,7 @@
from openerp.osv import fields, osv
+
class account_vat_declaration(osv.osv_memory):
_name = 'account.vat.declaration'
_description = 'Account Vat Declaration'
@@ -60,6 +61,6 @@ class account_vat_declaration(osv.osv_memory):
taxcode = taxcode_obj.browse(cr, uid, [taxcode_id], context=context)[0]
datas['form']['company_id'] = taxcode.company_id.id
- return self.pool['report'].get_action(cr, uid, ids, 'account.report_vat', datas=datas, context=context)
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_vat', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_plans/__openerp__.py b/addons/account_analytic_plans/__openerp__.py
index af5b5654b99..7c580bd14f2 100644
--- a/addons/account_analytic_plans/__openerp__.py
+++ b/addons/account_analytic_plans/__openerp__.py
@@ -19,7 +19,6 @@
#
##############################################################################
-
{
'name': 'Multiple Analytic Plans',
'version': '1.0',
@@ -74,9 +73,10 @@ The analytic plan validates the minimum and maximum percentage at the time of cr
'account_analytic_plans_report.xml',
'wizard/analytic_plan_create_model_view.xml',
'wizard/account_crossovered_analytic_view.xml',
+ 'views/report_crossoveredanalyticplans.xml',
],
'demo': [],
- 'test': ['test/acount_analytic_plans_report.yml'],
+ 'test': [],
'installable': True,
'auto_install': False,
}
diff --git a/addons/account_analytic_plans/account_analytic_plans_report.xml b/addons/account_analytic_plans/account_analytic_plans_report.xml
index 05d4c5b445c..608a22d1d96 100644
--- a/addons/account_analytic_plans/account_analytic_plans_report.xml
+++ b/addons/account_analytic_plans/account_analytic_plans_report.xml
@@ -1,16 +1,15 @@
-
-
+ report_type="qweb-pdf"
+ name="account_analytic_plans.report_crossoveredanalyticplans"
+ file="account_analytic_plans.report_crossoveredanalyticplans"
+ menu="False"
+ />
diff --git a/addons/account_analytic_plans/report/crossovered_analytic.rml b/addons/account_analytic_plans/report/crossovered_analytic.rml
deleted file mode 100644
index 48e7c13b0a1..00000000000
--- a/addons/account_analytic_plans/report/crossovered_analytic.rml
+++ /dev/null
@@ -1,304 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Account Name
-
-
- Code
-
-
- Quantity
-
-
- Amount
-
-
- Perc(%)
-
-
-
-
-
-
-
- Crossovered Analytic
-
-
-
-
-
-
- From Date
-
-
- To Date
-
-
- Company
-
-
- Currency
-
-
- Printing date
-
-
-
-
-
-
- [[ formatLang(data['form']['date1'],date=True) ]]
-
-
- [[ formatLang(data['form']['date2'],date=True) ]]
-
-
- [[ company.name ]]
-
-
- [[ company.currency_id.name ]]
-
-
- [[ formatLang(time.strftime('%Y-%m-%d'),date=True) ]] at [[ time.strftime('%H:%M:%S') ]]
-
-
-
-
-
-
- Analytic Account Reference:
-
-
-
-
-
-
- Account Name
-
-
- Code
-
-
- Quantity
-
-
- Amount
-
-
- Perc(%)
-
-
-
-
- [[ repeatIn(ref_lines(data['form']),'a') ]]
-
-
-
- [[ a['ref_name'] ]]
-
-
- [[ a['ref_code'] ]]
-
-
- [[ a['ref_qty'] and formatLang(a['ref_qty']) ]]
-
-
- [[ a['ref_amt'] and formatLang(a['ref_amt'], currency_obj=company.currency_id) ]]
-
-
- 100.00%
-
-
-
-
-
-
-
- Analytic Account :
-
-
-
-
-
-
- Account Name
-
-
- Code
-
-
- Quantity
-
-
- Amount
-
-
- Percentage
-
-
-
-
- [[ repeatIn(lines(data['form']),'a') ]]
-
-
-
- [[ a['acc_name'] ]]
-
-
- [[ a['code'] ]]
-
-
- [[formatLang(a['qty']) ]]
-
-
- [[ formatLang(a['amt'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(a['perc']) ]]%
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml b/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
new file mode 100644
index 00000000000..bce3cccd5c7
--- /dev/null
+++ b/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
Crossovered Analytic
+
+
+
+
Analytic Account Reference
+
+
+
+
+ Account Name
+ Code
+ Quantity
+ Amount
+ Perc(%)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 100.00%
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_analytic_plans/wizard/account_crossovered_analytic.py b/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
index d3581d6c457..ccac123c681 100644
--- a/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
+++ b/addons/account_analytic_plans/wizard/account_crossovered_analytic.py
@@ -65,11 +65,6 @@ class account_crossovered_analytic(osv.osv_memory):
'model': 'account.analytic.account',
'form': data
}
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.crossovered.analytic',
- 'datas': datas,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account_analytic_plans.report_crossoveredanalyticplans', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_bank_statement_extensions/__openerp__.py b/addons/account_bank_statement_extensions/__openerp__.py
index 7571eef3e54..203011c46c5 100644
--- a/addons/account_bank_statement_extensions/__openerp__.py
+++ b/addons/account_bank_statement_extensions/__openerp__.py
@@ -50,6 +50,7 @@ This module adds:
'wizard/confirm_statement_line_wizard.xml',
'wizard/cancel_statement_line_wizard.xml',
'data/account_bank_statement_extensions_data.xml',
+ 'views/report_bankstatementbalance.xml',
],
'auto_install': False,
'installable': True,
diff --git a/addons/account_bank_statement_extensions/account_bank_statement_report.xml b/addons/account_bank_statement_extensions/account_bank_statement_report.xml
index b4dafbfd9a7..861c3822520 100644
--- a/addons/account_bank_statement_extensions/account_bank_statement_report.xml
+++ b/addons/account_bank_statement_extensions/account_bank_statement_report.xml
@@ -1,16 +1,13 @@
-
-
-
-
-
+
+
+
diff --git a/addons/account_bank_statement_extensions/report/bank_statement_balance_report.rml b/addons/account_bank_statement_extensions/report/bank_statement_balance_report.rml
deleted file mode 100644
index 963b5d9dd68..00000000000
--- a/addons/account_bank_statement_extensions/report/bank_statement_balance_report.rml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ ]]
-
-
-
-
-
-
- Bank Statement Balances Report
-
-
-
-
-
-
-
-
-
-
-
-
- Name
-
-
- Date
-
-
- Journal
-
-
- Closing Balance
-
-
-
-
-
-
-
- [[ repeatIn(lines, 'l') ]]
-
-
-
- [[ l['s_name'] ]]
-
-
- [[ l['s_date'] ]]
-
-
- [[ l['j_code'] ]]
-
-
- [[ formatLang(l['s_balance']) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml b/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml
new file mode 100644
index 00000000000..a8ca5f54d3a
--- /dev/null
+++ b/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
Bank Statement Balances Report
+
+
+
+
+ Name
+ Date
+ Journal
+ Closing Balance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_budget/__openerp__.py b/addons/account_budget/__openerp__.py
index 222178b940c..695fd794b9f 100644
--- a/addons/account_budget/__openerp__.py
+++ b/addons/account_budget/__openerp__.py
@@ -19,7 +19,6 @@
#
##############################################################################
-
{
'name': 'Budgets Management',
'version': '1.0',
@@ -61,13 +60,18 @@ Three reports are available:
'wizard/account_budget_report_view.xml',
'wizard/account_budget_crossovered_summary_report_view.xml',
'wizard/account_budget_crossovered_report_view.xml',
+
+ 'views/report_analyticaccountbudget.xml',
+ 'views/report_budget.xml',
+ 'views/report_crossoveredbudget.xml',
],
'demo': ['account_budget_demo.xml'],
- 'test':[
+ 'test': [
'test/account_budget.yml',
'test/account_budget_report.yml',
],
'installable': True,
'auto_install': False,
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/account_budget_report.xml b/addons/account_budget/account_budget_report.xml
index 9cc38154ef9..7855deb9ccc 100644
--- a/addons/account_budget/account_budget_report.xml
+++ b/addons/account_budget/account_budget_report.xml
@@ -1,24 +1,34 @@
-
-
-
-
-
-
-
+ />
+
+
+
+
-
\ No newline at end of file
+
diff --git a/addons/account_budget/report/analytic_account_budget_report.rml b/addons/account_budget/report/analytic_account_budget_report.rml
deleted file mode 100644
index 15fddebd02d..00000000000
--- a/addons/account_budget/report/analytic_account_budget_report.rml
+++ /dev/null
@@ -1,226 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Description
-
-
- Theoretical Amt
-
-
- Planned Amt
-
-
- Practical Amt
-
-
- Perc(%)
-
-
-
-
- [[repeatIn(objects,'o')]]
- Analytic Budget
-
-
-
-
-
-
- Analysis from
-
-
- Analytic Account
-
-
- Currency
-
-
-
-
-
-
- [[ formatLang(data['form']['date_from'],date=True) ]] to [[ formatLang(data['form']['date_to'],date=True) ]]
-
-
- [[ o.name ]]
-
-
- [[ company.currency_id.name ]]
-
-
-
-
-
-
-
-
-
- Description
-
-
- Theoretical Amt
-
-
- Planned Amt
-
-
- Practical Amt
-
-
- Perc(%)
-
-
-
-
- [[ repeatIn(funct(o,data['form']),'a') ]]
-
-
-
- [['.....' *(a['status']-1) ]] [[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ a['name'] ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc']) ]]%
-
-
-
-
-
-
-
- [[ repeatIn(funct_total(data['form']),'b') ]] Total:
-
-
- [[ formatLang(b['tot_theo'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_pln'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_prac'], currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_perc']) ]]%
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_budget/report/budget_report.rml b/addons/account_budget/report/budget_report.rml
deleted file mode 100644
index 789c3ed1ffb..00000000000
--- a/addons/account_budget/report/budget_report.rml
+++ /dev/null
@@ -1,188 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'o') ]]
-
-
-
- Budget
-
-
-
-
-
-
- Currency: [[ company.currency_id.name ]]
-
-
- Printed at: [[ formatLang(time.strftime('%Y-%m-%d'),date=True) ]] at [[ time.strftime('%H:%M:%S')]]
-
-
-
-
- Analysis from [[ formatLang(data['form']['date_from'],date=True) ]] to [[ formatLang(data['form']['date_to'],date=True) ]]
-
-
- Budget : [[ o.name ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Description
-
-
- Theoretical Amt
-
-
- Planned Amt
-
-
- Practical Amt
-
-
- Perc(%)
-
-
-
-
- [[ repeatIn(funct(o,data['form']),'a') ]]
-
-
-
- [['.....' *(a['status']-1) ]] [[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ a['name'] ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc'], digits=2) ]]%
-
-
-
-
-
-
-
- [[ repeatIn(funct_total(data['form']),'b') ]] Total:
-
-
- [[ formatLang(b['tot_theo'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_pln'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_prac'], digits=get_digits(dp='Account'), currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_perc'], digits=2) ]]%
-
-
-
-
-
-
-
-
diff --git a/addons/account_budget/report/crossovered_budget_report.rml b/addons/account_budget/report/crossovered_budget_report.rml
deleted file mode 100644
index a63920a4c9f..00000000000
--- a/addons/account_budget/report/crossovered_budget_report.rml
+++ /dev/null
@@ -1,203 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'o') ]]
- Budget
-
-
-
-
-
-
- Analysis from
-
-
- Budget
-
-
- Currency
-
-
-
-
-
-
- [[ formatLang(data['form']['date_from'],date=True) ]] to [[ formatLang(data['form']['date_to'],date=True) ]]
-
-
- [[ o.name ]]
-
-
- [[ company.currency_id.name ]]
-
-
-
-
-
-
-
-
-
- Description
-
-
- Theoretical Amt
-
-
- Planned Amt
-
-
- Practical Amt
-
-
- Perc(%)
-
-
-
-
- [[ repeatIn(funct(o,data['form']),'a') ]]
-
-
-
- [['.....' *(a['status']-1) ]] [[ (a['status']==1 and (setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ a['name'] ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['theo'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['pln'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['prac'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ (a['status']==1 and ( setTag('para','para',{'fontName':'Helvetica-Bold'}))) or removeParentNode('font') ]] [[ formatLang(a['perc'],digits=2) ]]%
-
-
-
-
-
-
-
- [[ repeatIn(funct_total(data['form']),'b') ]] Total :
-
-
- [[ formatLang(b['tot_theo'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_pln'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_prac'], dp='Account', currency_obj=company.currency_id) ]]
-
-
- [[ formatLang(b['tot_perc'],digits=2) ]]%
-
-
-
-
-
-
-
-
diff --git a/addons/account_budget/views/report_analyticaccountbudget.xml b/addons/account_budget/views/report_analyticaccountbudget.xml
new file mode 100644
index 00000000000..dab987d6099
--- /dev/null
+++ b/addons/account_budget/views/report_analyticaccountbudget.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
Analytic Budget
+
+
+
+
+
+
+ Description
+ Theoretical Amt
+ Planned Amt
+ Practical Amt
+ Perc(%)
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+
+ %
+
+
+
+ Total:
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/account_budget/views/report_budget.xml b/addons/account_budget/views/report_budget.xml
new file mode 100644
index 00000000000..6bc72fc9dca
--- /dev/null
+++ b/addons/account_budget/views/report_budget.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
Budget
+
+
+
+
+
Analysis from:
+
to
+
+
+
+
+
+
+
+
+ Description
+ Theoretical Amount
+ Planned Amount
+ Practical Amount
+ Perc(%)
+
+
+
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+
+
+ %
+
+
+
+ Total:
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_budget/views/report_crossoveredbudget.xml b/addons/account_budget/views/report_crossoveredbudget.xml
new file mode 100644
index 00000000000..412c2aac8ed
--- /dev/null
+++ b/addons/account_budget/views/report_crossoveredbudget.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
Budget
+
+
+
+
Analysis from:
+
to
+
+
+
+
+
+
+
+
+
+ Description
+ Theoretical Amt
+ Planned Amt
+ Practical Amt
+ Perc(%)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+ %
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_budget/wizard/account_budget_analytic.py b/addons/account_budget/wizard/account_budget_analytic.py
index 90285b90d1e..a58b804ebbf 100644
--- a/addons/account_budget/wizard/account_budget_analytic.py
+++ b/addons/account_budget/wizard/account_budget_analytic.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+ # -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_budget_analytic(osv.osv_memory):
_name = 'account.budget.analytic'
@@ -30,7 +31,7 @@ class account_budget_analytic(osv.osv_memory):
'date_from': fields.date('Start of period', required=True),
'date_to': fields.date('End of period', required=True),
}
- _defaults= {
+ _defaults = {
'date_from': lambda *a: time.strftime('%Y-01-01'),
'date_to': lambda *a: time.strftime('%Y-%m-%d'),
}
@@ -40,15 +41,11 @@ class account_budget_analytic(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids, context=context)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.analytic.account',
- 'form': data
+ 'ids': context.get('active_ids', []),
+ 'model': 'account.analytic.account',
+ 'form': data
}
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.analytic.account.budget',
- 'datas': datas,
- }
-
+ datas['form']['ids'] = datas['ids']
+ return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_analyticaccountbudget', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_crossovered_report.py b/addons/account_budget/wizard/account_budget_crossovered_report.py
index 6f89a3cd95c..96561df5af0 100644
--- a/addons/account_budget/wizard/account_budget_crossovered_report.py
+++ b/addons/account_budget/wizard/account_budget_crossovered_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_budget_crossvered_report(osv.osv_memory):
_name = "account.budget.crossvered.report"
@@ -40,16 +41,12 @@ class account_budget_crossvered_report(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids, context=context)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'crossovered.budget',
- 'form': data
+ 'ids': context.get('active_ids', []),
+ 'model': 'crossovered.budget',
+ 'form': data
}
+ datas['form']['ids'] = datas['ids']
datas['form']['report'] = 'analytic-full'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'crossovered.budget.report',
- 'datas': datas,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_crossoveredbudget', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/wizard/account_budget_crossovered_summary_report.py b/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
index 6e3131b584c..6b676ecc684 100644
--- a/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
+++ b/addons/account_budget/wizard/account_budget_crossovered_summary_report.py
@@ -18,10 +18,11 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
+
class account_budget_crossvered_summary_report(osv.osv_memory):
"""
This wizard provides the crossovered budget summary report'
@@ -32,7 +33,7 @@ class account_budget_crossvered_summary_report(osv.osv_memory):
'date_from': fields.date('Start of period', required=True),
'date_to': fields.date('End of period', required=True),
}
- _defaults= {
+ _defaults = {
'date_from': lambda *a: time.strftime('%Y-01-01'),
'date_to': lambda *a: time.strftime('%Y-%m-%d'),
}
@@ -42,17 +43,12 @@ class account_budget_crossvered_summary_report(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids, context=context)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'crossovered.budge',
- 'form': data
+ 'ids': context.get('active_ids',[]),
+ 'model': 'crossovered.budge',
+ 'form': data
}
+ datas['form']['ids'] = datas['ids']
datas['form']['report'] = 'analytic-one'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'crossovered.budget.report',
- 'datas': datas,
- }
-
+ return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_crossoveredbudget', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account_budget/wizard/account_budget_report.py b/addons/account_budget/wizard/account_budget_report.py
index 54c3180ee0d..2308b5ff9ac 100644
--- a/addons/account_budget/wizard/account_budget_report.py
+++ b/addons/account_budget/wizard/account_budget_report.py
@@ -18,8 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
-import time
+import time
from openerp.osv import fields, osv
@@ -31,7 +31,7 @@ class account_budget_report(osv.osv_memory):
'date_from': fields.date('Start of period', required=True),
'date_to': fields.date('End of period', required=True),
}
- _defaults= {
+ _defaults = {
'date_from': lambda *a: time.strftime('%Y-01-01'),
'date_to': lambda *a: time.strftime('%Y-%m-%d'),
}
@@ -41,16 +41,12 @@ class account_budget_report(osv.osv_memory):
context = {}
data = self.read(cr, uid, ids, context=context)[0]
datas = {
- 'ids': context.get('active_ids',[]),
- 'model': 'account.budget.post',
- 'form': data
+ 'ids': context.get('active_ids', []),
+ 'model': 'account.budget.post',
+ 'form': data
}
- datas['form']['report']='analytic-full'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account.budget',
- 'datas': datas,
- }
-
+ datas['form']['ids'] = datas['ids']
+ datas['form']['report'] = 'analytic-full'
+ return self.pool['report'].get_action(cr, uid, ids, 'account_budget.report_budget', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_check_writing/__openerp__.py b/addons/account_check_writing/__openerp__.py
index e01c17d66a7..3311a7c03b3 100644
--- a/addons/account_check_writing/__openerp__.py
+++ b/addons/account_check_writing/__openerp__.py
@@ -31,10 +31,12 @@ Module for the Check Writing and Check Printing.
'depends' : ['account_voucher'],
'data': [
'wizard/account_check_batch_printing_view.xml',
- 'account_check_writing_report.xml',
'account_view.xml',
'account_voucher_view.xml',
'account_check_writing_data.xml',
+ 'data/report_paperformat.xml',
+ 'views/report_check.xml',
+ 'account_check_writing_report.xml',
],
'demo': ['account_demo.xml'],
'test': [],
diff --git a/addons/account_check_writing/account_check_writing_report.xml b/addons/account_check_writing/account_check_writing_report.xml
index eece4e4a5da..d32dd77bc8f 100644
--- a/addons/account_check_writing/account_check_writing_report.xml
+++ b/addons/account_check_writing/account_check_writing_report.xml
@@ -1,29 +1,17 @@
-
+
-
-
-
-
-
+
+
+
+
diff --git a/addons/account_check_writing/data/report_paperformat.xml b/addons/account_check_writing/data/report_paperformat.xml
new file mode 100644
index 00000000000..3782b8bde40
--- /dev/null
+++ b/addons/account_check_writing/data/report_paperformat.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ French Bank Check
+
+ custom
+ 80
+ 175
+ Portrait
+ 3
+ 3
+ 3
+ 3
+
+ 3
+ 80
+
+
+
diff --git a/addons/account_check_writing/report/check_print_bottom.rml b/addons/account_check_writing/report/check_print_bottom.rml
deleted file mode 100644
index f9add2fe60b..00000000000
--- a/addons/account_check_writing/report/check_print_bottom.rml
+++ /dev/null
@@ -1,318 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[repeatIn(objects,'voucher')]]
-
-
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Balance Due
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[formatLang( l['amount_original']) ]]
-
-
- [[ formatLang( l['amount_due']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Balance Due
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[ formatLang (l['amount_original']) ]]
-
-
- [[ formatLang (l['amount_due']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.partner_id.name ]]
- [[ display_address(voucher.partner_id) or removeParentNode('para') ]]
-
-
-
-
-
-
- [[ fill_stars(voucher.amount_in_word) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_check_writing/report/check_print_middle.rml b/addons/account_check_writing/report/check_print_middle.rml
deleted file mode 100644
index b1fffca662d..00000000000
--- a/addons/account_check_writing/report/check_print_middle.rml
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[repeatIn(objects,'voucher')]]
-
-
-
-
-
-
-
-
-
- [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Balance Due
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[formatLang( l['amount_original']) ]]
-
-
- [[ formatLang( l['amount_due']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
-
-
-
-
-
-
- [[ str(fill_stars(voucher.amount_in_word)) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.partner_id.name ]]
- [[ display_address(voucher.partner_id) or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
- [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Balance Due
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_original'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[ formatLang (l['amount_original']) ]]
-
-
- [[ formatLang (l['amount_due']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_check_writing/report/check_print_top.rml b/addons/account_check_writing/report/check_print_top.rml
deleted file mode 100644
index 9a4d633e680..00000000000
--- a/addons/account_check_writing/report/check_print_top.rml
+++ /dev/null
@@ -1,336 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[repeatIn(objects,'voucher')]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.partner_id.name ]]
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
- [[ fill_stars(voucher.amount_in_word) ]]
-
-
-
-
-
-
-
-
-
- [[ voucher.partner_id.name ]]
- [[ display_address(voucher.partner_id) or removeParentNode('para') ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.name ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Open Balance
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_due'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[formatLang( l['amount_original']) ]]
-
-
- [[ formatLang( l['amount_unreconciled']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[voucher.partner_id.name]]
-
-
- [[ formatLang(voucher.date , date=True) or '' ]] [[ voucher.journal_id.use_preprint_check and voucher.chk_seq or '' ]]
-
-
-
-
-
-
- Due Date
-
-
- Description
-
-
- Original Amount
-
-
- Open Balance
-
-
- Discount
-
-
- Payment
-
-
-
-
- [[ repeatIn(get_lines(voucher.line_dr_ids),'l') ]] [[ formatLang(l['date_due'] ,date=True) or '' ]]
-
-
- [[ l['name'] ]]
-
-
- [[ formatLang (l['amount_original']) ]]
-
-
- [[ formatLang (l['amount_unreconciled']) ]]
-
-
-
-
-
-
-
- [[ formatLang (l['amount']) ]]
-
-
-
-
-
-
- Check Amount
-
-
- [[ formatLang (voucher.amount) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_check_writing/views/report_check.xml b/addons/account_check_writing/views/report_check.xml
new file mode 100644
index 00000000000..d740de1a0a4
--- /dev/null
+++ b/addons/account_check_writing/views/report_check.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Due Date
+ Description
+ Original Amount
+ Open Balance
+ Discount
+ Payment
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_followup/__openerp__.py b/addons/account_followup/__openerp__.py
index dbb4ea6583e..61e9ea2d4ae 100644
--- a/addons/account_followup/__openerp__.py
+++ b/addons/account_followup/__openerp__.py
@@ -55,11 +55,12 @@ Note that if you want to check the follow-up level for a given partner/account e
'account_followup_view.xml',
'account_followup_customers.xml',
'wizard/account_followup_print_view.xml',
+ 'views/report_followup.xml',
+ 'account_followup_reports.xml'
],
'demo': ['account_followup_demo.xml'],
'test': [
'test/account_followup.yml',
- #TODO 'test/account_followup_report.yml', --> Need to wait for second step in order to check report (expects after first)
],
'installable': True,
'auto_install': False,
diff --git a/addons/account_followup/account_followup.py b/addons/account_followup/account_followup.py
index 9237282ad80..5f912b61b37 100644
--- a/addons/account_followup/account_followup.py
+++ b/addons/account_followup/account_followup.py
@@ -21,7 +21,7 @@
from openerp.osv import fields, osv
from lxml import etree
-
+import openerp.tools as tools
from openerp.tools.translate import _
class followup(osv.osv):
@@ -189,11 +189,7 @@ class res_partner(osv.osv):
'model': 'account_followup.followup',
'form': data
}
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'account_followup.followup.print',
- 'datas': datas,
- }
+ return self.pool['report'].get_action(cr, uid, wizard_partner_ids, 'account_followup.report_followup', data=datas, context=context)
def do_partner_mail(self, cr, uid, partner_ids, context=None):
if context is None:
@@ -247,8 +243,7 @@ class res_partner(osv.osv):
if partner.unreconciled_aml_ids:
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
current_date = fields.date.context_today(self, cr, uid, context=context)
- rml_parse = account_followup_print.report_rappel(cr, uid, "followup_rml_parser")
- final_res = rml_parse._lines_get_with_partner(partner, company.id)
+ final_res = self.pool['report.account_followup.report_followup']._lines_get_with_partner(partner, company.id, cr=cr, uid=uid)
for currency_dict in final_res:
currency = currency_dict.get('line', [{'currency_id': company.currency_id}])[0]['currency_id']
@@ -274,7 +269,11 @@ class res_partner(osv.osv):
strbegin = ""
strend = " "
followup_table +="" + strbegin + str(aml['date']) + strend + strbegin + aml['name'] + strend + strbegin + aml['ref'] + strend + strbegin + str(date) + strend + strbegin + str(aml['balance']) + strend + strbegin + block + strend + " "
- total = rml_parse.formatLang(total, dp='Account', currency_obj=currency)
+
+ total = reduce(lambda x, y: x+y['balance'], currency_dict['line'], 0.00)
+
+ report_obj = self.pool.get('report')
+ total = report_obj.formatLang(total, dp='Account', currency_obj=currency, cr=cr, uid=uid)
followup_table += '''
''' + _("Amount due") + ''' : %s ''' % (total)
diff --git a/addons/account_followup/account_followup_reports.xml b/addons/account_followup/account_followup_reports.xml
new file mode 100644
index 00000000000..16149a5fd47
--- /dev/null
+++ b/addons/account_followup/account_followup_reports.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/addons/account_followup/account_followup_view.xml b/addons/account_followup/account_followup_view.xml
index e233feb489e..57f71566db0 100644
--- a/addons/account_followup/account_followup_view.xml
+++ b/addons/account_followup/account_followup_view.xml
@@ -132,7 +132,6 @@
id="menu_manual_reconcile_followup"/>
-
account.move.line.partner.tree
diff --git a/addons/account_followup/report/account_followup_print.rml b/addons/account_followup/report/account_followup_print.rml
deleted file mode 100644
index 6eadaed8675..00000000000
--- a/addons/account_followup/report/account_followup_print.rml
+++ /dev/null
@@ -1,238 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(ids_to_objects(data['form']['partner_ids']),'o') ]]
- [[ setLang(o.partner_id.lang) ]]
-
-
-
-
-
-
- [[ o.partner_id.name or '' ]]
- [[ display_address(o.partner_id) or '']]
-
-
-
- VAT: [[ o.partner_id.vat or removeParentNode('para') ]]
-
-
-
-
-
-
- Document : Customer account statement
- Date : [[ formatLang(data['form']['date'],date=True) ]]
- Customer Ref : [[ o.partner_id.ref or '' ]]
-
-
-
- [[ format(get_text(o,data['form']['followup_id'])) ]]
-
-
-
-
-
-
- [[repeatIn(getLines(o), 'cur_lines') ]]
-
-
- Invoice Date
-
-
- Description
-
-
- Ref
-
-
- Maturity Date
-
-
- Amount
-
-
- Li.
-
-
-
-
-
- [[repeatIn(cur_lines['line'], 'line') ]]
-
- [[ formatLang(line['date'],date = True) ]]
-
-
- [[ line['name'] ]]
-
-
- [[ line['ref'] ]]
-
-
- [[ line['date_maturity'] and formatLang(line['date_maturity'], date=True) ]]
-
-
- [[ formatLang(line['balance'], currency_obj=line['currency_id']) ]]
-
-
- [[ line['blocked'] and 'X' or '' ]]
-
-
-
-
-
-
-
-
-
-
-
- Total:
-
-
- [[formatLang(reduce(lambda x,y: x+y['balance'], cur_lines['line'], 0.00), currency_obj=line['currency_id']) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_followup/tests/test_account_followup.py b/addons/account_followup/tests/test_account_followup.py
index 9e70430c518..b3025021278 100644
--- a/addons/account_followup/tests/test_account_followup.py
+++ b/addons/account_followup/tests/test_account_followup.py
@@ -59,7 +59,6 @@ class TestAccountFollowup(TransactionCase):
self.wizard.do_process(cr, uid, [self.wizard_id], context={"followup_id": self.followup_id})
self.assertFalse(self.partner.browse(cr, uid, self.partner_id).latest_followup_level_id)
-
def run_wizard_three_times(self):
cr, uid = self.cr, self.uid
current_date = datetime.datetime.utcnow()
@@ -131,7 +130,7 @@ class TestAccountFollowup(TransactionCase):
self.run_wizard_three_times()
self.assertEqual(self.partner.browse(cr, uid, self.partner_id).latest_followup_level_id.id,
self.last_followup_line_id, "Lines are not equal")
-
+
def test_06_pay_the_invoice(self):
"""Run wizard until manual action, pay the invoice and check that partner has no follow-up level anymore and after running the wizard the action is empty"""
cr, uid = self.cr, self.uid
@@ -148,7 +147,6 @@ class TestAccountFollowup(TransactionCase):
'followup_id': self.followup_id
}, context={"followup_id": self.followup_id})
self.wizard.do_process(cr, uid, [self.wizard_id], context={"followup_id": self.followup_id})
- partner_ref = self.partner.browse(cr, uid, self.partner_id)
self.assertEqual(0, self.partner.browse(cr, uid, self.partner_id).payment_amount_due, "Amount Due != 0")
self.assertFalse(self.partner.browse(cr, uid, self.partner_id).payment_next_action_date, "Next action date not cleared")
diff --git a/addons/account_followup/views/report_followup.xml b/addons/account_followup/views/report_followup.xml
new file mode 100644
index 00000000000..6c79fe4cc55
--- /dev/null
+++ b/addons/account_followup/views/report_followup.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+ Document: Customer account statement
+ Date:
+ Customer ref:
+
+
+
+
+
+
+
+
+ Invoice Date
+ Description
+ Ref
+ Maturity Date
+ Amount
+ Li.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
diff --git a/addons/account_payment/__openerp__.py b/addons/account_payment/__openerp__.py
index 4c3c8f045e3..c5cccc38c26 100644
--- a/addons/account_payment/__openerp__.py
+++ b/addons/account_payment/__openerp__.py
@@ -54,6 +54,8 @@ have a new option to import payment orders as bank statement lines.
'account_payment_workflow.xml',
'account_payment_sequence.xml',
'account_payment_report.xml',
+
+ 'views/report_paymentorder.xml',
],
'demo': ['account_payment_demo.xml'],
'test': [
diff --git a/addons/account_payment/account_payment_report.xml b/addons/account_payment/account_payment_report.xml
index 699207e1733..3a57abe901f 100644
--- a/addons/account_payment/account_payment_report.xml
+++ b/addons/account_payment/account_payment_report.xml
@@ -1,6 +1,13 @@
-
+
diff --git a/addons/account_payment/report/order.rml b/addons/account_payment/report/order.rml
deleted file mode 100644
index 02675baf0b2..00000000000
--- a/addons/account_payment/report/order.rml
+++ /dev/null
@@ -1,290 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Partner
-
-
- Bank Account
-
-
- Invoice Ref
-
-
- Value Date
-
-
- Amount
-
-
- Currency
-
-
-
-
- [[ repeatIn(objects, 'o') ]]
-
-
-
-
-
-
-
-
-
-
-
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.name or '']]
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.street or '']]
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.street2 or removeParentNode('para')]]
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.zip or '']] [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.city or '']]
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.state and o.mode.bank_id.bank.state.name or removeParentNode('para') ]]
- [[ o.mode and o.mode.bank_id.bank and o.mode.bank_id.bank.country and o.mode.bank_id.bank.country.name or '']]
-
-
-
-
-
-
- Payment Order / Payment
-
-
-
-
-
-
- Payment Type
-
-
- Reference
-
-
- Used Account
-
-
- Execution Type
-
-
- Company Currency
-
-
-
-
-
-
- [[ o.mode and o.mode.name or '-' ]]
-
-
- [[ o.reference or '-' ]]
-
-
- [[get_account_name(o.mode.bank_id.id)]]
-
-
- [[ o.date_prefered == 'now' and 'Now' or removeParentNode('para') ]]
- [[ o.date_prefered == 'due' and 'Due date' or removeParentNode('para') ]]
- [[ o.date_prefered == 'fixed' and 'Fixed date' or removeParentNode('para') ]]
-
-
- [[ o.user_id and o.user_id.company_id and o.user_id.company_id.currency_id and o.user_id.company_id.currency_id.name or '' ]]
-
-
-
-
-
-
-
-
-
- Partner
-
-
- Bank Account
-
-
- Invoice Ref
-
-
- Value Date
-
-
- Amount
-
-
- Currency
-
-
-
-
- [[repeatIn(o.line_ids, 'line') ]]
-
-
-
- [[line.partner_id and line.partner_id.name or '-' ]]
-
-
- [[get_account_name(line.bank_id.id) or '-']]
-
-
- [[ get_invoice_name(line.ml_inv_ref.id) or '-' ]]
-
-
- [[not line.date and '-' or formatLang(line.date,date=True) ]]
-
-
- [[ formatLang(line.amount or 0.0, currency_obj=line.company_currency) ]]
-
-
- [[ formatLang(line.amount_currency, currency_obj=line.currency) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Total:
-
-
- [[ formatLang(get_amount_total(o), currency_obj=o.company_id.currency_id) or '' ]]
-
-
- [[ formatLang(get_amount_total_in_currency(o), currency_obj=(o.line_ids and o.line_ids[0].currency or None)) or '' ]]
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_payment/views/report_paymentorder.xml b/addons/account_payment/views/report_paymentorder.xml
new file mode 100644
index 00000000000..c2662b6aa77
--- /dev/null
+++ b/addons/account_payment/views/report_paymentorder.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
Payment Order / Payment
+
+
+
+
+
+
+ Partner
+ Bank Account
+ Invoice Ref
+ Value Date
+ Amount
+ Currency
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total
+
+
+
+
+
+ Total (Currency)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_test/__openerp__.py b/addons/account_test/__openerp__.py
index cfd4007fed0..51b47bace7a 100644
--- a/addons/account_test/__openerp__.py
+++ b/addons/account_test/__openerp__.py
@@ -19,11 +19,12 @@
# along with this program. If not, see .
#
##############################################################################
+
{
- 'name' : 'Accounting Consistency Tests',
- 'version' : '1.0',
- 'author' : 'OpenERP',
- 'category' : 'Accounting & Finance',
+ 'name': 'Accounting Consistency Tests',
+ 'version': '1.0',
+ 'author': 'OpenERP',
+ 'category': 'Accounting & Finance',
'website': 'http://www.openerp.com',
'description': """
Asserts on accounting.
@@ -34,14 +35,16 @@ You can write a query in order to create Consistency Test and you will get the r
in PDF format which can be accessed by Menu Reporting -> Accounting Tests, then select the test
and print the report from Print button in header area.
""",
- 'depends' : ['account'],
- 'data' : [
+ 'depends': ['account'],
+ 'data': [
'security/ir.model.access.csv',
'account_test_view.xml',
'account_test_report.xml',
'account_test_data.xml',
+ 'views/report_accounttest.xml',
],
'active': False,
'installable': True
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_test/account_test_report.xml b/addons/account_test/account_test_report.xml
index 480507b6072..732b9e9fbdb 100644
--- a/addons/account_test/account_test_report.xml
+++ b/addons/account_test/account_test_report.xml
@@ -1,14 +1,13 @@
-
-
-
-
-
+
+
+
diff --git a/addons/account_test/report/account_test.rml b/addons/account_test/report/account_test.rml
deleted file mode 100644
index 1efa12fd5cb..00000000000
--- a/addons/account_test/report/account_test.rml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Accouting tests on [[ datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") ]]
-
-
-
-
- [[repeatIn(objects,'o')]]
-
-
-
- [[ o.name ]]
-
-
-
-
- [[ o.desc or '' ]]
-
-
-
-
-
-
- [[ repeatIn(execute_code(o.code_exec), 'test_result') ]]
- [[ test_result ]]
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_test/views/report_accounttest.xml b/addons/account_test/views/report_accounttest.xml
new file mode 100644
index 00000000000..02ce82218dc
--- /dev/null
+++ b/addons/account_test/views/report_accounttest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
Accouting tests on
+
+
+ Name:
+ Description:
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/account_voucher/__openerp__.py b/addons/account_voucher/__openerp__.py
index 0659e4f4bae..6a3b0ee81cd 100644
--- a/addons/account_voucher/__openerp__.py
+++ b/addons/account_voucher/__openerp__.py
@@ -49,7 +49,6 @@ This module manages:
'security/ir.model.access.csv',
'account_voucher_sequence.xml',
'account_voucher_workflow.xml',
- 'account_voucher_report.xml',
'wizard/account_statement_from_invoice_view.xml',
'account_voucher_view.xml',
'voucher_payment_receipt_view.xml',
@@ -59,6 +58,7 @@ This module manages:
'report/account_voucher_sales_receipt_view.xml',
'security/account_voucher_security.xml',
'account_voucher_data.xml',
+ 'account_voucher_report.xml',
],
'test' : [
'test/account_voucher_users.yml',
@@ -66,7 +66,6 @@ This module manages:
'test/account_voucher.yml',
'test/sales_receipt.yml',
'test/sales_payment.yml',
- 'test/account_voucher_report.yml',
'test/case1_usd_usd.yml',
'test/case1_usd_usd_payment_rate.yml',
'test/case2_usd_eur_debtor_in_eur.yml',
@@ -74,6 +73,7 @@ This module manages:
'test/case3_eur_eur.yml',
'test/case4_cad_chf.yml',
'test/case_eur_usd.yml',
+ 'account_voucher_report.yml',
],
'auto_install': False,
'application': True,
diff --git a/addons/account_voucher/report/account_voucher.rml b/addons/account_voucher/report/account_voucher.rml
deleted file mode 100644
index 6b3337aa64f..00000000000
--- a/addons/account_voucher/report/account_voucher.rml
+++ /dev/null
@@ -1,446 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'voucher') ]]
-
-
-
- [[ get_title(voucher.type) ]]
-
-
-
-
-
-
-
-
-
- Journal:
-
-
- [[ voucher.type ]]
-
-
- Number:
-
-
- [[ voucher.number ]]
-
-
-
-
-
-
- Status:
-
-
- PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
- Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
- Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
- Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
-
-
- Ref. :
-
-
- [[ voucher.reference or '' ]]
-
-
- Date:
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
-
-
-
-
-
-
-
- Particulars
-
-
- Debit
-
-
- Credit
-
-
-
-
-
-
-
- [[ repeatIn(voucher.move_ids,'move_ids') ]]
-
-
-
- [[ (move_ids.partner_id and move_ids.partner_id.name) or 'Account']]
-
-
- [[ formatLang(move_ids.debit) ]]
-
-
- [[ formatLang(move_ids.credit) ]]
-
-
-
-
- [[ move_ids.account_id.name ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ move_ids.name ]] - [[ get_ref(voucher.id,move_ids) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Through :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.narration or '']]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- On Account of :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ voucher.name ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Amount (in words) :
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ convert(voucher.amount,voucher.currency_id.name) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ debit(voucher.move_ids)]]
-
-
- [[ credit(voucher.move_ids) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Receiver's Signature
-
-
-
-
-
-
-
-
-
-
-
-
- Authorised Signatory
-
-
-
-
-
-
-
-
diff --git a/addons/account_voucher/report/account_voucher_print.rml b/addons/account_voucher/report/account_voucher_print.rml
deleted file mode 100644
index 9f0f2e1f07e..00000000000
--- a/addons/account_voucher/report/account_voucher_print.rml
+++ /dev/null
@@ -1,331 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'voucher') ]]
-
-
-
- [[ get_title(voucher.type) ]]
-
-
-
-
-
-
-
-
-
- Number:
-
-
- [[ voucher.number ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Date:
-
-
- [[ formatLang(voucher.date , date=True) or '' ]]
-
-
-
-
-
-
- Status:
-
-
- PRO-FORMA [[ ((voucher.state == 'proforma') or removeParentNode('para')) and '' ]]
- Draft[[ ((voucher.state == 'draft') or removeParentNode('para')) and '' ]]
- Canceled [[ ((voucher.state == 'cancel') or removeParentNode('para')) and '' ]]
- Posted [[ ((voucher.state == 'posted') or removeParentNode('para')) and '' ]]
-
-
-
-
-
-
-
-
-
-
-
-
- Currency:
-
-
- [[ voucher.currency_id.symbol ]]
-
-
-
-
-
-
-
-
-
- Particulars
-
-
- Amount
-
-
-
-
-
-
-
- [[ repeatIn(get_lines(voucher),'p') ]]
-
-
-
- Account :
-
-
-
-
-
-
-
-
-
- [[ p['pname'] ]]
-
-
- [[ formatLang(p['amount'], currency_obj=voucher.currency_id) ]]
-
-
-
-
- [[ p['ref'] ]]
-
-
-
-
-
-
-
-
-
- Account : [[ p['aname'] ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Through :
-
-
-
-
-
-
-
-
-
- [[ voucher.journal_id.name or '' ]]
-
-
-
-
-
-
-
-
-
- On Account of :
-
-
-
-
-
-
-
-
-
- [[ get_on_account(voucher) ]]
-
-
-
-
-
-
-
-
-
- Amount (in words) :
-
-
-
-
-
-
-
-
-
- [[ convert(voucher.amount,voucher.currency_id.name) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ formatLang(voucher.amount, currency_obj=voucher.currency_id) ]]
-
-
-
-
-
diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py
index 5cff7b4aae2..f8435ba8245 100644
--- a/addons/report/controllers/main.py
+++ b/addons/report/controllers/main.py
@@ -143,12 +143,17 @@ class ReportController(Controller):
elif value.lower() == 'true':
param[key] = True
elif ',' in value:
- param[key] = [int(i) for i in value.split(',')]
+ try:
+ param[key] = [int(i) for i in value.split(',')]
+ except ValueError:
+ param[key] = value.split(',')
+ if len(param[key]) == 1:
+ param[key] = value
else:
try:
param[key] = int(value)
except (ValueError, TypeError):
- pass
+ continue
else:
if isinstance(param, (str, unicode)):
param = [int(i) for i in param.split(',')]
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 8abe8e544eb..b93bbe09f89 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -74,7 +74,7 @@ class Report(osv.Model):
# Extension of ir_ui_view.render with arguments frequently used in reports
#--------------------------------------------------------------------------
- def _get_digits(self, cr, uid, obj=None, f=None, dp=None):
+ def _get_digits(self, cr=None, uid=None, obj=None, f=None, dp=None):
d = DEFAULT_DIGITS = 2
if dp:
decimal_precision_obj = self.pool['decimal.precision']
@@ -118,6 +118,14 @@ class Report(osv.Model):
def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
return len((datetime.now()).strftime(date_format))
+ # In case we use formatLang on the model (and not in the rendering environment).
+ if not hasattr(self, 'land_ditct'):
+ self.localcontext = {}
+ self.lang_dict = {}
+ self.default_lang = {}
+ self._get_lang_dict(cr, uid)
+ self.lang_dict_called = True
+
if digits is None:
if dp:
digits = self._get_digits(cr, uid, dp=dp)
@@ -212,7 +220,7 @@ class Report(osv.Model):
values.update({
'time': time,
'formatLang': partial(self.formatLang, cr=cr, uid=uid),
- 'get_digits': self._get_digits,
+ 'get_digits': partial(self._get_digits, cr=cr, uid=uid),
'render_doc': render_doc,
'editable': True, # Will active inherit_branding
'res_company': self.pool['res.users'].browse(cr, uid, uid).company_id,
@@ -377,7 +385,7 @@ class Report(osv.Model):
)
return pdf
- def get_action(self, cr, uid, ids, report_name, datas=None, context=None):
+ def get_action(self, cr, uid, ids, report_name, data=None, context=None):
"""Return an action of type ir.actions.report.xml.
:param report_name: Name of the template to generate an action for
@@ -386,8 +394,8 @@ class Report(osv.Model):
if context is None:
context = {}
- if datas is None:
- datas = {}
+ if data is None:
+ data = {}
report_obj = self.pool.get('ir.actions.report.xml')
idreport = report_obj.search(cr, uid, [('report_name', '=', report_name)], context=context)
@@ -405,8 +413,8 @@ class Report(osv.Model):
'report_file': report.report_file,
}
- if datas:
- action['datas'] = datas
+ if data:
+ action['datas'] = data
return action
@@ -566,8 +574,8 @@ class Report(osv.Model):
command_args.extend(['--page-size', paperformat.format])
if paperformat.page_height and paperformat.page_width and paperformat.format == 'custom':
- command_args.extend(['--page-width', str(paperformat.page_width) + 'in'])
- command_args.extend(['--page-height', str(paperformat.page_height) + 'in'])
+ command_args.extend(['--page-width', str(paperformat.page_width) + 'mm'])
+ command_args.extend(['--page-height', str(paperformat.page_height) + 'mm'])
if specific_paperformat_args and specific_paperformat_args['data-report-margin-top']:
command_args.extend(['--margin-top',
diff --git a/addons/report/models/report_paperformat.py b/addons/report/models/report_paperformat.py
index e3e747b81a4..6b84f3d3363 100644
--- a/addons/report/models/report_paperformat.py
+++ b/addons/report/models/report_paperformat.py
@@ -69,8 +69,8 @@ class report_paperformat(osv.Model):
'margin_bottom': fields.integer('Bottom Margin (mm)'),
'margin_left': fields.integer('Left Margin (mm)'),
'margin_right': fields.integer('Right Margin (mm)'),
- 'page_height': fields.integer('Page height (in)'),
- 'page_width': fields.integer('Page width (in)'),
+ 'page_height': fields.integer('Page height (mm)'),
+ 'page_width': fields.integer('Page width (mm)'),
'orientation': fields.selection([('Landscape', 'Landscape'),
('Portrait', 'Portrait')],
'Orientation'),
diff --git a/addons/report/views/layouts.xml b/addons/report/views/layouts.xml
index 588775fc41e..721176738cb 100644
--- a/addons/report/views/layouts.xml
+++ b/addons/report/views/layouts.xml
@@ -6,7 +6,10 @@
+ t-att-data-main-object="repr(main_object) if editable else None"
+ t-att-data-report-margin-top="data_report_margin_top if data_report_margin_top else None"
+ t-att-data-report-header-spacing="data_report_header_spacing if t_att_data_report_header_spacing else None"
+ t-att-data-report-dpi="data_report_dpi if data_report_dpi else None">
@@ -158,5 +161,6 @@
+
diff --git a/addons/report_intrastat/__init__.py b/addons/report_intrastat/__init__.py
index d2f598434a2..119777f2c70 100644
--- a/addons/report_intrastat/__init__.py
+++ b/addons/report_intrastat/__init__.py
@@ -20,7 +20,5 @@
##############################################################################
import report_intrastat
-import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/report_intrastat/__openerp__.py b/addons/report_intrastat/__openerp__.py
index 0fa57977db1..4682a777ccc 100644
--- a/addons/report_intrastat/__openerp__.py
+++ b/addons/report_intrastat/__openerp__.py
@@ -19,7 +19,6 @@
#
##############################################################################
-
{
'name': 'Intrastat Reporting',
'version': '1.0',
@@ -37,7 +36,8 @@ European Union.""",
'security/ir.model.access.csv',
'report_intrastat_view.xml',
'intrastat_report.xml',
- 'report_intrastat_data.xml'
+ 'report_intrastat_data.xml',
+ 'views/report_intrastatinvoice.xml'
],
'demo': [],
'test': ['test/report_intrastat_report.yml'],
@@ -45,4 +45,5 @@ European Union.""",
'auto_install': False,
'images': ['images/country_intrastat_code.jpeg','images/intrastat_code.jpeg'],
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/report_intrastat/intrastat_report.xml b/addons/report_intrastat/intrastat_report.xml
index 124cf899efb..c5a8e9e7f84 100644
--- a/addons/report_intrastat/intrastat_report.xml
+++ b/addons/report_intrastat/intrastat_report.xml
@@ -1,13 +1,13 @@
-
-
-
+
+
+
-
-
diff --git a/addons/report_intrastat/report/__init__.py b/addons/report_intrastat/report/__init__.py
deleted file mode 100644
index 64e530bc278..00000000000
--- a/addons/report_intrastat/report/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-import invoice
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/report_intrastat/report/invoice.py b/addons/report_intrastat/report/invoice.py
deleted file mode 100644
index c38a62774ac..00000000000
--- a/addons/report_intrastat/report/invoice.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-
-import time
-from openerp.report import report_sxw
-
-class account_invoice_intrastat(report_sxw.rml_parse):
- def __init__(self, cr, uid, name, context):
- super(account_invoice_intrastat, self).__init__(cr, uid, name, context=context)
- self.total=0
- self.localcontext.update({
- 'time': time,
- })
-
-report_sxw.report_sxw('report.account.invoice.intrastat', 'account.invoice', 'addons/report_intrastat/report/invoice.rml', parser=account_invoice_intrastat)
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/report_intrastat/report/invoice.rml b/addons/report_intrastat/report/invoice.rml
deleted file mode 100644
index fc410e04ce0..00000000000
--- a/addons/report_intrastat/report/invoice.rml
+++ /dev/null
@@ -1,401 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ repeatIn(objects,'o') ]]
- [[ setLang(o.partner_id.lang) ]]
-
-
-
-
-
-
-
-
- [[ (o.partner_id.title and o.partner_id.title.name) or '' ]] [[ (o.partner_id and o.partner_id.name) or '' ]]
- [[ o.partner_id and display_address(o.partner_id) ]]
-
-
-
- Tel. : [[ (o.partner_id.phone) or removeParentNode('para') ]]
- Fax : [[ (o.partner_id.fax) or removeParentNode('para') ]]
- VAT : [[ (o.partner_id.vat) or removeParentNode('para') ]]
-
-
-
- Invoice [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]]
- PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]]
- Draft Invoice [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]]
- Cancelled Invoice [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]]
- Refund [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]
- Supplier Refund [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]
- Supplier Invoice [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]]
-
-
-
-
-
-
- Document
-
-
- Invoice Date
-
-
- Partner Ref.
-
-
-
-
-
-
- [[ o.name or ' ' ]]
-
-
- [[ formatLang(o.date_invoice,date=True) ]]
-
-
- [[ (o.partner_id.ref) or ' ' ]]
-
-
-
-
-
-
-
-
-
- Description
-
-
- Taxes
-
-
- Intrastat
-
-
- Weight
-
-
- Quantity
-
-
- Unit Price
-
-
- Disc. (%)
-
-
- Price
-
-
-
-
- [[ repeatIn(o.invoice_line,'l') ]]
-
-
-
- [[ l.name ]]
-
-
- [[ ', '.join([lt.name for lt in l.invoice_line_tax_id]) ]]
-
-
- [[l.product_id and l.product_id.intrastat_id and l.product_id.intrastat_id.name or '']]
-
-
- [[ l.product_id and l.product_id.weight or '']]
-
-
- [[ formatLang(l.quantity) ]] [[ (l.uos_id and l.uos_id.name) or '' ]]
-
-
- [[ formatLang(l.price_unit) ]]
-
-
- [[ l.discount and formatLang (l.discount) or '' ]]
-
-
- [[ formatLang(l.price_subtotal, currency_obj=o.currency_id) ]]
-
-
-
-
- [[ format(l.note or removeParentNode('tr')) ]]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Total (excl. taxes):
-
-
- [[ formatLang(o.amount_untaxed, currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Taxes:
-
-
- [[ formatLang(o.amount_tax, currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Total (inclu. taxes):
-
-
- [[ formatLang(o.amount_total, currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
- Tax [[ o.tax_line==[] and removeParentNode('blockTable') ]]
-
-
- Base
-
-
- Amount
-
-
-
-
-
-
-
-
-
- [[ repeatIn(o.tax_line,'t') ]]
-
-
-
- [[ t.name ]]
-
-
- [[ formatLang(t.base, digits=get_digits(dp='Account'), currency_obj = o.currency_id) ]]
-
-
- [[ (t.tax_code_id and t.tax_code_id.notprintable) and removeParentNode('blockTable') or '' ]] [[ formatLang(t.amount, digits=get_digits(dp='Account'), currency_obj=o.currency_id) ]]
-
-
-
-
-
-
-
-
-
-
-
-
- [[ (o.comment and format(o.comment )) or removeParentNode('para') ]]
-
-
-
- [[ (o.payment_term and o.payment_term.note and format(o.payment_term and o.payment_term.note)) or removeParentNode('para') ]]
-
-
-
-
-
-
- Fiscal Position Remark :
-
-
- [[ (o.fiscal_position and o.fiscal_position.note and format(o.fiscal_position.note)) or removeParentNode('blockTable') ]]
-
-
-
-
-
-
-
-
diff --git a/addons/report_intrastat/views/report_intrastatinvoice.xml b/addons/report_intrastat/views/report_intrastatinvoice.xml
new file mode 100644
index 00000000000..e8bce6e952d
--- /dev/null
+++ b/addons/report_intrastat/views/report_intrastatinvoice.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+ Invoice
+ PRO-FORMA
+ Draft Invoice
+ Cancelled Invoice
+ Refund
+ Supplier Refund
+ Supplier Invoice
+
+
+
+
+
+
+
+
+ Description
+ Taxes
+ Intrastat
+ Weight
+ Quantity
+ Unit of measure
+ Unit Price
+ Discount (%)
+ Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total Without Taxes
+
+
+
+
+
+ Taxes
+
+
+
+
+
+ Total
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tax
+ Base
+ Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Comment:
+
+
+
+ Payment Term:
+
+
+
+ Fiscal Position:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 43beb0e75294a8a321c791840a26830b3f05a7c0 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Tue, 1 Apr 2014 17:31:14 +0200
Subject: [PATCH 04/57] [FIX] ir_qweb groups: in order to compute the groups of
a user, we are using cr and uid from request. In case we are rendering the
template in a non-request context (for instance, automated tests), we have no
cr and uid ; do not compute the user groups in this case.
bzr revid: sle@openerp.com-20140401153114-blxgbyp8zgx120r3
---
openerp/addons/base/ir/ir_qweb.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py
index f19a1fa6746..84551186f05 100644
--- a/openerp/addons/base/ir/ir_qweb.py
+++ b/openerp/addons/base/ir/ir_qweb.py
@@ -241,7 +241,7 @@ class QWeb(orm.AbstractModel):
if attribute_name == "groups":
cr = qwebcontext.get('request') and qwebcontext['request'].cr or None
uid = qwebcontext.get('request') and qwebcontext['request'].uid or None
- can_see = self.user_has_groups(cr, uid, groups=attribute_value)
+ can_see = self.user_has_groups(cr, uid, groups=attribute_value) if cr and uid else False
if not can_see:
return ''
continue
From c8aa0cc7f15c28c0aa1132e74fc676a45177fb5a Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Tue, 1 Apr 2014 17:33:39 +0200
Subject: [PATCH 05/57] [FIX] Adapted the render_report and try_report_action
methods used in yml test to work with qweb reports
bzr revid: sle@openerp.com-20140401153339-3n0xw5whx82uu0pu
---
openerp/addons/base/ir/ir_actions.py | 10 ++++++++--
openerp/tools/test_reports.py | 17 +++++++++++------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py
index 4cd0492d95c..61c7a1d525b 100644
--- a/openerp/addons/base/ir/ir_actions.py
+++ b/openerp/addons/base/ir/ir_actions.py
@@ -104,7 +104,9 @@ class ir_actions_report_xml(osv.osv):
cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,))
r = cr.dictfetchone()
if r:
- if r['report_rml'] or r['report_rml_content_data']:
+ if r['report_type'] in ['qweb-pdf', 'qweb-html']:
+ return r['report_name']
+ elif r['report_rml'] or r['report_rml_content_data']:
if r['parser']:
kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) }
else:
@@ -127,7 +129,11 @@ class ir_actions_report_xml(osv.osv):
Look up a report definition and render the report for the provided IDs.
"""
new_report = self._lookup_report(cr, name)
- return new_report.create(cr, uid, res_ids, data, context)
+ # in order to use current yml test files with qweb reports
+ if isinstance(new_report, (str, unicode)):
+ return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf'
+ else:
+ return new_report.create(cr, uid, res_ids, data, context)
_name = 'ir.actions.report.xml'
_inherit = 'ir.actions.actions'
diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py
index 874a8cced61..9aa55233a27 100644
--- a/openerp/tools/test_reports.py
+++ b/openerp/tools/test_reports.py
@@ -114,7 +114,6 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
Eg. 'OK' or 'gtk-print'
:param our_module: the name of the calling module (string), like 'account'
"""
-
if not our_module and isinstance(action_id, basestring):
if '.' in action_id:
our_module = action_id.split('.', 1)[0]
@@ -161,7 +160,10 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
# Updating the context : Adding the context of action in order to use it on Views called from buttons
if datas.get('id',False):
context.update( {'active_id': datas.get('id',False), 'active_ids': datas.get('ids',[]), 'active_model': datas.get('model',False)})
- context.update(safe_eval(action.get('context','{}'), context.copy()))
+ context1 = action.get('context', {})
+ if isinstance(context1, basestring):
+ context1 = safe_eval(context1, context.copy())
+ context.update(context1)
if action['type'] in ['ir.actions.act_window', 'ir.actions.submenu']:
for key in ('res_id', 'res_model', 'view_type', 'view_mode',
'limit', 'auto_refresh', 'search_view', 'auto_search', 'search_view_id'):
@@ -272,12 +274,17 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
if 'window' in datas:
del datas['window']
if not datas:
- datas = action.get('datas',{})
+ datas = action.get('datas')
+ if not datas:
+ datas = action.get('data')
datas = datas.copy()
ids = datas.get('ids')
if 'ids' in datas:
del datas['ids']
- res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
+ if action.get('report_type') in ['qweb-pdf', 'qweb-html']:
+ res = registry['report'].get_html(cr, uid, [], action.get('report_name'), data=datas, context=context)
+ else:
+ res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
return res
else:
raise Exception("Cannot handle action of type %s" % act_model)
@@ -303,6 +310,4 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
return True
-#eof
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
From 8c93dcbf62f918c10d01a62db6c04d5c173e8761 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 09:38:00 +0200
Subject: [PATCH 06/57] [IMP] refactoring of readgroup method. The work is
pretty much complete with this commit. Now, it correctly fills in empty group
using _read_group_fill_results (orm.py)
bzr revid: ged@openerp.com-20140402073800-0ggxqfpyo2in8ozt
---
openerp/osv/orm.py | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index ac07a6f5bca..45dc264c67c 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2115,7 +2115,7 @@ class BaseModel(object):
pass
- def _read_group_fill_results(self, cr, uid, domain, groupby, groupby_list, aggregated_fields,
+ def _read_group_fill_results(self, cr, uid, domain, groupby, remaining_groupbys, aggregated_fields,
read_group_result, read_group_order=None, context=None):
"""Helper method for filling in empty groups for all possible values of
the field being grouped by"""
@@ -2135,8 +2135,8 @@ class BaseModel(object):
result_template = dict.fromkeys(aggregated_fields, False)
result_template[groupby + '_count'] = 0
- if groupby_list and len(groupby_list) > 1:
- result_template['__context'] = {'group_by': groupby_list[1:]}
+ if remaining_groupbys:
+ result_template['__context'] = {'group_by': remaining_groupbys}
# Merge the left_side (current results as dicts) with the right_side (all
# possible values as m2o pairs). Both lists are supposed to be using the
@@ -2396,10 +2396,9 @@ class BaseModel(object):
def format_result (fromquery):
domain_group = [dom for gb in annotated_groupbys for dom in get_domain(gb, fromquery[gb['field']])]
- result = {
- '__domain': domain_group + domain,
- '__context': {'group_by': groupby[len(annotated_groupbys):]}
- }
+ result = { '__domain': domain_group + domain }
+ if len(groupby) - len(annotated_groupbys) >= 1:
+ result['__context'] = { 'group_by': groupby[len(annotated_groupbys):]}
result.update(fromquery)
for k,v in result.iteritems():
gb = groupby_dict.get(k)
@@ -2408,16 +2407,13 @@ class BaseModel(object):
del result['id']
return result
+ result = map(format_result, data)
+
for gb in groupby_fields:
if gb in self._group_by_full:
- print "DING"
- result = map(format_result, data)
-
- # TO DO!!!!!!!!!!!!
- # if first_groupby in self._group_by_full:
- # result = self._read_group_fill_results(cr, uid, domain, first_groupby, groupby,
- # aggregated_fields, result, read_group_order=order,
- # context=context)
+ result = self._read_group_fill_results(cr, uid, domain, gb, groupby[len(annotated_groupbys):],
+ aggregated_fields, result, read_group_order=order,
+ context=context)
return result
def _inherits_join_add(self, current_model, parent_model_name, query):
From 95b2daf17b9f3301095851e855b85dcbe6fa955f Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 09:41:22 +0200
Subject: [PATCH 07/57] [IMP] modifies the web client to be able to use the new
'lazy' parameter of the method readgroup (so now the client can requires a
readgroup to be eager/lazy) (addon web)
bzr revid: ged@openerp.com-20140402074122-sf52hult1qkqos81
---
addons/web/static/src/js/data.js | 44 ++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 8 deletions(-)
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 517afa7f5c2..413d0621011 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -27,6 +27,7 @@ instance.web.Query = instance.web.Class.extend({
this._fields = fields;
this._filter = [];
this._context = {};
+ this._lazy = true;
this._limit = false;
this._offset = 0;
this._order_by = [];
@@ -36,6 +37,7 @@ instance.web.Query = instance.web.Class.extend({
var q = new instance.web.Query(this._model, this._fields);
q._context = this._context;
q._filter = this._filter;
+ q._lazy = this._lazy;
q._limit = this._limit;
q._offset = this._offset;
q._order_by = this._order_by;
@@ -51,6 +53,7 @@ instance.web.Query = instance.web.Class.extend({
q._context = new instance.web.CompoundContext(
q._context, to_set.context);
break;
+ case 'lazy':
case 'limit':
case 'offset':
case 'order_by':
@@ -140,6 +143,7 @@ instance.web.Query = instance.web.Class.extend({
domain: this._model.domain(this._filter),
context: ctx,
offset: this._offset,
+ lazy: this._lazy,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
}).then(function (results) {
@@ -148,8 +152,9 @@ instance.web.Query = instance.web.Class.extend({
result.__context = result.__context || {};
result.__context.group_by = result.__context.group_by || [];
_.defaults(result.__context, ctx);
+ var grouping_fields = self._lazy ? [grouping[0]] : grouping;
return new instance.web.QueryGroup(
- self._model.name, grouping[0], result);
+ self._model.name, grouping_fields, result);
});
});
},
@@ -175,6 +180,18 @@ instance.web.Query = instance.web.Class.extend({
if (!domain) { return this; }
return this.clone({filter: domain});
},
+ /**
+ * Creates a new query with the provided parameter lazy replacing the current
+ * query's own.
+ *
+ * @param {Boolean} lazy indicates if the read_group should return only the
+ * first level of groupby records, or should return the records grouped by
+ * all levels at once (so, it makes only 1 db request).
+ * @returns {openerp.web.Query}
+ */
+ lazy: function (lazy) {
+ return this.clone({lazy: lazy});
+ },
/**
* Creates a new query with the provided limit replacing the current
* query's own limit
@@ -213,7 +230,7 @@ instance.web.Query = instance.web.Class.extend({
});
instance.web.QueryGroup = instance.web.Class.extend({
- init: function (model, grouping_field, read_group_group) {
+ init: function (model, grouping_fields, read_group_group) {
// In cases where group_by_no_leaf and no group_by, the result of
// read_group has aggregate fields but no __context or __domain.
// Create default (empty) values for those so that things don't break
@@ -221,29 +238,40 @@ instance.web.QueryGroup = instance.web.Class.extend({
{__context: {group_by: []}, __domain: []},
read_group_group);
- var raw_field = grouping_field && grouping_field.split(':')[0];
+ var raw_fields = _.map(grouping_fields, function (field) {
+ return field && field.split(':')[0];
+ });
+
+
var aggregates = {};
_(fixed_group).each(function (value, key) {
if (key.indexOf('__') === 0
- || key === raw_field
- || key === raw_field + '_count') {
+ || _.contains(raw_fields, key)
+ || (key === raw_fields[0] + '_count')) {
return;
}
aggregates[key] = value || 0;
});
+
this.model = new instance.web.Model(
model, fixed_group.__context, fixed_group.__domain);
- var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0;
+ var group_size = fixed_group[raw_fields[0] + '_count'] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0;
+ var value = (grouping_fields.length === 1)
+ ? fixed_group[raw_fields[0]]
+ : _.map(raw_fields, function (field) { return fixed_group[field]; });
+ var grouped_on = (grouping_fields.length === 1)
+ ? grouping_fields[0]
+ : grouping_fields;
this.attributes = {
folded: !!(fixed_group.__fold),
- grouped_on: grouping_field,
+ grouped_on: grouped_on,
// if terminal group (or no group) and group_by_no_leaf => use group.__count
length: group_size,
- value: fixed_group[raw_field],
+ value: value,
// A group is open-able if it's not a leaf in group_by_no_leaf mode
has_children: !(leaf_group && fixed_group.__context['group_by_no_leaf']),
From c4d0299eca6941e4f38f86c7e8c4a3e9a5cf84a7 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 09:43:41 +0200
Subject: [PATCH 08/57] [IMP] complete rewrite of the data loading code in the
graph view, using the lazy/eager feature of readgroup. The code is simpler
and more efficient: it only performs a fixed number of requests (well, the
number is 'fixed' in the sense that it does not depend of the size of the
data being displayed, but it still depends on the number of dimensions)
(addon web_graph)
bzr revid: ged@openerp.com-20140402074341-8cleqizqculxmkys
---
addons/web_graph/static/src/js/pivot_table.js | 406 ++++++++----------
1 file changed, 182 insertions(+), 224 deletions(-)
diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js
index f77d49f9a1a..e8a438b3fe5 100644
--- a/addons/web_graph/static/src/js/pivot_table.js
+++ b/addons/web_graph/static/src/js/pivot_table.js
@@ -82,7 +82,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
get_values: function (id1, id2, default_values) {
var cell = _.findWhere(this.cells, {x: Math.min(id1, id2), y: Math.max(id1, id2)});
- return (cell !== undefined) ? cell.values : (default_values || new Array(this.measures.length));
+ return (cell !== undefined) ?
+ cell.values :
+ (default_values || new Array(this.measures.length));
},
// ----------------------------------------------------------------------
@@ -144,12 +146,16 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
get_ancestors: function (header) {
var self = this;
if (!header.children) return [];
- return [].concat.apply([], _.map(header.children, function (c) {return self.get_ancestors_and_self(c); }));
+ return [].concat.apply([], _.map(header.children, function (c) {
+ return self.get_ancestors_and_self(c);
+ }));
},
get_ancestors_and_self: function (header) {
var self = this;
- return [].concat.apply([header], _.map(header.children, function (c) { return self.get_ancestors_and_self(c); }));
+ return [].concat.apply([header], _.map(header.children, function (c) {
+ return self.get_ancestors_and_self(c);
+ }));
},
get_total: function (header) {
@@ -205,54 +211,28 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
expand: function (header_id, groupby) {
var self = this,
header = this.get_header(header_id),
- otherRoot = this.get_other_root(header),
- fields = otherRoot.groupby.concat(this.measures);
+ other_root = this.get_other_root(header),
+ this_gb = [groupby.field],
+ other_gbs = _.pluck(other_root.groupby, 'field');
if (header.path.length === header.root.groupby.length) {
header.root.groupby.push(groupby);
}
- groupby = [groupby].concat(otherRoot.groupby);
-
- return this.get_groups(groupby, fields, header.domain).then(function (groups) {
- _.each(groups.reverse(), function (group) {
- // make header
- var child = self.make_header(group, header);
- child.expanded = false;
- header.children.splice(0,0, child);
- header.root.headers.splice(header.root.headers.indexOf(header) + 1, 0, child);
- // make cells
- _.each(self.get_ancestors_and_self(group), function (data) {
- var values = _.map(self.measures, function (m) {
- return data.attributes.aggregates[m.field];
- });
- var other = _.find(otherRoot.headers, function (h) {
- if (header.root === self.cols) {
- return _.isEqual(data.path.slice(1), h.path);
- } else {
- return _.isEqual(_.rest(data.path), h.path);
- }
- });
- if (other) {
- self.add_cell(child.id, other.id, values);
- }
- });
+ return this.perform_requests(this_gb, other_gbs, header.domain).then(function () {
+ var data = Array.prototype.slice.call(arguments);
+ data = data.slice(other_gbs.length + 1, data.length);
+ _.each(data, function (data_pt) {
+ self.make_headers_and_cell(
+ data_pt, header.root.headers, other_root.headers, 1, header.path);
});
header.expanded = true;
+ header.children.forEach(function (child) {
+ child.expanded = false;
+ child.root = header.root;
+ });
});
},
- make_header: function (group, parent) {
- var title = parent ? group.attributes.value : _t('Total');
- return {
- id: _.uniqueId(),
- path: parent ? parent.path.concat(title) : [],
- title: title,
- children: [],
- domain: parent ? group.model._domain : this.domain,
- root: parent ? parent.root : undefined,
- };
- },
-
swap_axis: function () {
var temp = this.rows;
this.rows = this.cols;
@@ -262,206 +242,184 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
// ----------------------------------------------------------------------
// Data updating methods
// ----------------------------------------------------------------------
- // Load the data from the db, using the method this.load_data
// update_data will try to preserve the expand/not expanded status of each
// column/row. If you want to expand all, then set this.cols.headers/this.rows.headers
// to null before calling update_data.
- update_data: function () {
- var self = this;
+ update_data: function () {
+ var self = this;
+ return this.perform_requests().then (function () {
+ var data = Array.prototype.slice.call(arguments);
+ self.no_data = !data[0][0].attributes.length;
+ if (self.no_data) {
+ return;
+ }
+ var row_headers = [],
+ col_headers = [];
+ self.cells = [];
- return this.load_data().then (function (result) {
- if (result) {
- self.no_data = false;
- self[self.cols.headers ? 'update_headers' : 'expand_headers'](self.cols, result.col_headers);
- self[self.rows.headers ? 'update_headers' : 'expand_headers'](self.rows, result.row_headers);
- } else {
- self.no_data = true;
- }
- });
- },
+ var dim_col = self.cols.groupby.length,
+ i, j, index;
- expand_headers: function (root, new_headers) {
- root.headers = new_headers;
- _.each(root.headers, function (header) {
- header.root = root;
- header.expanded = (header.children.length > 0);
- });
- },
-
- update_headers: function (root, new_headers) {
- _.each(root.headers, function (header) {
- var corresponding_header = _.find(new_headers, function (h) {
- return _.isEqual(h.path, header.path);
- });
- if (corresponding_header && header.expanded) {
- corresponding_header.expanded = true;
- _.each(corresponding_header.children, function (c) {
- c.expanded = false;
- });
- }
- if (corresponding_header && (!header.expanded)) {
- corresponding_header.expanded = false;
- }
- });
- var updated_headers = _.filter(new_headers, function (header) {
- return (header.expanded !== undefined);
- });
- _.each(updated_headers, function (header) {
- if (!header.expanded) {
- header.children = [];
- }
- header.root = root;
- });
- root.headers = updated_headers;
- },
-
- // ----------------------------------------------------------------------
- // Data loading methods
- // ----------------------------------------------------------------------
-
- // To obtain all the values required to draw the full table, we have to do
- // at least 2 + min(row.groupby.length, col.groupby.length)
- // calls to readgroup. To simplify the code, we will always do
- // 2 + row.groupby.length calls. For example, if row.groupby = [r1, r2, r3]
- // and col.groupby = [c1, c2], then we will make the call with the following
- // groupbys: [r1,r2,r3], [c1,r1,r2,r3], [c1,c2,r1,r2,r3], [].
- load_data: function () {
- var self = this,
- cols = this.cols.groupby,
- rows = this.rows.groupby,
- visible_fields = rows.concat(cols, self.measures);
-
- if (this.measures.length === 0) {
- return $.Deferred.resolve().promise();
- }
-
- var groupbys = _.map(_.range(cols.length + 1), function (i) {
- return cols.slice(0, i).concat(rows);
- });
- groupbys.push([]);
-
- var get_data_requests = _.map(groupbys, function (groupby) {
- return self.get_groups(groupby, visible_fields, self.domain);
- });
-
- return $.when.apply(null, get_data_requests).then(function () {
- var data = Array.prototype.slice.call(arguments),
- row_data = data[0],
- col_data = (cols.length !== 0) ? data[data.length - 2] : [],
- has_data = data[data.length - 1][0];
-
- return has_data && self.format_data(col_data, row_data, data);
+ for (i = 0; i < self.rows.groupby.length + 1; i++) {
+ for (j = 0; j < dim_col + 1; j++) {
+ index = i*(dim_col + 1) + j;
+ self.make_headers_and_cell(data[index], row_headers, col_headers, i);
+ }
+ }
+ self.set_headers(row_headers, self.rows);
+ self.set_headers(col_headers, self.cols);
});
},
- get_groups: function (groupbys, fields, domain, path) {
- var self = this,
- groupby = (groupbys.length) ? groupbys[0] : [];
- path = path || [];
+ make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix) {
+ var self = this;
+ data_pts.forEach(function (data_pt) {
+ var row_value = (prefix || []).concat(data_pt.attributes.value.slice(0,index));
+ var col_value = data_pt.attributes.value.slice(index);
+
+ var row = self.find_or_create_header(row_headers, row_value, data_pt);
+ var col = self.find_or_create_header(col_headers, col_value, data_pt);
- return this._query_db(groupby, fields, domain, path).then(function (groups) {
- if (groupbys.length > 1) {
- var get_subgroups = $.when.apply(null, _.map(groups, function (group) {
- return self.get_groups(_.rest(groupbys), fields, group.model._domain, path.concat(group.attributes.value)).then(function (subgroups) {
- group.children = subgroups;
- });
- }));
- return get_subgroups.then(function () {
- return groups;
- });
- } else {
- return groups;
+ var cell_value = _.map(self.measures, function (m) {
+ return data_pt.attributes.aggregates[m.field];
+ });
+ self.cells.push({
+ x: Math.min(row.id, col.id),
+ y: Math.max(row.id, col.id),
+ values: cell_value
+ });
+ });
+ },
+
+ make_header: function (values) {
+ return _.extend({
+ children: [],
+ domain: this.domain,
+ expanded: undefined,
+ id: _.uniqueId(),
+ path: [],
+ root: undefined,
+ title: undefined
+ }, values || {});
+ },
+
+ find_or_create_header: function (headers, path, data_pt) {
+ var hdr = _.find(headers, function (header) {
+ return _.isEqual(path, header.path);
+ });
+ if (hdr) {
+ return hdr;
+ }
+ if (!path.length) {
+ hdr = this.make_header({title: _t('Total')});
+ headers.push(hdr);
+ return hdr;
+ }
+ hdr = this.make_header({
+ path:path,
+ domain:data_pt.model._domain,
+ title: _t(_.last(path))
+ });
+ parent = _.find(headers, function (header) {
+ return _.isEqual(header.path, _.initial(path, 1));
+ });
+
+ var previous = parent.children.length ? _.last(parent.children) : parent;
+ headers.splice(headers.indexOf(previous) + 1, 0, hdr);
+ parent.children.push(hdr);
+ return hdr;
+ },
+
+ perform_requests: function (group1, group2, domain) {
+ var self = this,
+ requests = [],
+ row_gbs = _.pluck(this.rows.groupby, 'field'),
+ col_gbs = _.pluck(this.cols.groupby, 'field'),
+ field_list = row_gbs.concat(col_gbs, _.pluck(this.measures, 'field')),
+ fields = field_list.map(function (f) { return self.raw_field(f); });
+
+ group1 = group1 || row_gbs;
+ group2 = group2 || col_gbs;
+
+ var i,j, groupbys;
+ for (i = 0; i < group1.length + 1; i++) {
+ for (j = 0; j < group2.length + 1; j++) {
+ groupbys = group1.slice(0,i).concat(group2.slice(0,j));
+ requests.push(self.get_groups(groupbys, fields, domain || self.domain));
}
- });
+ }
+ return $.when.apply(null, requests);
+ },
- },
+ // set the 'expanded' status of new_headers more or less like root.headers, with root as root
+ set_headers: function(new_headers, root) {
+ if (root.headers) {
+ _.each(root.headers, function (header) {
+ var corresponding_header = _.find(new_headers, function (h) {
+ return _.isEqual(h.path, header.path);
+ });
+ if (corresponding_header && header.expanded) {
+ corresponding_header.expanded = true;
+ _.each(corresponding_header.children, function (c) {
+ c.expanded = false;
+ });
+ }
+ if (corresponding_header && (!header.expanded)) {
+ corresponding_header.expanded = false;
+ }
+ });
+ var updated_headers = _.filter(new_headers, function (header) {
+ return (header.expanded !== undefined);
+ });
+ _.each(updated_headers, function (header) {
+ header.root = root;
+ });
+ root.headers = updated_headers;
+ } else {
+ root.headers = new_headers;
+ _.each(root.headers, function (header) {
+ header.root = root;
+ header.expanded = (header.children.length > 0);
+ });
+ }
+ return new_headers;
+ },
- _query_db: function (groupby, fields, domain, path) {
- var self = this,
- field_ids = _.without(_.pluck(fields, 'field'), '__count'),
- fields = _.map(field_ids, function(f) { return self.raw_field(f); });
-
- return this.model.query(field_ids)
- .filter(domain)
- .group_by(groupby.field)
- .then(function (results) {
- var groups = _.filter(results, function (group) {
- return group.attributes.length > 0;
- });
- return _.map(groups, function (g) { return self.format_group(g, path); });
- });
- },
+ get_groups: function (groupbys, fields, domain) {
+ var self = this;
+ return this.model.query(_.without(fields, '__count'))
+ .filter(domain)
+ .lazy(false)
+ .group_by(groupbys)
+ .then(function (groups) {
+ return groups.map(function (group) {
+ var attrs = group.attributes,
+ grouped_on = attrs.grouped_on instanceof Array
+ ? attrs.grouped_on : [attrs.grouped_on],
+ raw_grouped_on = grouped_on.map(function (f) {
+ return self.raw_field(f);
+ });
+ if (grouped_on.length === 1) { attrs.value = [attrs.value]}
+ attrs.value = _.range(grouped_on.length).map(function (i) {
+ if (attrs.value[i] === false) {
+ return _t('Undefined');
+ } else if (attrs.value[i] instanceof Array) {
+ return attrs.value[i][1];
+ }
+ return attrs.value[i]
+ });
+ attrs.aggregates.__count = group.attributes.length;
+ attrs.grouped_on = raw_grouped_on;
+ return group;
+ });
+ });
+ },
// if field is a fieldname, returns field, if field is field_id:interval, retuns field_id
raw_field: function (field) {
return field.split(':')[0];
},
- // add the path to the group and sanitize the value...
- format_group: function (group, current_path) {
- var attrs = group.attributes,
- value = attrs.value,
- grouped_on = attrs.grouped_on ? this.raw_field(attrs.grouped_on) : false;
-
- if (value === false) {
- group.attributes.value = _t('Undefined');
- } else if (grouped_on && this.fields[grouped_on].type === 'selection') {
- var selection = this.fields[grouped_on].selection,
- value_lookup = _.where(selection, {0:value});
- group.attributes.value = value_lookup ? value_lookup[0][1] : _t('Undefined');
- } else if (value instanceof Array) {
- group.attributes.value = value[1];
- }
-
- group.path = (value !== undefined) ? (current_path || []).concat(group.attributes.value) : [];
- group.attributes.aggregates.__count = group.attributes.length;
-
- return group;
- },
-
- format_data: function (col_data, row_data, cell_data) {
- var self = this,
- dim_row = this.rows.groupby.length,
- dim_col = this.cols.groupby.length,
- col_headers = this.get_ancestors_and_self(this.make_headers(col_data, dim_col)),
- row_headers = this.get_ancestors_and_self(this.make_headers(row_data, dim_row));
-
- this.cells = [];
- _.each(cell_data, function (data, index) {
- self.make_cells(data, index, [], row_headers, col_headers);
- }); // not pretty. make it more functional?
-
- return {col_headers: col_headers, row_headers: row_headers};
- },
-
- make_headers: function (data, depth, parent) {
- var self = this,
- main = this.make_header(data, parent);
-
- if (main.path.length < depth) {
- main.children = _.map(data.children || data, function (data_pt) {
- return self.make_headers (data_pt, depth, main);
- });
- }
- return main;
- },
-
- make_cells: function (data, index, current_path, rows, cols) {
- var self = this;
- _.each(data, function (group) {
- var attr = group.attributes,
- path = attr.grouped_on ? current_path.concat(attr.value) : current_path,
- values = _.map(self.measures, function (measure) { return attr.aggregates[measure.field]; }),
- row = _.find(rows, function (header) { return _.isEqual(header.path, path.slice(index)); }),
- col = _.find(cols, function (header) { return _.isEqual(header.path, path.slice(0, index)); });
-
- self.add_cell(row.id, col.id, values);
- if (group.children) {
- self.make_cells (group.children, index, path, rows, cols);
- }
- });
- },
-
});
})();
From c138b778df3055dad9e1add03deaf5b519e7581f Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 13:47:58 +0200
Subject: [PATCH 09/57] [FIX] correctly filters out empty groups in read_group
results in the data loading code of graph view (addon web_graph)
bzr revid: ged@openerp.com-20140402114758-8qfdz8j76t2p2juo
---
addons/web_graph/static/src/js/pivot_table.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js
index e8a438b3fe5..824b41a6b25 100644
--- a/addons/web_graph/static/src/js/pivot_table.js
+++ b/addons/web_graph/static/src/js/pivot_table.js
@@ -392,7 +392,9 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
.lazy(false)
.group_by(groupbys)
.then(function (groups) {
- return groups.map(function (group) {
+ return groups.filter(function (group) {
+ return group.attributes.length > 0;
+ }).map(function (group) {
var attrs = group.attributes,
grouped_on = attrs.grouped_on instanceof Array
? attrs.grouped_on : [attrs.grouped_on],
From 590fe996ad8bfad6e6c52217604fece0243535c6 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Wed, 2 Apr 2014 14:12:37 +0200
Subject: [PATCH 10/57] [FIX] as render_report is adapted to qweb, no need to
filter in _exec_action
bzr revid: sle@openerp.com-20140402121237-t9tsnm9birhekj0b
---
openerp/tools/test_reports.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py
index 9aa55233a27..c008c20ae29 100644
--- a/openerp/tools/test_reports.py
+++ b/openerp/tools/test_reports.py
@@ -38,7 +38,7 @@ _logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
-def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
+def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, report_type=None):
""" Try to render a report with contents of ids
This function should also check for common pitfalls of reports.
@@ -281,10 +281,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
ids = datas.get('ids')
if 'ids' in datas:
del datas['ids']
- if action.get('report_type') in ['qweb-pdf', 'qweb-html']:
- res = registry['report'].get_html(cr, uid, [], action.get('report_name'), data=datas, context=context)
- else:
- res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
+ res = try_report(cr, uid, 'report.'+action['report_name'], ids, datas, context, our_module=our_module)
return res
else:
raise Exception("Cannot handle action of type %s" % act_model)
From 9d8fa4d7201b5cc48d97b4eefa1610b7f6a63596 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 15:57:04 +0200
Subject: [PATCH 11/57] [FIX] only fills groups with empty groups in read_group
when in lazy mode to prevent weird stuff happening with the
read_group_fill_result algorithm.
bzr revid: ged@openerp.com-20140402135704-3d71gczgg362cezl
---
openerp/osv/orm.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index f9ab9f423ef..9d267816ad5 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2417,9 +2417,12 @@ class BaseModel(object):
result = map(format_result, data)
- for gb in groupby_fields:
- if gb in self._group_by_full:
- result = self._read_group_fill_results(cr, uid, domain, gb, groupby[len(annotated_groupbys):],
+ if lazy and groupby_fields[0] in self._group_by_full:
+ # Right now, read_group only fill results in lazy mode (by default).
+ # If you need to have the empty groups in 'eager' mode, then the
+ # method _read_group_fill_results need to be completely reimplemented
+ # in a sane way
+ result = self._read_group_fill_results(cr, uid, domain, groupby_fields[0], groupby[len(annotated_groupbys):],
aggregated_fields, result, read_group_order=order,
context=context)
return result
From 729cd2ce023d8919aa1b250a4b51bf416cc12117 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Wed, 2 Apr 2014 17:08:17 +0200
Subject: [PATCH 12/57] [FIX] correct the expand functionality to avoid
creating rows/cols in the other dimension of an unfolding action (addon
web_graph)
bzr revid: ged@openerp.com-20140402150817-5s8drvhbznxq0hh9
---
addons/web_graph/static/src/js/pivot_table.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js
index 824b41a6b25..9231765c485 100644
--- a/addons/web_graph/static/src/js/pivot_table.js
+++ b/addons/web_graph/static/src/js/pivot_table.js
@@ -223,7 +223,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
data = data.slice(other_gbs.length + 1, data.length);
_.each(data, function (data_pt) {
self.make_headers_and_cell(
- data_pt, header.root.headers, other_root.headers, 1, header.path);
+ data_pt, header.root.headers, other_root.headers, 1, header.path, true);
});
header.expanded = true;
header.children.forEach(function (child) {
@@ -271,12 +271,15 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
});
},
- make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix) {
+ make_headers_and_cell: function (data_pts, row_headers, col_headers, index, prefix, expand) {
var self = this;
data_pts.forEach(function (data_pt) {
var row_value = (prefix || []).concat(data_pt.attributes.value.slice(0,index));
var col_value = data_pt.attributes.value.slice(index);
+ if (expand && !_.find(col_headers, function (hdr) {return _.isEqual(col_value, hdr.path);})) {
+ return;
+ }
var row = self.find_or_create_header(row_headers, row_value, data_pt);
var col = self.find_or_create_header(col_headers, col_value, data_pt);
From 8bf8e8a01c96106b59793c0baef6875ee1ceee17 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Wed, 2 Apr 2014 18:13:49 +0200
Subject: [PATCH 13/57] [FIX] website ir_qweb: do not crash if request is not
bound when rendering a template
bzr revid: sle@openerp.com-20140402161349-ecm6pit20j44taf1
---
addons/website/models/ir_ui_view.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index 67781cc02a0..c9fadade6ed 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -123,7 +123,7 @@ class view(osv.osv):
return arch
def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None):
- if getattr(request, 'website_enabled', False):
+ if request and getattr(request, 'website_enabled', False):
engine='website.qweb'
if isinstance(id_or_xml_id, list):
From 2c90fad7ac735a71b65c905ad6489906a33a3575 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Wed, 2 Apr 2014 18:23:44 +0200
Subject: [PATCH 14/57] [REF][IMP] report module: merge the four report's
routes into one; extra report arguments are passed json encoded (therefore
removed the _eval_params method); added an abstract_report model to wrap
old-style report without touching them; Removed formatLang method from report
as it is embeded in the old-style report localcontext; moved the
save_in_attachment logic in a method for readability; adapted the action
manager to encode data and context of action if needed; fixed the post
install test to test the generic report
bzr revid: sle@openerp.com-20140402162344-3lrako0jepmhasvl
---
addons/report/controllers/main.py | 115 +++-----
addons/report/models/__init__.py | 1 +
addons/report/models/abstract_report.py | 60 ++++
addons/report/models/report.py | 268 +++++-------------
.../report/static/src/js/qwebactionmanager.js | 52 ++--
addons/report/tests/test_reports.py | 50 ++--
6 files changed, 227 insertions(+), 319 deletions(-)
create mode 100644 addons/report/models/abstract_report.py
diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py
index f8435ba8245..d3a683cccdc 100644
--- a/addons/report/controllers/main.py
+++ b/addons/report/controllers/main.py
@@ -22,48 +22,43 @@
from openerp.addons.web.http import Controller, route, request
import simplejson
-import urlparse
-from werkzeug import exceptions
+from werkzeug import exceptions, url_decode
+from werkzeug.test import Client
+from werkzeug.wrappers import BaseResponse
+from werkzeug.datastructures import Headers
from reportlab.graphics.barcode import createBarcodeDrawing
class ReportController(Controller):
#------------------------------------------------------
- # Generic reports controller
+ # Report controllers
#------------------------------------------------------
- @route('/report//', type='http', auth='user', website=True, multilang=True)
- def report_html(self, reportname, docids):
- cr, uid, context = request.cr, request.uid, request.context
- docids = self._eval_params(docids)
- return request.registry['report'].get_html(cr, uid, docids, reportname, context=context)
-
- @route('/report/pdf/report//', type='http', auth="user", website=True)
- def report_pdf(self, reportname, docids):
- cr, uid, context = request.cr, request.uid, request.context
- docids = self._eval_params(docids)
- pdf = request.registry['report'].get_pdf(cr, uid, docids, reportname, context=context)
- pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
- return request.make_response(pdf, headers=pdfhttpheaders)
-
- #------------------------------------------------------
- # Particular reports controller
- #------------------------------------------------------
- @route('/report/', type='http', auth='user', website=True, multilang=True)
- def report_html_particular(self, reportname, **data):
- cr, uid, context = request.cr, request.uid, request.context
+ @route([
+ '/report//',
+ '/report///',
+ ], type='http', auth='user', website=True, multilang=True)
+ def report_routes(self, reportname, docids=None, converter=None, **data):
report_obj = request.registry['report']
- data = self._eval_params(data) # Sanitizing
- return report_obj.get_html(cr, uid, [], reportname, data=data, context=context)
-
- @route('/report/pdf/report/', type='http', auth='user', website=True, multilang=True)
- def report_pdf_particular(self, reportname, **data):
cr, uid, context = request.cr, request.uid, request.context
- report_obj = request.registry['report']
- data = self._eval_params(data) # Sanitizing
- pdf = report_obj.get_pdf(cr, uid, [], reportname, data=data, context=context)
- pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
- return request.make_response(pdf, headers=pdfhttpheaders)
+
+ if docids:
+ docids = [int(i) for i in docids.split(',')]
+ options_data = None
+ if data.get('options'):
+ options_data = simplejson.loads(data['options'])
+ if data.get('context'):
+ context.update(simplejson.loads(data['context']))
+
+ if converter == 'html':
+ html = report_obj.get_html(cr, uid, docids, reportname, data=options_data, context=context)
+ return request.make_response(html)
+ elif converter == 'pdf':
+ pdf = report_obj.get_pdf(cr, uid, docids, reportname, data=options_data, context=context)
+ pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
+ return request.make_response(pdf, headers=pdfhttpheaders)
+ else:
+ raise exceptions.HTTPException(description='Converter %s not implemented.' % converter)
#------------------------------------------------------
# Misc. route utils
@@ -94,7 +89,7 @@ class ReportController(Controller):
@route(['/report/download'], type='http', auth="user", website=True)
def report_download(self, data, token):
"""This function is used by 'qwebactionmanager.js' in order to trigger the download of
- a pdf report.
+ a pdf/controller report.
:param data: a javascript array JSON.stringified containg report internal url ([0]) and
type [1]
@@ -102,26 +97,26 @@ class ReportController(Controller):
"""
requestcontent = simplejson.loads(data)
url, type = requestcontent[0], requestcontent[1]
- if type == 'qweb-pdf':
- reportname = url.split('/report/pdf/report/')[1].split('?')[0].split('/')[0]
- if '?' not in url:
+ if type == 'qweb-pdf':
+ reportname = url.split('/report/pdf/')[1].split('?')[0]
+
+ docids = None
+ if '/' in reportname:
+ reportname, docids = reportname.split('/')
+
+ if docids:
# Generic report:
- docids = url.split('/')[-1]
- response = self.report_pdf(reportname, docids)
+ response = self.report_routes(reportname, docids=docids, converter='pdf')
else:
# Particular report:
- querystring = url.split('?')[1]
- querystring = dict(urlparse.parse_qsl(querystring))
- response = self.report_pdf_particular(reportname, **querystring)
+ data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON
+ response = self.report_routes(reportname, converter='pdf', **dict(data))
response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)
response.set_cookie('fileToken', token)
return response
elif type =='controller':
- from werkzeug.test import Client
- from werkzeug.wrappers import BaseResponse
- from werkzeug.datastructures import Headers
reqheaders = Headers(request.httprequest.headers)
response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
response.set_cookie('fileToken', token)
@@ -132,33 +127,3 @@ class ReportController(Controller):
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
def check_wkhtmltopdf(self):
return request.registry['report']._check_wkhtmltopdf()
-
- def _eval_params(self, param):
- """Parse a dict generated by the webclient (javascript) into a python dict.
- """
- if isinstance(param, dict):
- for key, value in param.iteritems():
- if value.lower() == 'false':
- param[key] = False
- elif value.lower() == 'true':
- param[key] = True
- elif ',' in value:
- try:
- param[key] = [int(i) for i in value.split(',')]
- except ValueError:
- param[key] = value.split(',')
- if len(param[key]) == 1:
- param[key] = value
- else:
- try:
- param[key] = int(value)
- except (ValueError, TypeError):
- continue
- else:
- if isinstance(param, (str, unicode)):
- param = [int(i) for i in param.split(',')]
- if isinstance(param, list):
- param = list(set(param))
- if isinstance(param, int):
- param = [param]
- return param
diff --git a/addons/report/models/__init__.py b/addons/report/models/__init__.py
index e048e10eb91..d21f03e5bcb 100644
--- a/addons/report/models/__init__.py
+++ b/addons/report/models/__init__.py
@@ -1,2 +1,3 @@
import report
import report_paperformat
+import abstract_report
diff --git a/addons/report/models/abstract_report.py b/addons/report/models/abstract_report.py
new file mode 100644
index 00000000000..c84ce1cac50
--- /dev/null
+++ b/addons/report/models/abstract_report.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2014-Today OpenERP SA ().
+#
+# 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 openerp.osv import osv
+
+
+class AbstractReport(osv.AbstractModel):
+ """Model used to embed old style reports"""
+ _name = 'report.abstract_report'
+ _template = None
+ _wrapped_report_class = None
+
+ def render_html(self, cr, uid, ids, data=None, context=None):
+ if context is None:
+ context = {}
+
+ # If the key 'landscape' is present in data['form'], passing it into the context
+ if data and data.get('form', {}).get('landscape'):
+ context['landscape'] = True
+
+ if context and context.get('active_ids'):
+ # Browse the selected objects via their reference in context
+ model = context.get('active_model') or context.get('model')
+ objects_model = self.pool[model]
+ objects = objects_model.browse(cr, uid, context['active_ids'], context=context)
+ else:
+ # If no context is set (for instance, during test execution), build one
+ model = self.pool['report']._get_report_from_name(cr, uid, self._template).model
+ objects_model = self.pool[model]
+ objects = objects_model.browse(cr, uid, ids, context=context)
+ context['active_model'] = model
+ context['active_ids'] = ids
+
+ # Generate the old style report
+ wrapped_report = self._wrapped_report_class(cr, uid, '', context=context)
+ wrapped_report.set_context(objects, data, ids)
+
+ # Rendering self._template with the wrapped report instance localcontext as
+ # rendering environment
+ docargs = wrapped_report.localcontext
+ docargs['docs'] = docargs.get('objects')
+ return self.pool['report'].render(cr, uid, [], self._template, docargs, context=context)
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index b93bbe09f89..992842ffacd 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -20,9 +20,8 @@
##############################################################################
from openerp.osv import osv
+from openerp.tools import config
from openerp.tools.translate import _
-from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, config
-from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field
import os
import time
@@ -34,8 +33,6 @@ import tempfile
import lxml.html
import cStringIO
import subprocess
-from datetime import datetime
-from functools import partial
from distutils.version import LooseVersion
try:
from pyPdf import PdfFileWriter, PdfFileReader
@@ -46,7 +43,7 @@ except ImportError:
_logger = logging.getLogger(__name__)
-"""Check the presence of wkhtmltopdf and return its version."""
+"""Check the presence of wkhtmltopdf and return its version at OpnerERP start-up."""
wkhtmltopdf_state = 'install'
try:
process = subprocess.Popen(
@@ -70,106 +67,26 @@ class Report(osv.Model):
public_user = None
+ MINIMAL_HTML_PAGE = """
+
+
+
+
+
+
+
+
+
+ {subst}
+
+
+ {body}
+
+"""
+
#--------------------------------------------------------------------------
# Extension of ir_ui_view.render with arguments frequently used in reports
#--------------------------------------------------------------------------
-
- def _get_digits(self, cr=None, uid=None, obj=None, f=None, dp=None):
- d = DEFAULT_DIGITS = 2
- if dp:
- decimal_precision_obj = self.pool['decimal.precision']
- ids = decimal_precision_obj.search(cr, uid, [('name', '=', dp)])
- if ids:
- d = decimal_precision_obj.browse(cr, uid, ids)[0].digits
- elif obj and f:
- res_digits = getattr(obj._columns[f], 'digits', lambda x: ((16, DEFAULT_DIGITS)))
- if isinstance(res_digits, tuple):
- d = res_digits[1]
- else:
- d = res_digits(cr)[1]
- elif (hasattr(obj, '_field') and
- isinstance(obj._field, (float_field, function_field)) and
- obj._field.digits):
- d = obj._field.digits[1] or DEFAULT_DIGITS
- return d
-
- def _get_lang_dict(self, cr, uid):
- pool_lang = self.pool['res.lang']
- lang = self.localcontext.get('lang', 'en_US') or 'en_US'
- lang_ids = pool_lang.search(cr, uid, [('code', '=', lang)])[0]
- lang_obj = pool_lang.browse(cr, uid, lang_ids)
- lang_dict = {
- 'lang_obj': lang_obj,
- 'date_format': lang_obj.date_format,
- 'time_format': lang_obj.time_format
- }
- self.lang_dict.update(lang_dict)
- self.default_lang[lang] = self.lang_dict.copy()
- return True
-
- def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False, currency_obj=False, cr=None, uid=None):
- """
- Assuming 'Account' decimal.precision=3:
- formatLang(value) -> digits=2 (default)
- formatLang(value, digits=4) -> digits=4
- formatLang(value, dp='Account') -> digits=3
- formatLang(value, digits=5, dp='Account') -> digits=5
- """
- def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
- return len((datetime.now()).strftime(date_format))
-
- # In case we use formatLang on the model (and not in the rendering environment).
- if not hasattr(self, 'land_ditct'):
- self.localcontext = {}
- self.lang_dict = {}
- self.default_lang = {}
- self._get_lang_dict(cr, uid)
- self.lang_dict_called = True
-
- if digits is None:
- if dp:
- digits = self._get_digits(cr, uid, dp=dp)
- else:
- digits = self._get_digits(cr, uid, value)
-
- if isinstance(value, (str, unicode)) and not value:
- return ''
-
- if not self.lang_dict_called:
- self._get_lang_dict(cr, uid)
- self.lang_dict_called = True
-
- if date or date_time:
- if not str(value):
- return ''
-
- date_format = self.lang_dict['date_format']
- parse_format = DEFAULT_SERVER_DATE_FORMAT
- if date_time:
- value = value.split('.')[0]
- date_format = date_format + " " + self.lang_dict['time_format']
- parse_format = DEFAULT_SERVER_DATETIME_FORMAT
- if isinstance(value, basestring):
- # FIXME: the trimming is probably unreliable if format includes day/month names
- # and those would need to be translated anyway.
- date = datetime.strptime(value[:get_date_length(parse_format)], parse_format)
- elif isinstance(value, time.struct_time):
- date = datetime(*value[:6])
- else:
- date = datetime(*value.timetuple()[:6])
- if date_time:
- # Convert datetime values to the expected client/context timezone
- date = datetime_field.context_timestamp(cr, uid, timestamp=date, context=self.localcontext)
- return date.strftime(date_format.encode('utf-8'))
-
- res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
- if currency_obj:
- if currency_obj.position == 'after':
- res = '%s %s' % (res, currency_obj.symbol)
- elif currency_obj and currency_obj.position == 'before':
- res = '%s %s' % (currency_obj.symbol, res)
- return res
-
def render(self, cr, uid, ids, template, values=None, context=None):
"""Allow to render a QWeb template python-side. This function returns the 'ir.ui.view'
render but embellish it with some variables/methods used in reports.
@@ -183,15 +100,6 @@ class Report(osv.Model):
if context is None:
context = {}
- self.lang_dict = self.default_lang = {}
- self.lang_dict_called = False
- self.localcontext = {
- 'lang': context.get('lang'),
- 'tz': context.get('tz'),
- 'uid': context.get('uid'),
- }
- self._get_lang_dict(cr, uid)
-
view_obj = self.pool['ir.ui.view']
def render_doc(doc_id, model, template):
@@ -217,22 +125,20 @@ class Report(osv.Model):
qcontext['o'] = self.pool[model].browse(cr, uid, doc_id, context=ctx)
return view_obj.render(cr, uid, template, qcontext, context=ctx)
+ user = self.pool['res.users'].browse(cr, uid, uid)
values.update({
'time': time,
- 'formatLang': partial(self.formatLang, cr=cr, uid=uid),
- 'get_digits': partial(self._get_digits, cr=cr, uid=uid),
'render_doc': render_doc,
'editable': True, # Will active inherit_branding
- 'res_company': self.pool['res.users'].browse(cr, uid, uid).company_id,
+ 'user': user,
+ 'res_company': user.company_id,
'website': False, # Will be overidden by ir.ui.view if the request has website enabled
})
-
return view_obj.render(cr, uid, template, values, context=context)
#--------------------------------------------------------------------------
- # Main reports methods
+ # Main report methods
#--------------------------------------------------------------------------
-
def get_html(self, cr, uid, ids, report_name, data=None, context=None):
"""This method generates and returns html version of a report.
"""
@@ -241,7 +147,7 @@ class Report(osv.Model):
try:
report_model_name = 'report.%s' % report_name
particularreport_obj = self.pool[report_model_name]
- return particularreport_obj.render_html(cr, uid, ids, data={'form': data}, context=context)
+ return particularreport_obj.render_html(cr, uid, ids, data=data, context=context)
except KeyError:
report = self._get_report_from_name(cr, uid, report_name)
report_obj = self.pool[report.model]
@@ -262,41 +168,12 @@ class Report(osv.Model):
if html is None:
html = self.get_html(cr, uid, ids, report_name, data=data, context=context)
- html = html.decode('utf-8')
+ html = html.decode('utf-8') # Ensure the current document is utf-8 encoded.
# Get the ir.actions.report.xml record we are working on.
report = self._get_report_from_name(cr, uid, report_name)
-
- # Check attachment_use field. If set to true and an existing pdf is already saved, load
- # this one now. Else, mark save it.
- save_in_attachment = {}
-
- if report.attachment_use is True:
- save_in_attachment['model'] = report.model
- save_in_attachment['loaded_documents'] = {}
-
- for record_id in ids:
- obj = self.pool[report.model].browse(cr, uid, record_id)
- filename = eval(report.attachment, {'object': obj, 'time': time})
-
- if filename is False: # May be false if, for instance, the record is in draft state
- continue
- else:
- alreadyindb = [('datas_fname', '=', filename),
- ('res_model', '=', report.model),
- ('res_id', '=', record_id)]
-
- attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
- if attach_ids:
- # Add the loaded pdf in the loaded_documents list
- pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
- pdf = base64.decodestring(pdf)
- save_in_attachment['loaded_documents'][record_id] = pdf
- _logger.info('The PDF document %s was loaded from the database' % filename)
- else:
- # Mark current document to be saved
- save_in_attachment[id] = filename
-
+ # Check if we have to save the report or if we have to get one from the db.
+ save_in_attachment = self._check_attachment_use(cr, uid, ids, report)
# Get the paperformat associated to the report, otherwise fallback on the company one.
if not report.paperformat_id:
user = self.pool['res.users'].browse(cr, uid, uid)
@@ -305,34 +182,15 @@ class Report(osv.Model):
paperformat = report.paperformat_id
# Preparing the minimal html pages
- #subst = self._get_url_content('/report/static/src/js/subst.js')[0] # Used in age numbering
subst = " "
css = '' # Will contain local css
-
headerhtml = []
contenthtml = []
footerhtml = []
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
- minimalhtml = """
-
-
-
-
-
-
-
-
-
- {subst}
-
-
- {body}
-
-"""
-
- # The retrieved html report must be simplified. We convert it into a xml tree
- # via lxml in order to extract headers, footers and content.
+ # The received html report must be simplified. We convert it in a xml tree
+ # in order to extract headers, bodies and footers.
try:
root = lxml.html.fromstring(html)
@@ -341,12 +199,12 @@ class Report(osv.Model):
for node in root.xpath("//div[@class='header']"):
body = lxml.html.tostring(node)
- header = minimalhtml.format(css=css, subst=subst, body=body, base_url=base_url)
+ header = self.MINIMAL_HTML_PAGE.format(css=css, subst=subst, body=body, base_url=base_url)
headerhtml.append(header)
for node in root.xpath("//div[@class='footer']"):
body = lxml.html.tostring(node)
- footer = minimalhtml.format(css=css, subst=subst, body=body, base_url=base_url)
+ footer = self.MINIMAL_HTML_PAGE.format(css=css, subst=subst, body=body, base_url=base_url)
footerhtml.append(footer)
for node in root.xpath("//div[@class='page']"):
@@ -363,7 +221,7 @@ class Report(osv.Model):
reportid = False
body = lxml.html.tostring(node)
- reportcontent = minimalhtml.format(css=css, subst='', body=body, base_url=base_url)
+ reportcontent = self.MINIMAL_HTML_PAGE.format(css=css, subst='', body=body, base_url=base_url)
contenthtml.append(tuple([reportid, reportcontent]))
except lxml.etree.XMLSyntaxError:
@@ -390,37 +248,60 @@ class Report(osv.Model):
:param report_name: Name of the template to generate an action for
"""
- # TODO: return the action for the ids passed in args
if context is None:
context = {}
- if data is None:
- data = {}
-
- report_obj = self.pool.get('ir.actions.report.xml')
+ report_obj = self.pool['ir.actions.report.xml']
idreport = report_obj.search(cr, uid, [('report_name', '=', report_name)], context=context)
-
try:
report = report_obj.browse(cr, uid, idreport[0], context=context)
except IndexError:
- raise osv.except_osv(_('Bad Report'),
- _('This report is not loaded into the database.'))
+ raise osv.except_osv(_('Bad Report'), _('This report is not loaded into the database.'))
action = {
+ 'context': context,
+ 'data': data,
'type': 'ir.actions.report.xml',
'report_name': report.report_name,
'report_type': report.report_type,
'report_file': report.report_file,
}
-
- if data:
- action['datas'] = data
-
return action
#--------------------------------------------------------------------------
# Report generation helpers
#--------------------------------------------------------------------------
+ def _check_attachment_use(self, cr, uid, ids, report):
+ """ Check attachment_use field. If set to true and an existing pdf is already saved, load
+ this one now. Else, mark save it.
+ """
+ save_in_attachment = {}
+ if report.attachment_use is True:
+ save_in_attachment['model'] = report.model
+ save_in_attachment['loaded_documents'] = {}
+
+ for record_id in ids:
+ obj = self.pool[report.model].browse(cr, uid, record_id)
+ filename = eval(report.attachment, {'object': obj, 'time': time})
+
+ if filename is False: # May be false if, for instance, the record is in draft state
+ continue
+ else:
+ alreadyindb = [('datas_fname', '=', filename),
+ ('res_model', '=', report.model),
+ ('res_id', '=', record_id)]
+
+ attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
+ if attach_ids:
+ # Add the loaded pdf in the loaded_documents list
+ pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
+ pdf = base64.decodestring(pdf)
+ save_in_attachment['loaded_documents'][record_id] = pdf
+ _logger.info('The PDF document %s was loaded from the database' % filename)
+ else:
+ # Mark current document to be saved
+ save_in_attachment[record_id] = filename
+ return save_in_attachment
def _check_wkhtmltopdf(self):
return wkhtmltopdf_state
@@ -445,7 +326,8 @@ class Report(osv.Model):
# Passing the cookie to wkhtmltopdf in order to resolve URL.
try:
from openerp.addons.web.http import request
- command_args.extend(['--cookie', 'session_id', request.session.sid])
+ if request:
+ command_args.extend(['--cookie', 'session_id', request.session.sid])
except AttributeError:
pass
@@ -453,6 +335,8 @@ class Report(osv.Model):
if paperformat:
command_args.extend(self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args))
+ command_args.extend(['--load-error-handling', 'ignore'])
+
if landscape and '--orientation' in command_args:
command_args_copy = list(command_args)
for index, elem in enumerate(command_args_copy):
@@ -472,7 +356,7 @@ class Report(osv.Model):
# Directly load the document if we have it
if save_in_attachment and save_in_attachment['loaded_documents'].get(reporthtml[0]):
pdfreport.write(save_in_attachment['loaded_documents'].get(reporthtml[0]))
- pdfreport.flush()
+ pdfreport.seek(0)
pdfdocuments.append(pdfreport)
continue
@@ -481,7 +365,7 @@ class Report(osv.Model):
head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.',
dir=tmp_dir, mode='w+')
head_file.write(headers[index])
- head_file.flush()
+ head_file.seek(0)
command_arg_local.extend(['--header-html', head_file.name])
# Footer stuff
@@ -489,14 +373,14 @@ class Report(osv.Model):
foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.',
dir=tmp_dir, mode='w+')
foot_file.write(footers[index])
- foot_file.flush()
+ foot_file.seek(0)
command_arg_local.extend(['--footer-html', foot_file.name])
# Body stuff
content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.',
dir=tmp_dir, mode='w+')
content_file.write(reporthtml[1])
- content_file.flush()
+ content_file.seek(0)
try:
# If the server is running with only one worker, ask to create a secund to be able
@@ -533,7 +417,7 @@ class Report(osv.Model):
_logger.info('The PDF document %s is now saved in the '
'database' % attachment['name'])
- pdfreport.flush()
+ pdfreport.seek(0)
pdfdocuments.append(pdfreport)
if headers:
diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js
index b75003942d2..aa98b2c9c52 100644
--- a/addons/report/static/src/js/qwebactionmanager.js
+++ b/addons/report/static/src/js/qwebactionmanager.js
@@ -6,8 +6,6 @@ openerp.report = function(instance) {
var self = this;
instance.web.blockUI();
action = _.clone(action);
- var eval_contexts = ([instance.session.user_context] || []).concat([action.context]);
- action.context = instance.web.pyeval.eval('contexts',eval_contexts);
_t = instance.web._t;
// QWeb reports
@@ -15,43 +13,33 @@ openerp.report = function(instance) {
var report_url = '';
switch (action.report_type) {
case 'qweb-html':
- report_url = '/report/' + action.report_name;
+ report_url = '/report/html/' + action.report_name;
break;
case 'qweb-pdf':
- report_url = '/report/pdf/report/' + action.report_name;
+ report_url = '/report/pdf/' + action.report_name;
break;
case 'controller':
report_url = action.report_file;
break;
default:
- report_url = '/report/' + action.report_name;
+ report_url = '/report/html/' + action.report_name;
break;
}
- // single/multiple id(s): no query string
- // wizard: query string of action.datas.form
- if (!('datas' in action)) {
+ // generic report: no query string
+ // particular: query string of action.data.form and context
+ if (!('data' in action) || !(action.data)) {
if ('active_ids' in action.context) {
report_url += "/" + action.context.active_ids.join(',');
}
} else {
- _.each(action.datas.form, function(value, key) {
- // will be erased when all wizards are rewritten
- if (key.substring(0, 12) === 'used_context') {
- delete action.datas.form[key];
- }
-
- if ($.type(value) === 'array') {
- action.datas.form[key] = value.join(',');
- }
- });
- report_url += "?" + $.param(action.datas.form);
+ report_url += "?options=" + encodeURI(JSON.stringify(action.data));
+ report_url += "&context=" + encodeURI(JSON.stringify(action.context));
}
+
if (action.report_type == 'qweb-html') {
- // Open the html report in a popup
window.open(report_url, '_blank', 'height=900,width=1280');
instance.web.unblockUI();
- return;
} else {
// Trigger the download of the pdf/controller report
var c = openerp.webclient.crashmanager;
@@ -68,6 +56,7 @@ openerp.report = function(instance) {
wkhtmltopdf.org'), true);
window.open(report_url.substring(12), '_blank', 'height=768,width=1024');
instance.web.unblockUI();
+ return;
} else {
if (presence == 'upgrade') {
self.do_notify(_t('Report'), _t('You should upgrade your version of\
@@ -75,22 +64,15 @@ openerp.report = function(instance) {
support for table-breaking between pages.wkhtmltopdf.org '), true);
}
- self.session.get_file({
- url: '/report/download',
- data: {data: JSON.stringify(response)},
- complete: openerp.web.unblockUI,
- error: c.rpc_error.bind(c)
- });
}
});
- } else {
- self.session.get_file({
- url: '/report/download',
- data: {data: JSON.stringify(response)},
- complete: openerp.web.unblockUI,
- error: c.rpc_error.bind(c)
- });
- }
+ }
+ self.session.get_file({
+ url: '/report/download',
+ data: {data: JSON.stringify(response)},
+ complete: openerp.web.unblockUI,
+ error: c.rpc_error.bind(c)
+ });
}
} else {
return self._super(action, options);
diff --git a/addons/report/tests/test_reports.py b/addons/report/tests/test_reports.py
index dda14442709..b1853489573 100644
--- a/addons/report/tests/test_reports.py
+++ b/addons/report/tests/test_reports.py
@@ -1,5 +1,23 @@
# -*- coding: utf-8 -*-
-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2014-Today OpenERP SA ().
+#
+# 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 logging
import openerp
@@ -11,26 +29,24 @@ _logger = logging.getLogger(__name__)
@openerp.tests.common.post_install(True)
class TestReports(openerp.tests.TransactionCase):
def test_reports(self):
- return # commented out until post_install tests are working
-
registry, cr, uid = self.registry, self.cr, self.uid
r_model = registry('ir.actions.report.xml')
domain = [('report_type', 'like', 'qweb')]
for r in r_model.browse(cr, uid, r_model.search(cr, uid, domain)):
report_model = 'report.%s' % r.report_name
- particular_model = registry('ir.model').search(cr, uid, [('model', '=', report_model)])
-
+ try:
+ registry(report_model)
+ except KeyError:
# Only test the generic reports here
- if particular_model:
+ _logger.info("testing report %s", r.report_name)
+ report_model = registry(r.model)
+ report_model_ids = report_model.search(cr, uid, [], limit=10)
+ if not report_model_ids:
+ _logger.info("no record found skipping report %s", r.report_name)
+ if not r.multi:
+ report_model_ids = report_model_ids[:1]
+
+ # Test report generation
+ registry('report').get_html(cr, uid, report_model_ids, r.report_name)
+ else:
continue
-
- _logger.info("testing report %s", r.report_name)
- report_model = registry(r.model)
- report_model_ids = report_model.search(cr, uid, [], limit=10)
- if not report_model_ids:
- _logger.info("no record found skipping report %s", r.report_name)
- if not r.multi:
- report_model_ids = report_model_ids[:1]
-
- # Test report generation
- registry('report').get_html(cr, uid, report_model_ids, r.report_name)
From 106d06ce5d14f5d3cad573d95ad8ed8dc19eb5b6 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Wed, 2 Apr 2014 18:40:53 +0200
Subject: [PATCH 15/57] [IMP] account* reports: removed unused
class/report/commented code/test, added the abstract_report wrapper on all
old style report classes + some fixes on views and wizards in order to use
these classes to render the qweb reports
bzr revid: sle@openerp.com-20140402164053-gry12scy8zca68lv
---
.../account/project/report/account_journal.py | 49 -------
.../project/report/analytic_balance.py | 15 +-
.../project/report/analytic_journal.py | 10 +-
addons/account/project/report/cost_ledger.py | 10 +-
.../report/inverted_analytic_balance.py | 9 +-
.../project/report/quantity_cost_ledger.py | 13 +-
.../project/views/report_analyticbalance.xml | 20 +--
.../views/report_analyticcostledger.xml | 20 +--
.../report_analyticcostledgerquantity.xml | 12 +-
.../project/views/report_analyticjournal.xml | 16 +--
.../views/report_invertedanalyticbalance.xml | 12 +-
...analytic_cost_ledger_for_journal_report.py | 1 -
...ccount_analytic_inverted_balance_report.py | 2 -
.../report/account_aged_partner_balance.py | 9 +-
addons/account/report/account_balance.py | 14 +-
.../account/report/account_central_journal.py | 10 +-
.../report/account_financial_report.py | 9 +-
.../account/report/account_general_journal.py | 11 +-
.../account/report/account_general_ledger.py | 10 +-
addons/account/report/account_journal.py | 19 ++-
.../account/report/account_partner_balance.py | 10 +-
.../account/report/account_partner_ledger.py | 23 ++--
.../account/report/account_print_overdue.py | 32 ++++-
addons/account/report/report_vat.py | 129 ++++++++----------
addons/account/test/account_report.yml | 9 +-
.../views/report_agedpartnerbalance.xml | 10 +-
addons/account/views/report_overdue.xml | 1 +
addons/account/views/report_vat.xml | 2 +-
.../wizard/account_financial_report.py | 2 -
.../wizard/account_report_partner_ledger.py | 2 +
addons/account_analytic_plans/__openerp__.py | 2 +-
.../report/crossovered_analytic.py | 11 +-
.../test/acount_analytic_plans_report.yml | 2 +-
.../views/report_crossoveredanalyticplans.xml | 4 +-
.../report/bank_statement_balance_report.py | 19 ++-
.../report/analytic_account_budget_report.py | 11 +-
addons/account_budget/report/budget_report.py | 8 +-
.../report/crossovered_budget_report.py | 14 +-
.../test/account_budget_report.yml | 25 +---
.../report/check_print.py | 29 ++--
addons/account_followup/account_followup.py | 7 +-
.../report/account_followup_print.py | 12 +-
.../wizard/account_followup_print.py | 8 +-
.../account_payment/report/payment_order.py | 10 +-
.../test/account_payment_report.yml | 2 +-
.../report/account_test_report.py | 11 +-
addons/account_voucher/__openerp__.py | 2 -
.../account_voucher_report.xml | 23 ----
addons/account_voucher/report/__init__.py | 2 -
.../account_voucher/report/account_voucher.py | 75 ----------
.../report/account_voucher_print.py | 96 -------------
.../test/account_voucher_report.yml | 27 ----
addons/lunch/report/order.py | 29 ++--
addons/mrp/report/bom_structure.py | 29 ++--
.../test/report_intrastat_report.yml | 2 +-
55 files changed, 379 insertions(+), 572 deletions(-)
delete mode 100644 addons/account/project/report/account_journal.py
delete mode 100644 addons/account_voucher/account_voucher_report.xml
delete mode 100644 addons/account_voucher/report/account_voucher.py
delete mode 100644 addons/account_voucher/report/account_voucher_print.py
delete mode 100644 addons/account_voucher/test/account_voucher_report.yml
diff --git a/addons/account/project/report/account_journal.py b/addons/account/project/report/account_journal.py
deleted file mode 100644
index 50f98fd0ee0..00000000000
--- a/addons/account/project/report/account_journal.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-
-
-import time
-from openerp.report import report_sxw
-
-#
-# Use period and Journal for selection or resources
-#
-class journal_print(report_sxw.rml_parse):
- def lines(self, journal_id, *args):
- self.cr.execute('select id from account_analytic_line where journal_id=%s order by date,id', (journal_id,))
- ids = map(lambda x: x[0], self.cr.fetchall())
- res = self.pool.get('account.analytic.line').browse(self.cr, self.uid, ids)
- return res
- def _sum_lines(self, journal_id):
- self.cr.execute('select sum(amount) from account_analytic_line where journal_id=%s', (journal_id,))
- return self.cr.fetchone()[0] or 0.0
- def __init__(self, cr, uid, name, context):
- super(journal_print, self).__init__(cr, uid, name, context=context)
- self.localcontext = {
- 'time': time,
- 'lines': self.lines,
- 'sum_lines': self._sum_lines,
- }
-report_sxw.report_sxw('report.account.analytic.journal.print', 'account.analytic.journal', 'addons/account/project/report/analytic_journal.rml',parser=journal_print)
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/report/analytic_balance.py b/addons/account/project/report/analytic_balance.py
index 2aa9f2c549e..7c333b84c45 100644
--- a/addons/account/project/report/analytic_balance.py
+++ b/addons/account/project/report/analytic_balance.py
@@ -20,7 +20,7 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
@@ -56,7 +56,6 @@ class account_analytic_balance(report_sxw.rml_parse):
self.get_children(data['child_ids'])
return True
-
def _get_objects(self, empty_acc):
if self.read_data:
return self.read_data
@@ -143,18 +142,16 @@ class account_analytic_balance(report_sxw.rml_parse):
WHERE account_id IN %s AND date>=%s AND date<=%s",query_params)
return self.cr.fetchone()[0] or 0.0
-
-
def _sum_balance(self, accounts, date1, date2):
debit = self._sum_all(accounts, date1, date2, 'debit') or 0.0
credit = self._sum_all(accounts, date1, date2, 'credit') or 0.0
return (debit-credit)
-report_sxw.report_sxw('report.account.analytic.account.balance',
- 'account.analytic.account', 'addons/account/project/report/analytic_balance.rml',
- parser=account_analytic_balance, header="internal")
-
+class report_analyticbalance(osv.AbstractModel):
+ _name = 'report.account.report_analyticbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_analyticbalance'
+ _wrapped_report_class = account_analytic_balance
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/report/analytic_journal.py b/addons/account/project/report/analytic_journal.py
index 1ca1ffb3ca4..c59efb057d7 100644
--- a/addons/account/project/report/analytic_journal.py
+++ b/addons/account/project/report/analytic_journal.py
@@ -20,9 +20,10 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
#
# Use period and Journal for selection or resources
#
@@ -57,8 +58,11 @@ class account_analytic_journal(report_sxw.rml_parse):
res = self.cr.dictfetchone()
return res['sum'] or 0
-report_sxw.report_sxw('report.account.analytic.journal', 'account.analytic.journal', 'addons/account/project/report/analytic_journal.rml',parser=account_analytic_journal,header="internal")
+class report_analyticjournal(osv.AbstractModel):
+ _name = 'report.account.report_analyticjournal'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_analyticjournal'
+ _wrapped_report_class = account_analytic_journal
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/report/cost_ledger.py b/addons/account/project/report/cost_ledger.py
index e594ab92a63..5eef375eaab 100644
--- a/addons/account/project/report/cost_ledger.py
+++ b/addons/account/project/report/cost_ledger.py
@@ -20,9 +20,10 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class account_analytic_cost_ledger(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(account_analytic_cost_ledger, self).__init__(cr, uid, name, context=context)
@@ -100,8 +101,11 @@ class account_analytic_cost_ledger(report_sxw.rml_parse):
credit = self._sum_credit(accounts, date1, date2)
return (debit-credit)
-report_sxw.report_sxw('report.account.analytic.account.cost_ledger', 'account.analytic.account', 'addons/account/project/report/cost_ledger.rml',parser=account_analytic_cost_ledger, header="internal")
+class report_analyticcostledger(osv.AbstractModel):
+ _name = 'report.account.report_analyticcostledger'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_analyticcostledger'
+ _wrapped_report_class = account_analytic_cost_ledger
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/report/inverted_analytic_balance.py b/addons/account/project/report/inverted_analytic_balance.py
index bd86bcfe257..23129144555 100644
--- a/addons/account/project/report/inverted_analytic_balance.py
+++ b/addons/account/project/report/inverted_analytic_balance.py
@@ -20,7 +20,7 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
class account_inverted_analytic_balance(report_sxw.rml_parse):
@@ -120,8 +120,11 @@ class account_inverted_analytic_balance(report_sxw.rml_parse):
WHERE account_id IN %s AND date>=%s AND date<=%s", (tuple(ids),date1, date2,))
return self.cr.fetchone()[0] or 0.0
-report_sxw.report_sxw('report.account.analytic.account.inverted.balance', 'account.analytic.account', 'addons/account/project/report/inverted_analytic_balance.rml',parser=account_inverted_analytic_balance, header="internal")
+class report_invertedanalyticbalance(osv.AbstractModel):
+ _name = 'report.account.report_invertedanalyticbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_invertedanalyticbalance'
+ _wrapped_report_class = account_inverted_analytic_balance
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account/project/report/quantity_cost_ledger.py b/addons/account/project/report/quantity_cost_ledger.py
index b22558b900f..d3ed1cdc3a8 100644
--- a/addons/account/project/report/quantity_cost_ledger.py
+++ b/addons/account/project/report/quantity_cost_ledger.py
@@ -19,9 +19,10 @@
#
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class account_analytic_quantity_cost_ledger(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(account_analytic_quantity_cost_ledger, self).__init__(cr, uid, name, context=context)
@@ -116,9 +117,11 @@ class account_analytic_quantity_cost_ledger(report_sxw.rml_parse):
AND journal_id IN %s",(tuple(ids), date1, date2, tuple(journal_ids)))
return self.cr.fetchone()[0] or 0.0
-report_sxw.report_sxw('report.account.analytic.account.quantity_cost_ledger',
- 'account.analytic.account',
- 'addons/account/project/report/quantity_cost_ledger.rml',
- parser=account_analytic_quantity_cost_ledger, header="internal")
+
+class report_analyticcostledgerquantity(osv.AbstractModel):
+ _name = 'report.account.report_analyticcostledgerquantity'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_analyticcostledgerquantity'
+ _wrapped_report_class = account_analytic_quantity_cost_ledger
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/views/report_analyticbalance.xml b/addons/account/project/views/report_analyticbalance.xml
index 96f692eda3d..09cd56fc83f 100644
--- a/addons/account/project/views/report_analyticbalance.xml
+++ b/addons/account/project/views/report_analyticbalance.xml
@@ -22,28 +22,28 @@
Total
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
+
diff --git a/addons/account/project/views/report_analyticcostledger.xml b/addons/account/project/views/report_analyticcostledger.xml
index fd99c637411..cda37d4158f 100644
--- a/addons/account/project/views/report_analyticcostledger.xml
+++ b/addons/account/project/views/report_analyticcostledger.xml
@@ -10,11 +10,11 @@
Printing Date:
@@ -38,10 +38,10 @@
Total:
-
-
+
+
-
+
@@ -50,12 +50,12 @@
-
-
-
+
+
+
-
+
@@ -66,7 +66,7 @@
-
+
diff --git a/addons/account/project/views/report_analyticcostledgerquantity.xml b/addons/account/project/views/report_analyticcostledgerquantity.xml
index 1098a7627f3..de49d4972e5 100644
--- a/addons/account/project/views/report_analyticcostledgerquantity.xml
+++ b/addons/account/project/views/report_analyticcostledgerquantity.xml
@@ -10,11 +10,11 @@
Printing Date:
@@ -39,7 +39,7 @@
-
+
@@ -54,11 +54,11 @@
-
+
-
+
@@ -66,7 +66,7 @@
-
+
diff --git a/addons/account/project/views/report_analyticjournal.xml b/addons/account/project/views/report_analyticjournal.xml
index ce2f216e419..1b3a4fda97c 100644
--- a/addons/account/project/views/report_analyticjournal.xml
+++ b/addons/account/project/views/report_analyticjournal.xml
@@ -11,11 +11,11 @@
Currency:
@@ -35,12 +35,12 @@
-
-
-
+
+
-
+
@@ -56,7 +56,7 @@
-
+
@@ -71,13 +71,13 @@
-
+
-
-
+
diff --git a/addons/account/project/views/report_invertedanalyticbalance.xml b/addons/account/project/views/report_invertedanalyticbalance.xml
index 7ed8f4f84f3..e545ec8525b 100644
--- a/addons/account/project/views/report_invertedanalyticbalance.xml
+++ b/addons/account/project/views/report_invertedanalyticbalance.xml
@@ -22,14 +22,14 @@
Total
-
-
+
+
-
+
-
+
-
+
@@ -58,7 +58,7 @@
-
+
diff --git a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
index b3c2d1bec12..125dfda46fb 100644
--- a/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_cost_ledger_for_journal_report.py
@@ -49,7 +49,6 @@ class account_analytic_cost_ledger_journal_report(osv.osv_memory):
}
datas['form']['active_ids'] = context.get('active_ids', False)
-
return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticcostledgerquantity', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/project/wizard/account_analytic_inverted_balance_report.py b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
index 3b03ad2da56..ad79c0b33f6 100644
--- a/addons/account/project/wizard/account_analytic_inverted_balance_report.py
+++ b/addons/account/project/wizard/account_analytic_inverted_balance_report.py
@@ -46,9 +46,7 @@ class account_analytic_inverted_balance(osv.osv_memory):
'model': 'account.analytic.account',
'form': data
}
-
datas['form']['active_ids'] = context.get('active_ids', False)
-
return self.pool['report'].get_action(cr, uid, ids, 'account.report_invertedanalyticbalance', data=datas, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py
index 3b000e40592..3fd83c19207 100644
--- a/addons/account/report/account_aged_partner_balance.py
+++ b/addons/account/report/account_aged_partner_balance.py
@@ -20,9 +20,11 @@
##############################################################################
import time
+from openerp.osv import osv
from openerp.report import report_sxw
from common_report_header import common_report_header
+
class aged_trial_report(report_sxw.rml_parse, common_report_header):
def __init__(self, cr, uid, name, context):
@@ -375,8 +377,11 @@ class aged_trial_report(report_sxw.rml_parse, common_report_header):
return self._translate('Receivable and Payable Accounts')
return ''
-report_sxw.report_sxw('report.account.aged_trial_balance', 'res.partner',
- 'addons/account/report/account_aged_partner_balance.rml',parser=aged_trial_report, header="internal landscape")
+class report_agedpartnerbalance(osv.AbstractModel):
+ _name = 'report.account.report_agedpartnerbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_agedpartnerbalance'
+ _wrapped_report_class = aged_trial_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_balance.py b/addons/account/report/account_balance.py
index 2a445984b27..af2c37fc610 100644
--- a/addons/account/report/account_balance.py
+++ b/addons/account/report/account_balance.py
@@ -21,9 +21,11 @@
import time
+from openerp.osv import osv
from openerp.report import report_sxw
from common_report_header import common_report_header
+
class account_balance(report_sxw.rml_parse, common_report_header):
_name = 'report.account.account.balance'
@@ -58,11 +60,6 @@ class account_balance(report_sxw.rml_parse, common_report_header):
objects = self.pool.get('account.account').browse(self.cr, self.uid, new_ids)
return super(account_balance, self).set_context(objects, data, new_ids, report_type=report_type)
- #def _add_header(self, node, header=1):
- # if header == 0:
- # self.rml_header = ""
- # return True
-
def _get_account(self, data):
if data['model']=='account.account':
return self.pool.get('account.account').browse(self.cr, self.uid, data['form']['id']).company_id.name
@@ -131,6 +128,11 @@ class account_balance(report_sxw.rml_parse, common_report_header):
_process_child(accounts,form['display_account'],parent)
return self.result_acc
-report_sxw.report_sxw('report.account.account.balance', 'account.account', 'addons/account/report/account_balance.rml', parser=account_balance, header="internal")
+
+class report_trialbalance(osv.AbstractModel):
+ _name = 'report.account.report_trialbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_trialbalance'
+ _wrapped_report_class = account_balance
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_central_journal.py b/addons/account/report/account_central_journal.py
index 8dae208a7a5..28892d0730e 100644
--- a/addons/account/report/account_central_journal.py
+++ b/addons/account/report/account_central_journal.py
@@ -20,11 +20,14 @@
##############################################################################
import time
+from openerp.osv import osv
from openerp.report import report_sxw
from common_report_header import common_report_header
#
# Use period and Journal for selection or resources
#
+
+
class journal_print(report_sxw.rml_parse, common_report_header):
def __init__(self, cr, uid, name, context=None):
@@ -103,6 +106,11 @@ class journal_print(report_sxw.rml_parse, common_report_header):
return True
return data['form']['amount_currency']
-report_sxw.report_sxw('report.account.central.journal', 'account.journal.period', 'addons/account/report/account_central_journal.rml', parser=journal_print, header='external')
+
+class report_agedpartnerbalance(osv.AbstractModel):
+ _name = 'report.account.report_centraljournal'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_centraljournal'
+ _wrapped_report_class = journal_print
# 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
index 2b1f5af4d68..064f02c5fbf 100644
--- a/addons/account/report/account_financial_report.py
+++ b/addons/account/report/account_financial_report.py
@@ -23,6 +23,8 @@ import time
from openerp.report import report_sxw
from common_report_header import common_report_header
from openerp.tools.translate import _
+from openerp.osv import osv
+
class report_account_common(report_sxw.rml_parse, common_report_header):
@@ -105,8 +107,11 @@ class report_account_common(report_sxw.rml_parse, common_report_header):
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')
+class report_financial(osv.AbstractModel):
+ _name = 'report.account.report_financial'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_financial'
+ _wrapped_report_class = report_account_common
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_general_journal.py b/addons/account/report/account_general_journal.py
index 4f63411478c..ada615e31fa 100644
--- a/addons/account/report/account_general_journal.py
+++ b/addons/account/report/account_general_journal.py
@@ -20,8 +20,10 @@
##############################################################################
import time
-from common_report_header import common_report_header
+from openerp.osv import osv
from openerp.report import report_sxw
+from common_report_header import common_report_header
+
class journal_print(report_sxw.rml_parse, common_report_header):
@@ -156,6 +158,11 @@ class journal_print(report_sxw.rml_parse, common_report_header):
(tuple(move_state), period_id, tuple(journals)))
return self.cr.fetchone()[0] or 0.0
-report_sxw.report_sxw('report.account.general.journal', 'account.journal.period', 'addons/account/report/general_journal.rml', parser=journal_print, header='internal')
+
+class report_generaljournal(osv.AbstractModel):
+ _name = 'report.account.report_generaljournal'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_generaljournal'
+ _wrapped_report_class = journal_print
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_general_ledger.py b/addons/account/report/account_general_ledger.py
index 4f712ad58cc..ffccbec300d 100644
--- a/addons/account/report/account_general_ledger.py
+++ b/addons/account/report/account_general_ledger.py
@@ -28,9 +28,11 @@
##############################################################################
import time
+from openerp.osv import osv
from openerp.report import report_sxw
from common_report_header import common_report_header
+
class general_ledger(report_sxw.rml_parse, common_report_header):
_name = 'report.account.general.ledger'
@@ -304,7 +306,11 @@ class general_ledger(report_sxw.rml_parse, common_report_header):
return self._translate('Journal & Partner')
return self._translate('Date')
-report_sxw.report_sxw('report.account.general.ledger', 'account.account', 'addons/account/report/account_general_ledger.rml', parser=general_ledger, header='internal')
-report_sxw.report_sxw('report.account.general.ledger_landscape', 'account.account', 'addons/account/report/account_general_ledger_landscape.rml', parser=general_ledger, header='internal landscape')
+
+class report_generalledger(osv.AbstractModel):
+ _name = 'report.account.report_generalledger'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_generalledger'
+ _wrapped_report_class = general_ledger
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_journal.py b/addons/account/report/account_journal.py
index 97e19be4b0c..13dfd538f4a 100644
--- a/addons/account/report/account_journal.py
+++ b/addons/account/report/account_journal.py
@@ -20,8 +20,10 @@
##############################################################################
import time
-from common_report_header import common_report_header
+from openerp.osv import osv
from openerp.report import report_sxw
+from common_report_header import common_report_header
+
class journal_print(report_sxw.rml_parse, common_report_header):
@@ -196,7 +198,18 @@ class journal_print(report_sxw.rml_parse, common_report_header):
return self._translate('Reference Number')
return self._translate('Date')
-report_sxw.report_sxw('report.account.journal.period.print', 'account.journal.period', 'addons/account/report/account_journal.rml', parser=journal_print, header='external')
-report_sxw.report_sxw('report.account.journal.period.print.sale.purchase', 'account.journal.period', 'addons/account/report/account_journal_sale_purchase.rml', parser=journal_print, header='external')
+
+class report_journal(osv.AbstractModel):
+ _name = 'report.account.report_journal'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_journal'
+ _wrapped_report_class = journal_print
+
+
+class report_salepurchasejournal(osv.AbstractModel):
+ _name = 'report.account.report_salepurchasejournal'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_salepurchasejournal'
+ _wrapped_report_class = journal_print
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_partner_balance.py b/addons/account/report/account_partner_balance.py
index 53edbbe9685..ecd287551e5 100644
--- a/addons/account/report/account_partner_balance.py
+++ b/addons/account/report/account_partner_balance.py
@@ -20,11 +20,12 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.tools.translate import _
from openerp.report import report_sxw
from common_report_header import common_report_header
+
class partner_balance(report_sxw.rml_parse, common_report_header):
def __init__(self, cr, uid, name, context=None):
@@ -301,6 +302,11 @@ class partner_balance(report_sxw.rml_parse, common_report_header):
return _('Receivable and Payable Accounts')
return ''
-report_sxw.report_sxw('report.account.partner.balance', 'res.partner', 'account/report/account_partner_balance.rml',parser=partner_balance, header="internal")
+
+class report_partnerbalance(osv.AbstractModel):
+ _name = 'report.account.report_partnerbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_partnerbalance'
+ _wrapped_report_class = partner_balance
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_partner_ledger.py b/addons/account/report/account_partner_ledger.py
index d21323e02fc..f02ac96b6fc 100644
--- a/addons/account/report/account_partner_ledger.py
+++ b/addons/account/report/account_partner_ledger.py
@@ -20,10 +20,11 @@
##############################################################################
import time
-import re
+from openerp.osv import osv
+from openerp.tools.translate import _
from openerp.report import report_sxw
from common_report_header import common_report_header
-from openerp.tools.translate import _
+
class third_party_ledger(report_sxw.rml_parse, common_report_header):
@@ -297,12 +298,18 @@ class third_party_ledger(report_sxw.rml_parse, common_report_header):
return True
return False
-report_sxw.report_sxw('report.account.third_party_ledger', 'res.partner',
- 'addons/account/report/account_partner_ledger.rml',parser=third_party_ledger,
- header='internal')
-report_sxw.report_sxw('report.account.third_party_ledger_other', 'res.partner',
- 'addons/account/report/account_partner_ledger_other.rml',parser=third_party_ledger,
- header='internal')
+class report_partnerledger(osv.AbstractModel):
+ _name = 'report.account.report_partnerledger'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_partnerledger'
+ _wrapped_report_class = third_party_ledger
+
+
+class report_partnerledgerother(osv.AbstractModel):
+ _name = 'report.account.report_partnerledgerother'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_partnerledgerother'
+ _wrapped_report_class = third_party_ledger
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/account_print_overdue.py b/addons/account/report/account_print_overdue.py
index e135f41309d..26192d39949 100644
--- a/addons/account/report/account_print_overdue.py
+++ b/addons/account/report/account_print_overdue.py
@@ -22,15 +22,36 @@
import time
from openerp.report import report_sxw
+from openerp.osv import osv
+
class Overdue(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(Overdue, self).__init__(cr, uid, name, context=context)
- self.localcontext.update( {
+ ids = context.get('active_ids')
+ partner_obj = self.pool['res.partner']
+ docs = partner_obj.browse(cr, uid, ids, context)
+
+ due = {}
+ paid = {}
+ mat = {}
+
+ for partner in docs:
+ due[partner.id] = reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['debit'] or 0) or (y['account_id']['type'] == 'payable' and y['credit'] * -1 or 0)), self._lines_get(partner), 0)
+ paid[partner.id] = reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['credit'] or 0) or (y['account_id']['type'] == 'payable' and y['debit'] * -1 or 0)), self._lines_get(partner), 0)
+ mat[partner.id] = reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] < time.strftime('%Y-%m-%d'), self._lines_get(partner)), 0)
+
+ addresses = self.pool['res.partner']._address_display(cr, uid, ids, None, None)
+ self.localcontext.update({
+ 'docs': docs,
'time': time,
'getLines': self._lines_get,
'tel_get': self._tel_get,
'message': self._message,
+ 'due': due,
+ 'paid': paid,
+ 'mat': mat,
+ 'addresses': addresses
})
self.context = context
@@ -41,7 +62,7 @@ class Overdue(report_sxw.rml_parse):
addresses = res_partner.address_get(self.cr, self.uid, [partner.id], ['invoice'])
adr_id = addresses and addresses['invoice'] or False
if adr_id:
- adr=res_partner_address.read(self.cr, self.uid, [adr_id])[0]
+ adr=res_partner.read(self.cr, self.uid, [adr_id])[0]
return adr['phone']
else:
return partner.phone or False
@@ -62,5 +83,10 @@ class Overdue(report_sxw.rml_parse):
return message.split('\n')
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+class report_overdue(osv.AbstractModel):
+ _name = 'report.account.report_overdue'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_overdue'
+ _wrapped_report_class = Overdue
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/report/report_vat.py b/addons/account/report/report_vat.py
index 3a0950ac62f..be2b6244f7d 100644
--- a/addons/account/report/report_vat.py
+++ b/addons/account/report/report_vat.py
@@ -19,24 +19,16 @@
#
##############################################################################
+import time
from openerp.osv import osv
-from openerp.addons.web import http
-from openerp.addons.web.http import request
+from openerp.report import report_sxw
from common_report_header import common_report_header
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
-import xlwt
-class tax_report(osv.AbstractModel, common_report_header):
- _name = 'report.account.report_vat'
-
- def render_html(self, cr, uid, ids, data=None, context=None):
- report_obj = request.registry['report']
- self.cr, self.uid, self.context = cr, uid, context
+class tax_report(report_sxw.rml_parse, common_report_header):
+ def set_context(self, objects, data, ids, report_type=None):
+ new_ids = ids
res = {}
self.period_ids = []
period_obj = self.pool.get('account.period')
@@ -46,30 +38,42 @@ class tax_report(osv.AbstractModel, common_report_header):
if data['form'].get('period_from', False) and data['form'].get('period_to', False):
self.period_ids = period_obj.build_ctx_periods(self.cr, self.uid, data['form']['period_from'], data['form']['period_to'])
+ periods_l = period_obj.read(self.cr, self.uid, self.period_ids, ['name'])
+ for period in periods_l:
+ if res['periods'] == '':
+ res['periods'] = period['name']
+ else:
+ res['periods'] += ", "+ period['name']
+ return super(tax_report, self).set_context(objects, data, new_ids, report_type=report_type)
- docargs = {
- 'fiscalyear': self._get_fiscalyear(data),
- 'account': self._get_account(data),
- 'based_on': self._get_basedon(data),
- 'period_from': self.get_start_period(data),
- 'period_to': self.get_end_period(data),
- 'taxlines': self._get_lines(self._get_basedon(data), company_id=data['form']['company_id'], cr=cr, uid=uid),
- }
- return report_obj.render(self.cr, self.uid, [], 'account.report_vat', docargs, context=context)
+ def __init__(self, cr, uid, name, context=None):
+ super(tax_report, self).__init__(cr, uid, name, context=context)
+ self.localcontext.update({
+ 'time': time,
+ 'get_codes': self._get_codes,
+ 'get_general': self._get_general,
+ 'get_currency': self._get_currency,
+ 'get_lines': self._get_lines,
+ '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_basedon': self._get_basedon,
+ })
def _get_basedon(self, form):
return form['form']['based_on']
- def _get_lines(self, based_on, company_id=False, parent=False, level=0, context=None, cr=None, uid=None):
+ def _get_lines(self, based_on, company_id=False, parent=False, level=0, context=None):
period_list = self.period_ids
- res = self._get_codes(based_on, company_id, parent, level, period_list, cr=cr, uid=uid, context=context)
+ res = self._get_codes(based_on, company_id, parent, level, period_list, context=context)
if period_list:
res = self._add_codes(based_on, res, period_list, context=context)
else:
- cr.execute ("select id from account_fiscalyear")
- fy = cr.fetchall()
- cr.execute ("select id from account_period where fiscalyear_id = %s",(fy[0][0],))
- periods = cr.fetchall()
+ self.cr.execute ("select id from account_fiscalyear")
+ fy = self.cr.fetchall()
+ self.cr.execute ("select id from account_period where fiscalyear_id = %s",(fy[0][0],))
+ periods = self.cr.fetchall()
for p in periods:
period_list.append(p[0])
res = self._add_codes(based_on, res, period_list, context=context)
@@ -89,7 +93,7 @@ class tax_report(osv.AbstractModel, common_report_header):
}
top_result.append(res_dict)
- res_general = self._get_general(res[i][1].id, period_list, company_id, based_on, cr=cr, uid=uid, context=context)
+ res_general = self._get_general(res[i][1].id, period_list, company_id, based_on, context=context)
ind_general = 0
while ind_general < len(res_general):
res_general[ind_general]['type'] = 2
@@ -100,14 +104,14 @@ class tax_report(osv.AbstractModel, common_report_header):
i+=1
return top_result
- def _get_general(self, tax_code_id, period_list, company_id, based_on, cr=None, uid=None, context=None):
+ def _get_general(self, tax_code_id, period_list, company_id, based_on, context=None):
if not self.display_detail:
return []
res = []
obj_account = self.pool.get('account.account')
periods_ids = tuple(period_list)
if based_on == 'payments':
- cr.execute('SELECT SUM(line.tax_amount) AS tax_amount, \
+ self.cr.execute('SELECT SUM(line.tax_amount) AS tax_amount, \
SUM(line.debit) AS debit, \
SUM(line.credit) AS credit, \
COUNT(*) AS count, \
@@ -131,7 +135,7 @@ class tax_report(osv.AbstractModel, common_report_header):
company_id, periods_ids, 'paid',))
else:
- cr.execute('SELECT SUM(line.tax_amount) AS tax_amount, \
+ self.cr.execute('SELECT SUM(line.tax_amount) AS tax_amount, \
SUM(line.debit) AS debit, \
SUM(line.credit) AS credit, \
COUNT(*) AS count, \
@@ -148,21 +152,23 @@ class tax_report(osv.AbstractModel, common_report_header):
AND account.active \
GROUP BY account.id,account.name,account.code', ('draft', tax_code_id,
company_id, periods_ids,))
- res = cr.dictfetchall()
+ res = self.cr.dictfetchall()
i = 0
while i= int(accounts[bcl_rup_ind]['level']) and bcl_rup_ind >= 0 ):
- res_tot = {
- 'code': accounts[bcl_rup_ind]['code'],
+ res_tot = { 'code': accounts[bcl_rup_ind]['code'],
'name': '',
'debit': 0,
'credit': 0,
@@ -225,40 +234,10 @@ class tax_report(osv.AbstractModel, common_report_header):
return result_accounts
-class tax_report_xls(http.Controller):
-
- @http.route(['/report/account.report_vat_xls'], type='http', auth='user', website=True, multilang=True)
- def report_account_tax_xls(self, **data):
-
- # Very ugly lines, only for the proof of concept of 'controller' report
- taxreport_obj = request.registry['report.account.report_vat']
- from openerp.addons.report.controllers.main import ReportController
- eval_params = ReportController()._eval_params
-
- cr, uid = request.cr, request.uid
- data = eval_params(data)
- data = {'form': data}
-
- taxreport_obj.render_html(cr, uid, [], data=data)
- lines = taxreport_obj._get_lines(taxreport_obj._get_basedon(data), company_id=data['form']['company_id'], cr=cr, uid=uid)
-
- if lines:
- xls = StringIO.StringIO()
- xls_workbook = xlwt.Workbook()
- vat_sheet = xls_workbook.add_sheet('report_vat')
-
- for x in range(0, len(lines)):
- for y in range(0, len(lines[0])):
- vat_sheet.write(x, y, lines[x].values()[y])
-
- xls_workbook.save(xls)
- xls.seek(0)
- content = xls.read()
-
- response = request.make_response(content, headers=[
- ('Content-Type', 'application/vnd.ms-excel'),
- ('Content-Disposition', 'attachment; filename=report_vat.xls;')
- ])
- return response
+class report_vat(osv.AbstractModel):
+ _name = 'report.account.report_vat'
+ _inherit = 'report.abstract_report'
+ _template = 'account.report_vat'
+ _wrapped_report_class = tax_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/test/account_report.yml b/addons/account/test/account_report.yml
index 7a2d09486e4..9173c37b61e 100644
--- a/addons/account/test/account_report.yml
+++ b/addons/account/test/account_report.yml
@@ -16,10 +16,9 @@
import os
import openerp.report
from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [ref('account.account_invoice_customer0')], 'account.invoice', {}, {})
+ data, format = openerp.report.render_report(cr, uid, [ref('account.account_invoice_customer0')], 'account.report_invoice', {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'account-invoice.'+format), 'wb+').write(data)
-
-
In order to test the PDF reports defined on a partner, we will print the Overdue Report
-
@@ -27,7 +26,7 @@
import os
import openerp.report
from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [ref('base.res_partner_1'),ref('base.res_partner_2'),ref('base.res_partner_12')], 'account.overdue', {}, {})
+ data, format = openerp.report.render_report(cr, uid, [ref('base.res_partner_1'),ref('base.res_partner_2'),ref('base.res_partner_12')], 'account.report_overdue', {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'account-report_overdue.'+format), 'wb+').write(data)
-
@@ -86,8 +85,8 @@
Print the General Ledger Report in Landscape Mode
-
!python {model: account.account}: |
- ctx={}
- data_dict = {'chart_account_id':ref('account.chart0'),'landscape':True}
+ ctx={'landscape': True}
+ data_dict = {'chart_account_id':ref('account.chart0')}
from openerp.tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_ledger_menu',wiz_data=data_dict, context=ctx, our_module='account')
-
diff --git a/addons/account/views/report_agedpartnerbalance.xml b/addons/account/views/report_agedpartnerbalance.xml
index 9ab05afa772..019f32a35de 100644
--- a/addons/account/views/report_agedpartnerbalance.xml
+++ b/addons/account/views/report_agedpartnerbalance.xml
@@ -52,11 +52,11 @@
Due
Not due
-
-
-
-
- +
+
+
+
+
+
Total
diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml
index 080de9a5615..0c2d763f84e 100644
--- a/addons/account/views/report_overdue.xml
+++ b/addons/account/views/report_overdue.xml
@@ -8,6 +8,7 @@
+
diff --git a/addons/account/views/report_vat.xml b/addons/account/views/report_vat.xml
index 03664045ef4..f88d45e5c44 100644
--- a/addons/account/views/report_vat.xml
+++ b/addons/account/views/report_vat.xml
@@ -39,7 +39,7 @@
-
+
diff --git a/addons/account/wizard/account_financial_report.py b/addons/account/wizard/account_financial_report.py
index df1fa94ae90..6c1b57fa428 100644
--- a/addons/account/wizard/account_financial_report.py
+++ b/addons/account/wizard/account_financial_report.py
@@ -84,8 +84,6 @@ class accounting_report(osv.osv_memory):
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['data'] = {}
- res['data']['form'] = data['form']
res['data']['form']['comparison_context'] = comparison_context
return res
diff --git a/addons/account/wizard/account_report_partner_ledger.py b/addons/account/wizard/account_report_partner_ledger.py
index 75f79512603..eb743e32e4f 100644
--- a/addons/account/wizard/account_report_partner_ledger.py
+++ b/addons/account/wizard/account_report_partner_ledger.py
@@ -57,6 +57,8 @@ class account_partner_ledger(osv.osv_memory):
context = {}
data = self.pre_print_report(cr, uid, ids, data, context=context)
data['form'].update(self.read(cr, uid, ids, ['initial_balance', 'filter', 'page_split', 'amount_currency'])[0])
+ if data['form'].get('page_split') is True:
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerledgerother', data=data, context=context)
return self.pool['report'].get_action(cr, uid, ids, 'account.report_partnerledger', data=data, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_analytic_plans/__openerp__.py b/addons/account_analytic_plans/__openerp__.py
index 7c580bd14f2..7ca7c00e6c0 100644
--- a/addons/account_analytic_plans/__openerp__.py
+++ b/addons/account_analytic_plans/__openerp__.py
@@ -76,7 +76,7 @@ The analytic plan validates the minimum and maximum percentage at the time of cr
'views/report_crossoveredanalyticplans.xml',
],
'demo': [],
- 'test': [],
+ 'test': ['test/acount_analytic_plans_report.yml'],
'installable': True,
'auto_install': False,
}
diff --git a/addons/account_analytic_plans/report/crossovered_analytic.py b/addons/account_analytic_plans/report/crossovered_analytic.py
index b1a8f965d6b..ef7589fda8e 100644
--- a/addons/account_analytic_plans/report/crossovered_analytic.py
+++ b/addons/account_analytic_plans/report/crossovered_analytic.py
@@ -20,9 +20,10 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class crossovered_analytic(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(crossovered_analytic, self).__init__(cr, uid, name, context = context)
@@ -173,7 +174,11 @@ class crossovered_analytic(report_sxw.rml_parse):
final.append(item)
return final
-report_sxw.report_sxw('report.account.analytic.account.crossovered.analytic', 'account.analytic.account', 'addons/account_analytic_plans/report/crossovered_analytic.rml',parser = crossovered_analytic, header='internal')
+
+class report_crossoveredanalyticplans(osv.AbstractModel):
+ _name = 'report.account_analytic_plans.report_crossoveredanalyticplans'
+ _inherit = 'report.abstract_report'
+ _template = 'account_analytic_plans.report_crossoveredanalyticplans'
+ _wrapped_report_class = crossovered_analytic
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account_analytic_plans/test/acount_analytic_plans_report.yml b/addons/account_analytic_plans/test/acount_analytic_plans_report.yml
index 6aa67a3052a..cae58583793 100644
--- a/addons/account_analytic_plans/test/acount_analytic_plans_report.yml
+++ b/addons/account_analytic_plans/test/acount_analytic_plans_report.yml
@@ -6,6 +6,6 @@
import openerp.report
from openerp import tools
data_dict = {'model': 'account.analytic.account', 'form': {'date1':time.strftime("%Y-01-01"),'date2':time.strftime('%Y-%m-%d'),'journal_ids':[6,0,(ref('account.cose_journal_sale'))],'ref':ref('account.analytic_root'),'empty_line':True,'id':ref('account.analytic_root'),'context':{}}}
- data, format = openerp.report.render_report(cr, uid, [ref('account.analytic_root')], 'account.analytic.account.crossovered.analytic', data_dict, {})
+ data, format = openerp.report.render_report(cr, uid, [ref('account.analytic_root')], 'account_analytic_plans.report_crossoveredanalyticplans', data_dict, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'account_analytic_plans-crossovered_analyitic.'+format), 'wb+').write(data)
diff --git a/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml b/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
index bce3cccd5c7..b4470ea2913 100644
--- a/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
+++ b/addons/account_analytic_plans/views/report_crossoveredanalyticplans.xml
@@ -11,11 +11,11 @@
Company:
diff --git a/addons/account_bank_statement_extensions/report/bank_statement_balance_report.py b/addons/account_bank_statement_extensions/report/bank_statement_balance_report.py
index 59b8efb23e1..f0b63bf148c 100644
--- a/addons/account_bank_statement_extensions/report/bank_statement_balance_report.py
+++ b/addons/account_bank_statement_extensions/report/bank_statement_balance_report.py
@@ -21,15 +21,14 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class bank_statement_balance_report(report_sxw.rml_parse):
def set_context(self, objects, data, ids, report_type=None):
cr = self.cr
- uid = self.uid
- context = self.context
cr.execute('SELECT s.name as s_name, s.date AS s_date, j.code as j_code, s.balance_end_real as s_balance ' \
'FROM account_bank_statement s ' \
@@ -46,7 +45,6 @@ class bank_statement_balance_report(report_sxw.rml_parse):
})
super(bank_statement_balance_report, self).set_context(objects, data, ids, report_type=report_type)
-
def __init__(self, cr, uid, name, context):
if context is None:
context = {}
@@ -56,12 +54,11 @@ class bank_statement_balance_report(report_sxw.rml_parse):
})
self.context = context
-report_sxw.report_sxw(
- 'report.bank.statement.balance.report',
- 'account.bank.statement',
- 'addons/account_bank_statement_extensions/report/bank_statement_balance_report.rml',
- parser=bank_statement_balance_report,
- header='internal'
-)
+
+class report_bankstatementbalance(osv.AbstractModel):
+ _name = 'report.account_bank_statement_extensions.report_bankstatementbalance'
+ _inherit = 'report.abstract_report'
+ _template = 'account_bank_statement_extensions.report_bankstatementbalance'
+ _wrapped_report_class = bank_statement_balance_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/report/analytic_account_budget_report.py b/addons/account_budget/report/analytic_account_budget_report.py
index 6701fc06a2b..4e3feaf06b7 100644
--- a/addons/account_budget/report/analytic_account_budget_report.py
+++ b/addons/account_budget/report/analytic_account_budget_report.py
@@ -20,10 +20,10 @@
##############################################################################
import time
-import datetime
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class analytic_account_budget_report(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(analytic_account_budget_report, self).__init__(cr, uid, name, context=context)
@@ -166,6 +166,11 @@ class analytic_account_budget_report(report_sxw.rml_parse):
result.append(res)
return result
-report_sxw.report_sxw('report.account.analytic.account.budget', 'account.analytic.account', 'addons/account_budget/report/analytic_account_budget_report.rml',parser=analytic_account_budget_report,header='internal')
+
+class report_analyticaccountbudget(osv.AbstractModel):
+ _name = 'report.account_budget.report_analyticaccountbudget'
+ _inherit = 'report.abstract_report'
+ _template = 'account_budget.report_analyticaccountbudget'
+ _wrapped_report_class = analytic_account_budget_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/report/budget_report.py b/addons/account_budget/report/budget_report.py
index f00eb8a3713..f8f812639b0 100644
--- a/addons/account_budget/report/budget_report.py
+++ b/addons/account_budget/report/budget_report.py
@@ -20,6 +20,7 @@
##############################################################################
import time
+from openerp.osv import osv
from openerp.report import report_sxw
tot = {}
@@ -187,6 +188,11 @@ class budget_report(report_sxw.rml_parse):
result.append(res)
return result
-report_sxw.report_sxw('report.account.budget', 'account.budget.post', 'addons/account_budget/report/budget_report.rml', parser=budget_report, header='internal')
+
+class report_budget(osv.AbstractModel):
+ _name = 'report.account_budget.report_budget'
+ _inherit = 'report.abstract_report'
+ _template = 'account_budget.report_budget'
+ _wrapped_report_class = budget_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_budget/report/crossovered_budget_report.py b/addons/account_budget/report/crossovered_budget_report.py
index 70cbdecb713..8a001aafb39 100644
--- a/addons/account_budget/report/crossovered_budget_report.py
+++ b/addons/account_budget/report/crossovered_budget_report.py
@@ -20,11 +20,9 @@
##############################################################################
import time
-import datetime
-
+from openerp.osv import osv
from openerp.report import report_sxw
-import operator
-from openerp import osv
+
class budget_report(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
@@ -191,7 +189,11 @@ class budget_report(report_sxw.rml_parse):
result.append(res)
return result
-report_sxw.report_sxw('report.crossovered.budget.report', 'crossovered.budget', 'addons/account_budget/report/crossovered_budget_report.rml',parser=budget_report,header='internal')
+
+class report_crossoveredbudget(osv.AbstractModel):
+ _name = 'report.account_budget.report_crossoveredbudget'
+ _inherit = 'report.abstract_report'
+ _template = 'account_budget.report_crossoveredbudget'
+ _wrapped_report_class = budget_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/account_budget/test/account_budget_report.yml b/addons/account_budget/test/account_budget_report.yml
index 80ab9b36b34..a36c2d87d04 100644
--- a/addons/account_budget/test/account_budget_report.yml
+++ b/addons/account_budget/test/account_budget_report.yml
@@ -2,35 +2,22 @@
Print the Analytic Budget Report through wizard
-
!python {model: account.analytic.account}: |
- import os, time
- from openerp import netsvc, tools
- ctx={}
- ctx.update({'model': 'account.analytic.account','active_ids': [ref('account.analytic_root')]})
- data_dict = {}
+ ctx = {'model': 'account.analytic.account','active_ids': [ref('account.analytic_root')]}
from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_account_budget_analytic',wiz_data=data_dict, context=ctx, our_module='account_budget')
+ test_reports.try_report_action(cr, uid, 'action_account_budget_analytic',wiz_data={}, context=ctx, our_module='account_budget')
-
Print the Budget Report through wizard
-
!python {model: account.budget.post}: |
- import os, time
- from openerp import netsvc, tools
- ctx={}
- ctx.update({'model': 'account.budget.post','active_ids': [ref('account_budget.account_budget_post_sales0')]})
- data_dict = {}
+ ctx = {'model': 'account.budget.post','active_ids': [ref('account_budget.account_budget_post_sales0')]}
from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_account_budget_report',wiz_data=data_dict, context=ctx, our_module='account_budget')
+ test_reports.try_report_action(cr, uid, 'action_account_budget_report',wiz_data={}, context=ctx, our_module='account_budget')
-
Print the CrossOvered Budget Report mode through wizard
-
!python {model: crossovered.budget}: |
- import os, time
- from openerp import netsvc, tools
- ctx={}
- ctx.update({'model': 'account.budget.post','active_ids': [ref('account_budget.crossovered_budget_budgetoptimistic0')]})
- data_dict = {}
+ ctx = {'model': 'account.budget.post','active_ids': [ref('account_budget.crossovered_budget_budgetoptimistic0')]}
from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_account_budget_crossvered_report',wiz_data=data_dict, context=ctx, our_module='account_budget')
-
+ test_reports.try_report_action(cr, uid, 'action_account_budget_crossvered_report',wiz_data={}, context=ctx, our_module='account_budget')
diff --git a/addons/account_check_writing/report/check_print.py b/addons/account_check_writing/report/check_print.py
index add79fcc35a..be5feb4662b 100644
--- a/addons/account_check_writing/report/check_print.py
+++ b/addons/account_check_writing/report/check_print.py
@@ -20,8 +20,9 @@
##############################################################################
import time
+from openerp.osv import osv
from openerp.report import report_sxw
-from openerp.tools import amount_to_text_en
+
class report_print_check(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
@@ -33,13 +34,14 @@ class report_print_check(report_sxw.rml_parse):
'get_lines': self.get_lines,
'fill_stars' : self.fill_stars,
})
+
def fill_stars(self, amount):
if len(amount) < 100:
stars = 100 - len(amount)
return ' '.join([amount,'*'*stars])
else: return amount
-
+
def get_lines(self, voucher_lines):
result = []
self.number_lines = len(voucher_lines)
@@ -63,24 +65,11 @@ class report_print_check(report_sxw.rml_parse):
result.append(res)
return result
-report_sxw.report_sxw(
- 'report.account.print.check.top',
- 'account.voucher',
- 'addons/account_check_writing/report/check_print_top.rml',
- parser=report_print_check,header=False
-)
-report_sxw.report_sxw(
- 'report.account.print.check.middle',
- 'account.voucher',
- 'addons/account_check_writing/report/check_print_middle.rml',
- parser=report_print_check,header=False
-)
+class report_check(osv.AbstractModel):
+ _name = 'report.account_check_writing.report_check'
+ _inherit = 'report.abstract_report'
+ _template = 'account_check_writing.report_check'
+ _wrapped_report_class = report_print_check
-report_sxw.report_sxw(
- 'report.account.print.check.bottom',
- 'account.voucher',
- 'addons/account_check_writing/report/check_print_bottom.rml',
- parser=report_print_check,header=False
-)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_followup/account_followup.py b/addons/account_followup/account_followup.py
index 5f912b61b37..eae361913ad 100644
--- a/addons/account_followup/account_followup.py
+++ b/addons/account_followup/account_followup.py
@@ -21,7 +21,6 @@
from openerp.osv import fields, osv
from lxml import etree
-import openerp.tools as tools
from openerp.tools.translate import _
class followup(osv.osv):
@@ -243,7 +242,8 @@ class res_partner(osv.osv):
if partner.unreconciled_aml_ids:
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
current_date = fields.date.context_today(self, cr, uid, context=context)
- final_res = self.pool['report.account_followup.report_followup']._lines_get_with_partner(partner, company.id, cr=cr, uid=uid)
+ rml_parse = account_followup_print.report_rappel(cr, uid, "followup_rml_parser")
+ final_res = rml_parse._lines_get_with_partner(partner, company.id)
for currency_dict in final_res:
currency = currency_dict.get('line', [{'currency_id': company.currency_id}])[0]['currency_id']
@@ -272,8 +272,7 @@ class res_partner(osv.osv):
total = reduce(lambda x, y: x+y['balance'], currency_dict['line'], 0.00)
- report_obj = self.pool.get('report')
- total = report_obj.formatLang(total, dp='Account', currency_obj=currency, cr=cr, uid=uid)
+ total = rml_parse.formatLang(total, dp='Account', currency_obj=currency)
followup_table += '''
''' + _("Amount due") + ''' : %s ''' % (total)
diff --git a/addons/account_followup/report/account_followup_print.py b/addons/account_followup/report/account_followup_print.py
index eecba81acb9..4e856853915 100644
--- a/addons/account_followup/report/account_followup_print.py
+++ b/addons/account_followup/report/account_followup_print.py
@@ -21,9 +21,10 @@
import time
from collections import defaultdict
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class report_rappel(report_sxw.rml_parse):
_name = "account_followup.report.rappel"
@@ -108,8 +109,11 @@ class report_rappel(report_sxw.rml_parse):
}
return text
-report_sxw.report_sxw('report.account_followup.followup.print',
- 'account_followup.stat.by.partner', 'addons/account_followup/report/account_followup_print.rml',
- parser=report_rappel)
+
+class report_followup(osv.AbstractModel):
+ _name = 'report.account_followup.report_followup'
+ _inherit = 'report.abstract_report'
+ _template = 'account_followup.report_followup'
+ _wrapped_report_class = report_rappel
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py
index 00ecab7b860..7b7cb8fc77e 100644
--- a/addons/account_followup/wizard/account_followup_print.py
+++ b/addons/account_followup/wizard/account_followup_print.py
@@ -218,18 +218,18 @@ class account_followup_print(osv.osv_memory):
#Update partners
self.do_update_followup_level(cr, uid, to_update, partner_list, date, context=context)
#process the partners (send mails...)
- restot = self.process_partners(cr, uid, partner_list, data, context=context)
+ restot_context = context.copy()
+ restot = self.process_partners(cr, uid, partner_list, data, context=restot_context)
+ context.update(restot_context)
#clear the manual actions if nothing is due anymore
nbactionscleared = self.clear_manual_actions(cr, uid, partner_list, context=context)
if nbactionscleared > 0:
restot['resulttext'] = restot['resulttext'] + "
" + _("%s partners have no credits and as such the action is cleared") %(str(nbactionscleared)) + " "
- res = restot['action']
-
#return the next action
mod_obj = self.pool.get('ir.model.data')
model_data_ids = mod_obj.search(cr, uid, [('model','=','ir.ui.view'),('name','=','view_account_followup_sending_results')], context=context)
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
- context.update({'description': restot['resulttext'], 'needprinting': restot['needprinting'], 'report_data': res})
+ context.update({'description': restot['resulttext'], 'needprinting': restot['needprinting'], 'report_data': restot['action']})
return {
'name': _('Send Letters and Emails: Actions Summary'),
'view_type': 'form',
diff --git a/addons/account_payment/report/payment_order.py b/addons/account_payment/report/payment_order.py
index a851a54ecbb..292d0e11bf4 100644
--- a/addons/account_payment/report/payment_order.py
+++ b/addons/account_payment/report/payment_order.py
@@ -20,9 +20,10 @@
##############################################################################
import time
-
+from openerp.osv import osv
from openerp.report import report_sxw
+
class payment_order(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context=None):
@@ -70,6 +71,11 @@ class payment_order(report_sxw.rml_parse):
return value_name[0][1]
return False
-report_sxw.report_sxw('report.payment.order', 'payment.order', 'addons/account_payment/report/payment_order.rml', parser=payment_order, header="external")
+
+class report_paymentorder(osv.AbstractModel):
+ _name = 'report.account_payment.report_paymentorder'
+ _inherit = 'report.abstract_report'
+ _template = 'account_payment.report_paymentorder'
+ _wrapped_report_class = payment_order
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/test/account_payment_report.yml b/addons/account_payment/test/account_payment_report.yml
index 3def62de429..922d2502203 100644
--- a/addons/account_payment/test/account_payment_report.yml
+++ b/addons/account_payment/test/account_payment_report.yml
@@ -5,6 +5,6 @@
import os
import openerp.report
from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [ref('payment_order_1')], 'payment.order', {}, {})
+ data, format = openerp.report.render_report(cr, uid, [ref('payment_order_1')], 'account_payment.report_paymentorder', {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'account_payment-payment_order_report.'+format), 'wb+').write(data)
diff --git a/addons/account_test/report/account_test_report.py b/addons/account_test/report/account_test_report.py
index 0cfbc040d82..bb21e3807a8 100644
--- a/addons/account_test/report/account_test_report.py
+++ b/addons/account_test/report/account_test_report.py
@@ -23,8 +23,10 @@
import datetime
import time
-from openerp.report import report_sxw
+from openerp.osv import osv
from openerp.tools.translate import _
+from openerp.report import report_sxw
+
#
# Use period and Journal for selection or resources
@@ -84,6 +86,11 @@ class report_assert_account(report_sxw.rml_parse):
return result
-report_sxw.report_sxw('report.account.test.assert.print', 'accounting.assert.test', 'addons/account_test/report/account_test.rml', parser=report_assert_account, header=False)
+
+class report_accounttest(osv.AbstractModel):
+ _name = 'report.account_test.report_accounttest'
+ _inherit = 'report.abstract_report'
+ _template = 'account_test.report_accounttest'
+ _wrapped_report_class = report_assert_account
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/__openerp__.py b/addons/account_voucher/__openerp__.py
index 6a3b0ee81cd..dc8102d6647 100644
--- a/addons/account_voucher/__openerp__.py
+++ b/addons/account_voucher/__openerp__.py
@@ -58,7 +58,6 @@ This module manages:
'report/account_voucher_sales_receipt_view.xml',
'security/account_voucher_security.xml',
'account_voucher_data.xml',
- 'account_voucher_report.xml',
],
'test' : [
'test/account_voucher_users.yml',
@@ -73,7 +72,6 @@ This module manages:
'test/case3_eur_eur.yml',
'test/case4_cad_chf.yml',
'test/case_eur_usd.yml',
- 'account_voucher_report.yml',
],
'auto_install': False,
'application': True,
diff --git a/addons/account_voucher/account_voucher_report.xml b/addons/account_voucher/account_voucher_report.xml
deleted file mode 100644
index 239492d1a27..00000000000
--- a/addons/account_voucher/account_voucher_report.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_voucher/report/__init__.py b/addons/account_voucher/report/__init__.py
index 862843352a8..53ac7e915be 100644
--- a/addons/account_voucher/report/__init__.py
+++ b/addons/account_voucher/report/__init__.py
@@ -19,8 +19,6 @@
#
##############################################################################
-import account_voucher
-import account_voucher_print
import account_voucher_sales_receipt
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/report/account_voucher.py b/addons/account_voucher/report/account_voucher.py
deleted file mode 100644
index c23c7f4d384..00000000000
--- a/addons/account_voucher/report/account_voucher.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-
-import time
-from openerp.report import report_sxw
-from openerp.tools import amount_to_text_en
-
-class report_voucher(report_sxw.rml_parse):
- def __init__(self, cr, uid, name, context):
- super(report_voucher, self).__init__(cr, uid, name, context)
- self.localcontext.update({
- 'time': time,
- 'convert':self.convert,
- 'get_title': self.get_title,
- 'debit':self.debit,
- 'credit':self.credit,
- 'get_ref': self._get_ref
- })
-
- def convert(self, amount, cur):
- amt_en = amount_to_text_en.amount_to_text(amount, 'en', cur)
- return amt_en
-
- def get_title(self, type):
- title = ''
- if type:
- title = type[0].swapcase() + type[1:] + " Voucher"
- return title
-
- def debit(self, move_ids):
- debit = 0.0
- for move in move_ids:
- debit += move.debit
- return debit
-
- def credit(self, move_ids):
- credit = 0.0
- for move in move_ids:
- credit += move.credit
- return credit
-
- def _get_ref(self, voucher_id, move_ids):
- voucher_line_obj = self.pool.get('account.voucher.line')
- voucher_line = voucher_line_obj.search(self.cr, self.uid, [('partner_id', '=', move_ids.partner_id.id), ('voucher_id', '=', voucher_id)])
- if voucher_line:
- voucher = voucher_line_obj.browse(self.cr, self.uid, voucher_line)[0]
- return voucher.name
- else:
- return
-report_sxw.report_sxw(
- 'report.voucher.cash_receipt.drcr',
- 'account.voucher',
- 'addons/account_voucher/report/account_voucher.rml',
- parser=report_voucher,header="external"
-)
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/report/account_voucher_print.py b/addons/account_voucher/report/account_voucher_print.py
deleted file mode 100644
index 1bc411947f6..00000000000
--- a/addons/account_voucher/report/account_voucher_print.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- 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 .
-#
-##############################################################################
-
-import time
-from openerp.report import report_sxw
-from openerp.tools import amount_to_text_en
-
-class report_voucher_print(report_sxw.rml_parse):
- def __init__(self, cr, uid, name, context):
- super(report_voucher_print, self).__init__(cr, uid, name, context)
- self.localcontext.update({
- 'time': time,
- 'get_title': self.get_title,
- 'get_lines':self.get_lines,
- 'get_on_account':self.get_on_account,
- 'convert':self.convert
- })
-
- def convert(self, amount, cur):
- amt_en = amount_to_text_en.amount_to_text(amount, 'en', cur)
- return amt_en
-
- def get_lines(self, voucher):
- result = []
- if voucher.type in ('payment','receipt'):
- type = voucher.line_ids and voucher.line_ids[0].type or False
- for move in voucher.move_ids:
- res = {}
- amount = move.credit
- if type == 'dr':
- amount = move.debit
- if amount > 0.0:
- res['pname'] = move.partner_id.name
- res['ref'] = 'Agst Ref'+" "+str(move.name)
- res['aname'] = move.account_id.name
- res['amount'] = amount
- result.append(res)
- else:
- type = voucher.line_ids and voucher.line_ids[0].type or False
- for move in voucher.move_ids:
- res = {}
- amount = move.credit
- if type == 'dr':
- amount = move.debit
- if amount > 0.0:
- res['pname'] = move.partner_id.name
- res['ref'] = move.name
- res['aname'] = move.account_id.name
- res['amount'] = amount
- result.append(res)
- return result
-
- def get_title(self, type):
- title = ''
- if type:
- title = type[0].swapcase() + type[1:] + " Voucher"
- return title
-
- def get_on_account(self, voucher):
- name = ""
- if voucher.type == 'receipt':
- name = "Received cash from "+str(voucher.partner_id.name)
- elif voucher.type == 'payment':
- name = "Payment from "+str(voucher.partner_id.name)
- elif voucher.type == 'sale':
- name = "Sale to "+str(voucher.partner_id.name)
- elif voucher.type == 'purchase':
- name = "Purchase from "+str(voucher.partner_id.name)
- return name
-
-report_sxw.report_sxw(
- 'report.voucher.print',
- 'account.voucher',
- 'addons/account_voucher/report/account_voucher_print.rml',
- parser=report_voucher_print,header="external"
-)
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_voucher/test/account_voucher_report.yml b/addons/account_voucher/test/account_voucher_report.yml
deleted file mode 100644
index 96e96e4bdfd..00000000000
--- a/addons/account_voucher/test/account_voucher_report.yml
+++ /dev/null
@@ -1,27 +0,0 @@
--
- Demo for Account Voucher
--
- !record {model: account.voucher, id: account_voucher_voucheraxelor0again, view: view_sale_receipt_form}:
- type: sale
- account_id: account.cash
- company_id: base.main_company
- journal_id: account.bank_journal
- name: Voucher Axelor
- narration: PC Assemble SC234
- amount: 1000.0
- line_ids:
- - account_id: account.cash
- amount: 1000.0
- name: Voucher Axelor
- period_id: account.period_6
-
--
- In order to test the PDF reports defined on a account_voucher, we will print account voucher Report
--
- !python {model: account.voucher}: |
- import os
- import openerp.report
- from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [ref("account_voucher_voucheraxelor0again")], 'voucher.cash_receipt.drcr', {}, {})
- if tools.config['test_report_directory']:
- file(os.path.join(tools.config['test_report_directory'], 'account_voucher-report.'+format), 'wb+').write(data)
diff --git a/addons/lunch/report/order.py b/addons/lunch/report/order.py
index 0bb99f01017..85b216ac632 100644
--- a/addons/lunch/report/order.py
+++ b/addons/lunch/report/order.py
@@ -20,11 +20,11 @@
##############################################################################
import time
-from openerp.addons.web import http
-from openerp.addons.web.http import request
+from openerp.report import report_sxw
+from openerp.osv import osv
-class order(http.Controller):
+class order(report_sxw.rml_parse):
def get_lines(self, user,objects):
lines=[]
@@ -60,24 +60,23 @@ class order(http.Controller):
notes.append(obj.note)
return notes
- @http.route(['/report/lunch.report_lunchorder/'], type='http', auth='user', website=True, multilang=True)
- def report_lunch(self, docids):
- self.cr, self.uid, self.context = request.cr, request.uid, request.context
-
- ids = [int(i) for i in docids.split(',')]
- report_obj = request.registry['lunch.order.line']
- docs = report_obj.browse(self.cr, self.uid, ids, context=self.context)
-
+ def __init__(self, cr, uid, name, context):
+ super(order, self).__init__(cr, uid, name, context)
self.net_total=0.0
- docargs = {
- 'docs': docs,
+ self.localcontext.update({
'time': time,
'get_lines': self.get_lines,
'get_users': self.get_users,
'get_total': self.get_total,
'get_nettotal': self.get_nettotal,
'get_note': self.get_note,
- }
- return request.registry['report'].render(self.cr, self.uid, [], 'lunch.report_lunchorder', docargs)
+ })
+
+
+class report_lunchorder(osv.AbstractModel):
+ _name = 'report.lunch.report_lunchorder'
+ _inherit = 'report.abstract_report'
+ _template = 'lunch.report_lunchorder'
+ _wrapped_report_class = order
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mrp/report/bom_structure.py b/addons/mrp/report/bom_structure.py
index 98949ed75dc..1b286feac46 100644
--- a/addons/mrp/report/bom_structure.py
+++ b/addons/mrp/report/bom_structure.py
@@ -19,22 +19,18 @@
#
##############################################################################
+import time
from openerp.osv import osv
+from openerp.report import report_sxw
-class bom_structure(osv.AbstractModel):
- _name = 'report.mrp.report_mrpbomstructure'
-
- def render_html(self, cr, uid, ids, data=None, context=None):
- mrpbom_obj = self.pool['mrp.bom']
- report_obj = self.pool['report']
- docs = mrpbom_obj.browse(cr, uid, ids, context=context)
-
- docargs = {
- 'docs': docs,
- 'get_children': self.get_children,
- }
- return report_obj.render(cr, uid, [], 'mrp.report_mrpbomstructure', docargs, context=context)
+class bom_structure(report_sxw.rml_parse):
+ def __init__(self, cr, uid, name, context):
+ super(bom_structure, self).__init__(cr, uid, name, context=context)
+ self.localcontext.update({
+ 'time': time,
+ 'get_children':self.get_children,
+ })
def get_children(self, object, level=0):
result = []
@@ -62,4 +58,11 @@ class bom_structure(osv.AbstractModel):
return children
+
+class report_lunchorder(osv.AbstractModel):
+ _name = 'report.mrp.report_mrpbomstructure'
+ _inherit = 'report.abstract_report'
+ _template = 'mpr.report_mrpbomstructure'
+ _wrapped_report_class = bom_structure
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/report_intrastat/test/report_intrastat_report.yml b/addons/report_intrastat/test/report_intrastat_report.yml
index 687f605b901..5c70ba67ef2 100644
--- a/addons/report_intrastat/test/report_intrastat_report.yml
+++ b/addons/report_intrastat/test/report_intrastat_report.yml
@@ -16,6 +16,6 @@
import os
import openerp.report
from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [ref('test_invoice_1')], 'account.invoice.intrastat', {}, {})
+ data, format = openerp.report.render_report(cr, uid, [ref('test_invoice_1')], 'report_intrastat.report_intrastatinvoice', {}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'report_intrastat-intrastat_report.'+format), 'wb+').write(data)
From 33471e966fcae83b60b75ced8d63b0ddb8e2d251 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 11:18:18 +0200
Subject: [PATCH 16/57] [FIX] missing dependancies of report module
bzr revid: sle@openerp.com-20140403091818-6evr0k4r2k4818j1
---
addons/account/__openerp__.py | 2 +-
addons/lunch/__openerp__.py | 2 +-
addons/mrp/__openerp__.py | 2 +-
addons/purchase/__openerp__.py | 2 +-
addons/sale/__openerp__.py | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py
index 83434893ac7..1a222b2f83c 100644
--- a/addons/account/__openerp__.py
+++ b/addons/account/__openerp__.py
@@ -49,7 +49,7 @@ for a particular financial year and for preparation of vouchers there is a modul
""",
'website': 'http://www.openerp.com',
'images' : ['images/accounts.jpeg','images/bank_statement.jpeg','images/cash_register.jpeg','images/chart_of_accounts.jpeg','images/customer_invoice.jpeg','images/journal_entries.jpeg'],
- 'depends' : ['base_setup', 'product', 'analytic', 'process', 'board', 'edi'],
+ 'depends' : ['base_setup', 'product', 'analytic', 'process', 'board', 'edi', 'report'],
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
diff --git a/addons/lunch/__openerp__.py b/addons/lunch/__openerp__.py
index f8a4a1ddcf2..955a1278c03 100644
--- a/addons/lunch/__openerp__.py
+++ b/addons/lunch/__openerp__.py
@@ -23,7 +23,7 @@
'name': 'Lunch Orders',
'author': 'OpenERP SA',
'version': '0.2',
- 'depends': ['base'],
+ 'depends': ['base', 'report'],
'category' : 'Tools',
'summary': 'Lunch Order, Meal, Food',
'description': """
diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py
index ef68b27a489..f3f290b12b0 100644
--- a/addons/mrp/__openerp__.py
+++ b/addons/mrp/__openerp__.py
@@ -29,7 +29,7 @@
'sequence': 18,
'summary': 'Manufacturing Orders, Bill of Materials, Routing',
'images': ['images/bill_of_materials.jpeg', 'images/manufacturing_order.jpeg', 'images/planning_manufacturing_order.jpeg', 'images/manufacturing_analysis.jpeg', 'images/production_dashboard.jpeg','images/routings.jpeg','images/work_centers.jpeg'],
- 'depends': ['product','procurement', 'stock', 'resource', 'purchase','process'],
+ 'depends': ['product','procurement', 'stock', 'resource', 'purchase','process', 'report'],
'description': """
Manage the Manufacturing process in OpenERP
===========================================
diff --git a/addons/purchase/__openerp__.py b/addons/purchase/__openerp__.py
index 0d0a372a3d0..009cbf00b78 100644
--- a/addons/purchase/__openerp__.py
+++ b/addons/purchase/__openerp__.py
@@ -46,7 +46,7 @@ Dashboard / Reports for Purchase Management will include:
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'images' : ['images/purchase_order.jpeg', 'images/purchase_analysis.jpeg', 'images/request_for_quotation.jpeg'],
- 'depends': ['stock', 'process', 'procurement'],
+ 'depends': ['stock', 'process', 'procurement', 'report'],
'data': [
'security/purchase_security.xml',
'security/ir.model.access.csv',
diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py
index bb5bac89e46..1684760debf 100644
--- a/addons/sale/__openerp__.py
+++ b/addons/sale/__openerp__.py
@@ -59,7 +59,7 @@ The Dashboard for the Sales Manager will include
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
'images': ['images/sale_dashboard.jpeg','images/Sale_order_line_to_invoice.jpeg','images/sale_order.jpeg','images/sales_analysis.jpeg'],
- 'depends': ['account_voucher'],
+ 'depends': ['account_voucher', 'report'],
'data': [
'wizard/sale_make_invoice_advance.xml',
'wizard/sale_line_invoice.xml',
From 0d4732b5c4194c7c25a13266dfdd1aed05e534eb Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Thu, 3 Apr 2014 11:40:50 +0200
Subject: [PATCH 17/57] [FIX] makes sure the internal data structure of pivot
table is correct after update_data (the children were not correct when the
tree of headers was not full, after an expand for example (addon web_graph)
bzr revid: ged@openerp.com-20140403094050-vjeq4dks86mejuub
---
addons/web_graph/static/src/js/pivot_table.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js
index 9231765c485..309bb103fa8 100644
--- a/addons/web_graph/static/src/js/pivot_table.js
+++ b/addons/web_graph/static/src/js/pivot_table.js
@@ -219,8 +219,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
header.root.groupby.push(groupby);
}
return this.perform_requests(this_gb, other_gbs, header.domain).then(function () {
- var data = Array.prototype.slice.call(arguments);
- data = data.slice(other_gbs.length + 1, data.length);
+ var data = Array.prototype.slice.call(arguments).slice(other_gbs.length + 1);
_.each(data, function (data_pt) {
self.make_headers_and_cell(
data_pt, header.root.headers, other_root.headers, 1, header.path, true);
@@ -369,6 +368,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({
}
if (corresponding_header && (!header.expanded)) {
corresponding_header.expanded = false;
+ corresponding_header.children = [];
}
});
var updated_headers = _.filter(new_headers, function (header) {
From 75b66ed77c89f14cb4215f4a677298bdcfce3881 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Thu, 3 Apr 2014 11:43:16 +0200
Subject: [PATCH 18/57] [FIX] work around a read bug: false data are fetched
when the same field is present multiple times as a field parameter. The
solution is to make sure the list many2onefields does not contain duplicate
fields (orm.py)
bzr revid: ged@openerp.com-20140403094316-kmlliqbwd14ey68p
---
openerp/osv/orm.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index 9d267816ad5..d9340745b11 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2382,6 +2382,7 @@ class BaseModel(object):
many2onefields = [gb['field'] for gb in annotated_groupbys if gb['type'] == 'many2one']
if many2onefields:
data_ids = [r['id'] for r in fetched_data]
+ many2onefields = list(set(many2onefields))
data_dict = {d['id']: d for d in self.read(cr, uid, data_ids, many2onefields, context=context)}
for d in fetched_data:
d.update(data_dict[d['id']])
@@ -2416,7 +2417,7 @@ class BaseModel(object):
return result
result = map(format_result, data)
-
+
if lazy and groupby_fields[0] in self._group_by_full:
# Right now, read_group only fill results in lazy mode (by default).
# If you need to have the empty groups in 'eager' mode, then the
From 55090e56db84bae50166f1813874f0da32eaac5d Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 12:05:43 +0200
Subject: [PATCH 19/57] [FIX] payment order: do not use qweb contact widget on
res.bank as it is made for res.partner and res.bank has not all the
res.partner fields
bzr revid: sle@openerp.com-20140403100543-t0m45q1wkgbkli7i
---
addons/account_payment/views/report_paymentorder.xml | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/addons/account_payment/views/report_paymentorder.xml b/addons/account_payment/views/report_paymentorder.xml
index c2662b6aa77..42a2cbe989a 100644
--- a/addons/account_payment/views/report_paymentorder.xml
+++ b/addons/account_payment/views/report_paymentorder.xml
@@ -10,8 +10,13 @@
From 1aba5f08cf8697fbfe12b5694e609dfc174d7c03 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Thu, 3 Apr 2014 13:56:05 +0200
Subject: [PATCH 20/57] [FIX] fixes read_group so that it uses the correct
_count attribute in the result dictionary (orm.py)
bzr revid: ged@openerp.com-20140403115605-tuboy66r9ews2u0e
---
openerp/osv/orm.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index d9340745b11..c916b40b6d8 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2337,7 +2337,7 @@ class BaseModel(object):
groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, annotated_groupbys, query, fget)
from_clause, where_clause, where_clause_params = query.get_sql()
- count_field = groupby_fields[0] if (len(groupby_fields) == 1 and context.get('group_by_no_leaf')) else '_'
+ count_field = groupby_fields[0] if lazy and (len(groupby_fields) >= 2 or not context.get('group_by_no_leaf')) else '_'
prefix_terms = lambda prefix, terms: (prefix + " " + ",".join(terms)) if terms else ''
prefix_term = lambda prefix, term: ('%s %s' % (prefix, term)) if term else ''
From 7dd2e6789d2bc7619b6d99dd65f64f133d401ff4 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Thu, 3 Apr 2014 16:29:23 +0200
Subject: [PATCH 21/57] [FIX] when using readgroup in eager mode, there is a
possible name collision when grouping on several fields with different
intervals, for ex, date_deadline:month, date_deadline:week. This commit
resolves the issue by changing the keys 'field' into 'field:interval' (for
ex, date_deadline:month) in the results (orm.py)
bzr revid: ged@openerp.com-20140403142923-puiruf29tbi1pjj9
---
openerp/osv/orm.py | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index c916b40b6d8..1c72001c275 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -2207,7 +2207,7 @@ class BaseModel(object):
"""
orderby_terms = []
groupby_terms = [gb['qualified_field'] for gb in annotated_groupbys]
- groupby_fields = [gb['field'] for gb in annotated_groupbys]
+ groupby_fields = [gb['groupby'] for gb in annotated_groupbys]
if not orderby:
return groupby_terms, orderby_terms
@@ -2217,13 +2217,13 @@ class BaseModel(object):
order_field = order_split[0]
if order_field in groupby_fields:
- if fget[order_field]['type'] == 'many2one':
+ if fget[order_field.split(':')[0]]['type'] == 'many2one':
order_clause = self._generate_order_by(order_part, query).replace('ORDER BY ', '')
if order_clause:
orderby_terms.append(order_clause)
groupby_terms += [order_term.split()[0] for order_term in order_clause.split(',')]
else:
- orderby_terms.append(order_part)
+ orderby_terms.append('"%s"' % order_part)
elif order_field in aggregated_fields:
orderby_terms.append(order_part)
else:
@@ -2299,7 +2299,8 @@ class BaseModel(object):
if field_type == 'boolean':
qualified_field = "coalesce(%s,false)" % qualified_field
return {
- 'field': split[0],
+ 'field': split[0],
+ 'groupby': gb,
'type': field_type,
'display_format': display_formats[gb_function or 'month'] if temporal else None,
'interval': time_intervals[gb_function or 'month'] if temporal else None,
@@ -2309,8 +2310,8 @@ class BaseModel(object):
annotated_groupbys = map(process_groupby, groupby[:1] if lazy else groupby)
groupby_fields = [g['field'] for g in annotated_groupbys]
- order = orderby or ','.join(groupby_fields)
- groupby_dict = {gb['field']: gb for gb in annotated_groupbys}
+ order = orderby or ','.join([g['groupby'] for g in annotated_groupbys])
+ groupby_dict = {gb['groupby']: gb for gb in annotated_groupbys}
self._apply_ir_rules(cr, uid, query, 'read', context=context)
for gb in groupby_fields:
@@ -2333,7 +2334,7 @@ class BaseModel(object):
select_terms = ["%s(%s) AS %s" % field_formatter(f) for f in aggregated_fields]
for gb in annotated_groupbys:
- select_terms.append("%s as %s " % (gb['qualified_field'], gb['field']))
+ select_terms.append('%s as "%s" ' % (gb['qualified_field'], gb['groupby']))
groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, annotated_groupbys, query, fget)
from_clause, where_clause, where_clause_params = query.get_sql()
@@ -2404,7 +2405,7 @@ class BaseModel(object):
return [(gb['field'], '=', value)]
def format_result (fromquery):
- domain_group = [dom for gb in annotated_groupbys for dom in get_domain(gb, fromquery[gb['field']])]
+ domain_group = [dom for gb in annotated_groupbys for dom in get_domain(gb, fromquery[gb['groupby']])]
result = { '__domain': domain_group + domain }
if len(groupby) - len(annotated_groupbys) >= 1:
result['__context'] = { 'group_by': groupby[len(annotated_groupbys):]}
@@ -4421,7 +4422,7 @@ class BaseModel(object):
return Query(tables, where_clause, where_params)
def _check_qorder(self, word):
- if not regex_order.match(word):
+ if not regex_order.match(word.split(':')[0]):
raise except_orm(_('AccessError'), _('Invalid "order" specified. A valid "order" specification is a comma-separated list of valid field names (optionally followed by asc/desc for the direction)'))
return True
From 4975d2b9dc3afe12dfce8a5c6e80dbd42f7a0073 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 16:32:35 +0200
Subject: [PATCH 22/57] [FIX] fixed report translation and translate overdue
report into partner's lang
bzr revid: sle@openerp.com-20140403143235-mpw30fq4j2nyov6x
---
addons/account/views/report_overdue.xml | 204 ++++++++++++------------
addons/report/models/abstract_report.py | 5 +
addons/report/models/report.py | 18 ++-
addons/website_report/views/layouts.xml | 27 ++--
4 files changed, 141 insertions(+), 113 deletions(-)
diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml
index 0c2d763f84e..772e7661800 100644
--- a/addons/account/views/report_overdue.xml
+++ b/addons/account/views/report_overdue.xml
@@ -1,112 +1,116 @@
-
-
-
-
-
-
+
+
+
+
-
- Document: Customer account statement
- Date:
- Customer ref:
-
+
+ Document: Customer account statement
+ Date:
+ Customer ref:
+
-
-
-
+
+
+
+
+
+
+
+
+
+ Date
+ Description
+ Ref
+ Maturity Date
+ Due
+ Paid
+ Maturity
+ Li.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ x
+
+
+
+
+ Sub-Total :
+
+
+
+
+
+
+
+ Balance :
+
+
+
+
+
+
+
+
-
-
-
- Date
- Description
- Ref
- Maturity Date
- Due
- Paid
- Maturity
- Li.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- x
-
-
-
-
- Sub-Total :
-
-
-
-
-
-
-
- Balance :
-
-
-
-
-
-
-
-
+
+ Total amount due:
+
+
-
- Total amount due:
-
-
+
+ There is nothing due with this customer.
+
+
+
+
-
- There is nothing due with this customer.
-
-
-
+
+
+
+
diff --git a/addons/report/models/abstract_report.py b/addons/report/models/abstract_report.py
index c84ce1cac50..730d47287c5 100644
--- a/addons/report/models/abstract_report.py
+++ b/addons/report/models/abstract_report.py
@@ -57,4 +57,9 @@ class AbstractReport(osv.AbstractModel):
# rendering environment
docargs = wrapped_report.localcontext
docargs['docs'] = docargs.get('objects')
+
+ # Used in template translating (see render_doc method from report model)
+ docargs['doc_ids'] = context['active_ids']
+ docargs['doc_model'] = model
+
return self.pool['report'].render(cr, uid, [], self._template, docargs, context=context)
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 992842ffacd..bf1b34b9f2a 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -22,6 +22,7 @@
from openerp.osv import osv
from openerp.tools import config
from openerp.tools.translate import _
+from openerp.addons.web.http import request
import os
import time
@@ -121,18 +122,28 @@ class Report(osv.Model):
if ctx.get('translatable') is True:
qcontext['o'] = doc
else:
- ctx['lang'] = doc.partner_id.lang
- qcontext['o'] = self.pool[model].browse(cr, uid, doc_id, context=ctx)
+ # Guessing the lang we want to translate the doc into
+ newlang = None
+ if hasattr(doc, 'partner_id'):
+ newlang = doc.partner_id.lang
+ elif hasattr(doc, 'lang'):
+ newlang = doc.lang
+ if newlang:
+ ctx['lang'] = newlang
+ qcontext['o'] = self.pool[model].browse(cr, uid, doc_id, context=ctx)
return view_obj.render(cr, uid, template, qcontext, context=ctx)
user = self.pool['res.users'].browse(cr, uid, uid)
+ website = None
+ if request and hasattr(request, 'website'):
+ website = request.website
values.update({
'time': time,
'render_doc': render_doc,
'editable': True, # Will active inherit_branding
'user': user,
'res_company': user.company_id,
- 'website': False, # Will be overidden by ir.ui.view if the request has website enabled
+ 'website': website,
})
return view_obj.render(cr, uid, template, values, context=context)
@@ -325,7 +336,6 @@ class Report(osv.Model):
# Passing the cookie to wkhtmltopdf in order to resolve URL.
try:
- from openerp.addons.web.http import request
if request:
command_args.extend(['--cookie', 'session_id', request.session.sid])
except AttributeError:
diff --git a/addons/website_report/views/layouts.xml b/addons/website_report/views/layouts.xml
index f5deb483374..ef6639de499 100644
--- a/addons/website_report/views/layouts.xml
+++ b/addons/website_report/views/layouts.xml
@@ -72,15 +72,24 @@
-
-
+
+
+
+
From 9d915db2144be0d3b8e01340495f45b4187ceb76 Mon Sep 17 00:00:00 2001
From: Gery Debongnie
Date: Thu, 3 Apr 2014 16:35:34 +0200
Subject: [PATCH 23/57] [FIX] read_group has been changed to return the results
with field:interval as key (for example, date_deadline:week), to avoid name
collisions. This commit changes the web client to make sure it properly
processes the new result format. No change at all for queries that do not
use the field:interval format (addon web)
bzr revid: ged@openerp.com-20140403143534-3jpugw9g8n966n9t
---
addons/web/static/src/js/data.js | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 413d0621011..9d11dbcf2a8 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -238,31 +238,26 @@ instance.web.QueryGroup = instance.web.Class.extend({
{__context: {group_by: []}, __domain: []},
read_group_group);
- var raw_fields = _.map(grouping_fields, function (field) {
- return field && field.split(':')[0];
- });
-
-
+ var count_key = (grouping_fields[0] && grouping_fields[0].split(':')[0]) + '_count';
var aggregates = {};
_(fixed_group).each(function (value, key) {
if (key.indexOf('__') === 0
- || _.contains(raw_fields, key)
- || (key === raw_fields[0] + '_count')) {
+ || _.contains(grouping_fields, key)
+ || (key === count_key)) {
return;
}
aggregates[key] = value || 0;
});
-
this.model = new instance.web.Model(
model, fixed_group.__context, fixed_group.__domain);
- var group_size = fixed_group[raw_fields[0] + '_count'] || fixed_group.__count || 0;
+ var group_size = fixed_group[count_key] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0;
var value = (grouping_fields.length === 1)
- ? fixed_group[raw_fields[0]]
- : _.map(raw_fields, function (field) { return fixed_group[field]; });
+ ? fixed_group[grouping_fields[0]]
+ : _.map(grouping_fields, function (field) { return fixed_group[field]; });
var grouped_on = (grouping_fields.length === 1)
? grouping_fields[0]
: grouping_fields;
From 126d61796aaa0eb8dbf6375ddfd27905bb7b6e23 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 17:48:56 +0200
Subject: [PATCH 24/57] [FIX] abstract_report: correctly pass the active ids in
wrapped_report.set_context, fix analytic journal from ir.ui.menu by setting a
consistent context
bzr revid: sle@openerp.com-20140403154856-s3i220d6w1yw4e5s
---
.../project/wizard/account_analytic_journal_report.py | 5 ++++-
addons/report/models/abstract_report.py | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/addons/account/project/wizard/account_analytic_journal_report.py b/addons/account/project/wizard/account_analytic_journal_report.py
index ab7e553435d..f2e406bc3a5 100644
--- a/addons/account/project/wizard/account_analytic_journal_report.py
+++ b/addons/account/project/wizard/account_analytic_journal_report.py
@@ -54,7 +54,10 @@ class account_analytic_journal_report(osv.osv_memory):
'model': 'account.analytic.journal',
'form': data
}
- return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticjournal', data=datas, context=context)
+ context2 = context.copy()
+ context2['active_model'] = 'account.analytic.journal'
+ context2['active_ids'] = ids_list
+ return self.pool['report'].get_action(cr, uid, ids, 'account.report_analyticjournal', data=datas, context=context2)
def default_get(self, cr, uid, fields, context=None):
if context is None:
diff --git a/addons/report/models/abstract_report.py b/addons/report/models/abstract_report.py
index 730d47287c5..2da32b6c0f6 100644
--- a/addons/report/models/abstract_report.py
+++ b/addons/report/models/abstract_report.py
@@ -51,7 +51,7 @@ class AbstractReport(osv.AbstractModel):
# Generate the old style report
wrapped_report = self._wrapped_report_class(cr, uid, '', context=context)
- wrapped_report.set_context(objects, data, ids)
+ wrapped_report.set_context(objects, data, context['active_ids'])
# Rendering self._template with the wrapped report instance localcontext as
# rendering environment
From d5c06607b69680f13eece3700d801c5507fb0599 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 18:01:33 +0200
Subject: [PATCH 25/57] [FIX] Report: in the save_in_attachment logic, when a
single report is printed, use the id passed in argument to identify it (and
not the qweb branding)
bzr revid: sle@openerp.com-20140403160133-4axmxhw7bq2yf94l
---
addons/report/models/report.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index bf1b34b9f2a..9a65134b0b1 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -233,6 +233,14 @@ class Report(osv.Model):
body = lxml.html.tostring(node)
reportcontent = self.MINIMAL_HTML_PAGE.format(css=css, subst='', body=body, base_url=base_url)
+
+ # FIXME: imo the best way to extract record id from html reports is by using the
+ # qweb branding. As website editor is not yet splitted in a module independant from
+ # website, when we print a unique report we can use the id passed in argument to
+ # identify it.
+ if len(ids) == 1:
+ reportid = ids[0]
+
contenthtml.append(tuple([reportid, reportcontent]))
except lxml.etree.XMLSyntaxError:
From ff1e5edceaa2f3acdb5620ef29312a5e541b20b7 Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 18:21:38 +0200
Subject: [PATCH 26/57] [FIX] guess the language in which the document must be
translated without triggering an orm warning
bzr revid: sle@openerp.com-20140403162138-6yvh3q24n39tdi4r
---
addons/report/models/report.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 9a65134b0b1..96296d50218 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -124,9 +124,9 @@ class Report(osv.Model):
else:
# Guessing the lang we want to translate the doc into
newlang = None
- if hasattr(doc, 'partner_id'):
+ if doc._model._all_columns.get('partner_id'):
newlang = doc.partner_id.lang
- elif hasattr(doc, 'lang'):
+ elif doc._model._all_columns.get('lang'):
newlang = doc.lang
if newlang:
ctx['lang'] = newlang
From 3a917639c84b37459a419b4db28a0dcdd9982afd Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 18:50:51 +0200
Subject: [PATCH 27/57] [FIX] report: there are not always ids in get_pdf...
bzr revid: sle@openerp.com-20140403165051-e6sg419c19xv3w7b
---
addons/report/models/report.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/addons/report/models/report.py b/addons/report/models/report.py
index 96296d50218..723c098ccb2 100644
--- a/addons/report/models/report.py
+++ b/addons/report/models/report.py
@@ -238,7 +238,7 @@ class Report(osv.Model):
# qweb branding. As website editor is not yet splitted in a module independant from
# website, when we print a unique report we can use the id passed in argument to
# identify it.
- if len(ids) == 1:
+ if ids and len(ids) == 1:
reportid = ids[0]
contenthtml.append(tuple([reportid, reportcontent]))
From a1f08e0d103e96268c5bbd1a83d0869d1bfba44d Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 23:17:17 +0200
Subject: [PATCH 28/57] [FIX] action manager: use EncodeURIComponent instead of
EncodeURI because of bad encoding of the ampersand in the secund (resulting
in impossibility to encode 'Belgium Profit & Loss' for instance)
bzr revid: sle@openerp.com-20140403211717-sb84ir2ts62yizzf
---
addons/report/static/src/js/qwebactionmanager.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js
index aa98b2c9c52..3910cab4dd7 100644
--- a/addons/report/static/src/js/qwebactionmanager.js
+++ b/addons/report/static/src/js/qwebactionmanager.js
@@ -33,8 +33,8 @@ openerp.report = function(instance) {
report_url += "/" + action.context.active_ids.join(',');
}
} else {
- report_url += "?options=" + encodeURI(JSON.stringify(action.data));
- report_url += "&context=" + encodeURI(JSON.stringify(action.context));
+ report_url += "?options=" + encodeURIComponent(JSON.stringify(action.data));
+ report_url += "&context=" + encodeURIComponent(JSON.stringify(action.context));
}
if (action.report_type == 'qweb-html') {
From 0cbd5fb87b39683689e9694ba369e5a94ef33e1d Mon Sep 17 00:00:00 2001
From: Simon Lejeune
Date: Thu, 3 Apr 2014 23:22:38 +0200
Subject: [PATCH 29/57] [REM] Removed the luxembourg tax report (this report is
now deprecated as LU only accepts xml etva or onlineform filling)
bzr revid: sle@openerp.com-20140403212238-rf85l911i2g5da3t
---
addons/l10n_lu/__init__.py | 2 -
addons/l10n_lu/__openerp__.py | 5 +-
addons/l10n_lu/test/l10n_lu_report.yml | 18 ----
addons/l10n_lu/wizard/TVA_MEN_09_xxxx.pdf | Bin 384828 -> 0 bytes
addons/l10n_lu/wizard/TVA_TRI_10_xxxx.pdf | Bin 291286 -> 0 bytes
addons/l10n_lu/wizard/__init__.py | 24 -----
addons/l10n_lu/wizard/pdf_ext.py | 110 ----------------------
addons/l10n_lu/wizard/print_vat.py | 96 -------------------
addons/l10n_lu/wizard/print_vat_view.xml | 39 --------
9 files changed, 2 insertions(+), 292 deletions(-)
delete mode 100644 addons/l10n_lu/test/l10n_lu_report.yml
delete mode 100644 addons/l10n_lu/wizard/TVA_MEN_09_xxxx.pdf
delete mode 100644 addons/l10n_lu/wizard/TVA_TRI_10_xxxx.pdf
delete mode 100644 addons/l10n_lu/wizard/__init__.py
delete mode 100644 addons/l10n_lu/wizard/pdf_ext.py
delete mode 100644 addons/l10n_lu/wizard/print_vat.py
delete mode 100644 addons/l10n_lu/wizard/print_vat_view.xml
diff --git a/addons/l10n_lu/__init__.py b/addons/l10n_lu/__init__.py
index 0e933f136e0..9a6ca02408e 100644
--- a/addons/l10n_lu/__init__.py
+++ b/addons/l10n_lu/__init__.py
@@ -19,6 +19,4 @@
#
##############################################################################
-import wizard
-
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/l10n_lu/__openerp__.py b/addons/l10n_lu/__openerp__.py
index 46d2312bb02..96c4ea64dea 100644
--- a/addons/l10n_lu/__openerp__.py
+++ b/addons/l10n_lu/__openerp__.py
@@ -22,7 +22,6 @@
#
##############################################################################
-
{
'name': 'Luxembourg - Accounting',
'version': '1.0',
@@ -51,12 +50,12 @@ This is the base module to manage the accounting chart for Luxembourg.
'account.fiscal.position.tax.template-2011.csv',
# configuration wizard, views, reports...
'l10n_lu_wizard.xml',
- 'wizard/print_vat_view.xml'
],
- 'test': ['test/l10n_lu_report.yml'],
+ 'test': [],
'demo': [],
'installable': True,
'auto_install': False,
'images': ['images/config_chart_l10n_lu.jpeg','images/l10n_lu_chart.jpeg'],
}
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/l10n_lu/test/l10n_lu_report.yml b/addons/l10n_lu/test/l10n_lu_report.yml
deleted file mode 100644
index 0ee032d581c..00000000000
--- a/addons/l10n_lu/test/l10n_lu_report.yml
+++ /dev/null
@@ -1,18 +0,0 @@
--
- It is demo data for the account.tax.code
--
- !record {model: account.tax.code, id: account_tax_code_id_r1}:
- name: a
-
--
- In order to test the PDF reports defined on a l10u_lu, we will print a VAT Report
--
- !python {model: res.partner}: |
- import os
- import openerp.report
- from openerp import tools
- data, format = openerp.report.render_report(cr, uid, [], 'l10n_lu.tax.report.print', {'model':'ir.ui.menu', 'form':{'tax_code_id': ref('account_tax_code_id_r1'), 'period_id': ref('account.period_1')}}, {})
- if tools.config['test_report_directory']:
- file(os.path.join(tools.config['test_report_directory'], 'l10n_lu-vat_report.'+format), 'wb+').write(data)
-
-
diff --git a/addons/l10n_lu/wizard/TVA_MEN_09_xxxx.pdf b/addons/l10n_lu/wizard/TVA_MEN_09_xxxx.pdf
deleted file mode 100644
index 9df4ae34065816a636cc5c4805eee2a541f7cbcc..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 384828
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%0AZ
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 SYM?AP3Wn0Tr
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