Commit a47250c7 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

More general approach in which the structure of the grid is defined only

once in the database table view. Then  the ArrayStore is build accordingly.
parent 7a2f77ba
......@@ -12,7 +12,7 @@ import json
from datetime import date, timedelta
from gluon.dal import smart_query
from import Storage
from reporting_tools2 import Report, repr_duration
from reporting_tools2 import Report, repr_duration, to_dataFields
def list():
......@@ -43,22 +43,7 @@ def list():
cfg = dict()
cfg['data'] = []
cfg['fields'] = [{'name': 'people.age', 'type': 'int'},
{'name': 'people_categories.category', 'type': 'string'},
{'name': 'history.cdd_flag', 'type': 'boolean'},
{'name': 'history.coverage', 'type': 'float'},
{'name': 'history.duration', 'type': 'string'},
{'name': 'history.end_date', 'type': 'date', 'dateFormat': 'Y-m-d'},
{'name': 'events.event', 'type': 'string'},
{'name': 'history.fte', 'type': 'float'},
{'name': 'people.last_name', 'type': 'string'},
{'name': 'history.note', 'type': 'string'},
{'name': 'history.is_over', 'type': 'boolean'},
{'name': 'history.percentage', 'type': 'float'},
{'name': 'projects.project', 'type': 'string'},
{'name': 'people_categories.code', 'type': 'string'},
{'name': 'history.start_date', 'type': 'date', 'dateFormat': 'Y-m-d'},
{'name': '', 'type': 'string'}]
cfg['fields'] = to_dataFields(view.columns)
if view.group_field:
cfg['groupField'] = view.group_field
......@@ -67,29 +52,22 @@ def list():
cfg['sorters'] = view.sorters
# fill the data block
# It is mandatory to preserve the data fields order
for row in
end = row.history.end_date
start = row.history.start_date
# build the row
li = [row.people.age,
(end.strftime("%Y-%m-%d") if end else ""),,
(start.strftime("%Y-%m-%d") if start else ""),]
li = []
for field in cfg['fields']:
value = row[field['name']]
if isinstance(value, date):
value = value.strftime("%Y-%m-%d")
elif isinstance(value, timedelta):
value = value.total_seconds()
return dict(cfg_store=cfg, view=view)
......@@ -4,6 +4,8 @@
'%s in %s': '%s en %s',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'A list of Ext.grid.column.Column configuration.': "liste de configuration d'Ext.grid.column.Column.",
'A list of Ext.grid.feature.Feature configuration.': "list de configuration d'Ext.grid.feature.Feature.",
'about': 'à propos',
'Add a new history line %i': 'Add a new history line %i',
'Add a new person successfully': 'Une nouvelle personne a été ajouté',
......@@ -60,6 +62,7 @@
'Created By': 'Created By',
'Created On': 'Created On',
'Data people': 'Les données des personnes',
'Database field encoded as tablename.fieldname.': 'Champ de la base de donnée encodé tablename.fieldname.',
'database schema': 'schéma de la base de données',
'Defined a year or a time period !!!': 'Defined a year or a time period !!!',
'Definition': 'Définition',
......@@ -2,15 +2,19 @@
""" views
tp_columns = \
T("A list of Ext.grid.column.Column configuration.")
tp_conditions = \
T("Can be applied on any field of the table using the SQL WHERE syntax. "
"Be aware that foreign key are not resolved "
"(more information in the smart_query in the web2py documentation).")
tp_features = \
T("A list of Ext.grid.feature.Feature configuration.")
tp_fields = \
"""The available fields are:
age, category, cdd, coverage, duration, end, event, fte, name, note,
percentage, project, quality, start, team."""
T("Database field encoded as tablename.fieldname.")
def_columns = \
"[{xtype: 'rownumberer'},\n{text: '', dataIndex: '', flex:1}]"
......@@ -24,6 +28,6 @@ db.define_table("views",
Field("conditions", "text", comment=tp_conditions),
Field("group_field", "string", length=255, comment=tp_fields),
Field("sorters", "list:string", comment=tp_fields),
Field("columns", "text", default=def_columns, comment=tp_fields, notnull=True),
Field("features", "text", default=def_features, comment=tp_fields),
Field("columns", "text", default=def_columns, comment=tp_columns, notnull=True),
Field("features", "text", default=def_features, comment=tp_features),
"""reporting tools module
import re
from datetime import date, timedelta
from gluon import current
from gluon.dal import Field
......@@ -30,6 +33,63 @@ def repr_duration(value):
return ''
def to_dataFields(cfg_columns):
"""Convert the cfg_columns configuration for and Ext.grid.Panel
into a fields configuration for an
@type cfg_columns: str
@param cfg_columns: a list of Ext.grid.column.Column configuration
encoded into a string.
@rtype: list of dictionary
@return: a list of configuration
li = []
db = current.globalenv['db']
# extract the list of database field names from the column configuration
columns = re.findall("dataIndex *: *'([a-z_\.]+)'", cfg_columns)
# convert the database field into and
for column in columns:
cfg = dict()
cfg['name'] = column
tablename, fieldname = column.split('.')
field = db[tablename][fieldname]
cfg['type'] = field.type
if field.type in ('string', 'text', 'json'):
cfg['type'] = 'string'
elif field.type == 'date':
cfg['type'] = 'date'
cfg['dateFormat'] = 'Y-m-d'
elif field.type == 'datetime':
cfg['type'] = 'date'
cfg['dateFormat'] = 'Y-m-d H:i:s'
elif field.type == 'double':
cfg['type'] = 'float'
elif field.type == 'integer':
cfg['type'] = 'int'
elif field.type == 'time':
cfg['type'] = 'date'
cfg['dateFormat'] = 'H:i:s'
cfg['type'] = field.type
return li
class SelectorActiveItems(Selector):
"""Selector to get records active during a given period of time.
......@@ -125,11 +185,11 @@ class Report(SelectorActiveItems):
# add virtual fields
db = current.globalenv['db']
db.people.age = Field.Virtual('age', self._age)
db.history.coverage = Field.Virtual('coverage', self._coverage)
db.history.duration = Field.Virtual('duration', self._duration)
db.history.fte = Field.Virtual('fte', self._fte)
db.history.is_over = Field.Virtual('is_over', self._is_over)
db.people.age = Field.Virtual('age', self._age, ftype='integer')
db.history.coverage = Field.Virtual('coverage', self._coverage, ftype='double')
db.history.duration = Field.Virtual('duration', self._duration, ftype='double')
db.history.fte = Field.Virtual('fte', self._fte, ftype='double')
db.history.is_over = Field.Virtual('is_over', self._is_over, ftype='boolean')
def _age(self, row):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment