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

Incubator of the generic plugin_report.

parent 680376bd
......@@ -8,6 +8,7 @@ databases
databases*/
errors/
private/
*plugin_ace*
*plugin_dbui*
*plugin_extjs*
*plugin_mathjax*
......
""" List controllers
"""
from reporting_tools import (MyList,
MySelector,
from reporting_tools import (MySelector,
Base,
Person)
BASE_VIEW = 'report.%s'
def index():
""" Generate list(s) according to list definition and selector requirement
(experimental).
Handle the following URLs:
application/list/index
application/list/index?id_sqltable_configuration=2
"""
report = MyList(virtdb.my_list_selector)
iframe = report.download()
if iframe:
return iframe
if request.vars.id_sqltable_configurations:
report.id_sqltable_configurations = request.vars.id_sqltable_configurations
# response.view = "list/build_list.%s" % request.extension
return dict(report=report())
def hardware():
""" Active hardware for a given period of time, given team, ...
......
""" plugin_reports controllers
"""
import traceback
from plugin_report import MySelector, Report
def index():
""" Generate report(s) according to sqltable definition
and selector requirement (experimental).
Handle the following URLs:
application/plugin_report/index
application/plugin_report/index?id_report_objects=2
"""
# get user requirements from the selector widget
selector_name = plugins.report.selector_name
selector = MySelector(virtdb[selector_name])
iframe = selector.download()
if iframe:
return iframe
# the configuration of the table can be chosen via the URL
if request.vars.id_report_objects:
selector.id_report_objects = request.vars.id_report_objects
# instantiate the report and link it to a selector
report = Report(selector)
# build the report content
try:
report()
except BaseException, e:
msg = '<br><br><hr/>'
msg += CODE(traceback.format_exc()).xml()
msg += '<hr/>'
return msg
# give the hand to the view for the rendering
return dict(report=report)
......@@ -23,6 +23,7 @@
'auth_user': 'auth_user',
'Birth Date': 'Né le',
'budgets': 'budgets',
'can be applied on any field of the table using the SQL WHERE syntax. Be aware that foreign key are not resolved (see smart_query in the web2py)': 'can be applied on any field of the table using the SQL WHERE syntax. Be aware that foreign key are not resolved (see smart_query in the web2py)',
"Can't delete this record since several transactions refer to it.": 'Cet enregistrement ne peut pas être détruit car il est utilisé dans la table historique.',
'Cannot be empty': 'Cannot be empty',
'careers': 'carrières',
......@@ -38,6 +39,7 @@
'Code': 'Code',
'Collections': 'Collections',
'Columns': 'Colonnes',
'Conditions': 'Conditions',
'Configuration': 'Configuration',
'contains': 'contiens',
'Contract': 'Contrat',
......@@ -54,6 +56,8 @@
'Definition': 'Définition',
'Demanded': 'Demandé',
'Description': 'Description',
'Dictionary associating the column name and the column label. The dictionary is encoded as {tablename.columnname: label, ...}': 'Dictionaire associant un champ et son étiquette. The dictionaire est encodé {tablename.columnname: étiquette, ...}',
'Dictionary associating the column name and the function used to represent the field. The dictionary is encoded as {tablename.columnname: function, ...}': 'Dictionaire associant un champ et la function pour le représenté. Le dictionaire est encodé {tablename.columnname: fonction, ...}',
'documentations': 'documentations',
'Domain': 'Domaine',
'Domaine': 'Domaine',
......@@ -128,6 +132,8 @@
'Line': 'Ligne',
'lines': 'lines',
'List': 'Liste',
"List of column names separated by a comma. The column name is encoded as 'tablename.columnname.": "Liste de champs separé par une virgule. Le champ est encodé'tablename.columnname.",
'List of columns defining the order by directive: the syntax follow the web2py rules: tablename.columnname, ~tablename.columnname, ...': 'Liste de champ qui définissnet la directive order by: la syntaxe est celle de web2py: tablename.columnname, ~tablename.columnname, ...',
'List of hardware': 'Liste de matériel',
'List of people': 'Liste de personne',
'List of people ': 'Liste des personnes ',
......@@ -151,6 +157,8 @@
'My lists': 'Mes listes',
'my_lists': 'mes listes',
'Name': 'Nom',
'Name of the database table shown by the sqltable.Any fields of this table can be displayed including foreign fields.': 'Name of the database table shown by the sqltable.Any fields of this table can be displayed including foreign fields.',
'Name of the sqltable.': 'Name of the sqltable.',
'Niveau': 'Niveau',
'Note': 'Note',
'Notified': 'Notifié',
......@@ -215,6 +223,7 @@
'Start_Date': 'Start_Date',
'startswith': 'startswith',
'Store': 'Store',
'Tablename': 'Tablename',
'Tables': 'Tables',
'Team': 'Équipe',
'teams': 'équipes',
......
......@@ -94,31 +94,6 @@ db.history.id_events.requires = IS_IN_DB(db, 'events.event')
db.history.id_people.requires = IS_IN_DB(db, 'people.last_name')
db.history.trainee_category.requires = IS_IN_USET((undef, 'PHY', 'IR'))
tp_list = "Name of the list."
tp_columns = "List of column names separated by a comma. " \
"The column name is encoded as 'tablename.columnname."
tp_headers = "Dictionary associating the column name and the column header. " \
"The dictionary is encoded as {tablename.columnname: header, ...}"
tp_formats = "Dictionary associating the column name and the format fucntion. " \
"The dictionary is encoded as {tablename.columnname: function, ...}"
tp_orderby = "List of columns defining the order by directive: " \
"tablename.columnname, ~tablename.columnname, ..."
db.define_table("my_lists",
Field("list", "string", notnull=True, unique=True, comment=tp_list),
Field("id_events", "reference events", default=undef_id, label='Event'),
Field("columns", "text", notnull=True, comment=tp_columns),
Field("headers", "text", comment=tp_headers),
Field("formats", "text", comment=tp_formats),
Field("orderby", "text", comment=tp_orderby),
Field("note", "text"),
migrate="my_lists.table")
db.define_table("organizations",
Field("organization", "string", notnull=True, unique=True),
Field("definition", "text"),
......
# -*- coding: utf-8 -*-
""" db
Defined the database tables for the sqltables (reports)
"""
tp_name = "Name of the sqltable."
tp_columns = "List of column names separated by a comma. " \
"The column name is encoded as 'tablename.columnname."
tp_formats = "Dictionary associating the column name and the format fucntion. " \
"The dictionary is encoded as {tablename.columnname: function, ...}"
tp_labels = "Dictionary associating the column name and the column header. " \
"The dictionary is encoded as {tablename.columnname: header, ...}"
tp_orderby = "List of columns defining the order by directive: " \
"tablename.columnname, ~tablename.columnname, ..."
db.define_table("sqltable_configurations",
Field("sqltable", "string", notnull=True, unique=True, comment=tp_list),
Field("id_events", "reference events", default=undef_id, label='Event'),
Field("columns", "text", notnull=True, comment=tp_columns),
Field("labels", "text", comment=tp_labels),
Field("formats", "text", comment=tp_formats),
Field("orderby", "text", comment=tp_orderby),
Field("note", "text"),
migrate="sqltable_configurations.table")
func_code = "def repr_xxx(value, row):\n"\
" return value\n"
db.define_table("sqltable_functions",
Field("function", "string", default= "repr_xxx", notnull=True, unique=True),
Field("python_code", "text", default=func_code),
migrate="sqltable_functions.table")
virtualfield_code = "def xxx(row):\n"\
" return None\n"
db.define_table("sqltable_virtualfields",
Field("field", "string", notnull=True, unique=True),
Field("python_code", "text", default=virtualfield_code),
migrate="sqltable_virtualfields.table")
# -*- coding: utf-8 -*-
""" plugin_report
Define the plugin constants
Define the database tables to configure the reports.
Customize the table interface
"""
from plugin_report import SET_NAME
#-------------------------------------------------------------------------------
#
# plugin constants -- Default value
#
#-------------------------------------------------------------------------------
plugins = PluginManager('report',
selector_name="my_list_selector")
#-------------------------------------------------------------------------------
#
# report tables
#
#-------------------------------------------------------------------------------
#
# report_functions
#
func_code = "def repr_xxx(value, row):\n"\
" return value\n"
db.define_table("report_functions",
Field("function", "string", default= "repr_xxx", notnull=True, unique=True),
Field("python_code", "text", default=func_code),
Field("tests", "text", notnull=True, default='Not yet implemented'),
migrate="report_functions.table")
db.report_functions._before_insert.append(SET_NAME("function"))
db.report_functions._before_update.append(SET_NAME("function"))
#
# report_objects
#
tp_alignments = \
T("Dictionary associating a column and its alignment (left, center, right). "
"The key is a column name encoded as tablename.fieldname ")
tp_columns = \
T("List of column to be displayed in the table. "
"The column is identified by its name encoded as 'tablename.fieldname. "
"The column can contains a virtual field 'tablename.virtualfield. "
"The function associated to the virtual field has to be defined in "
"the database table report_virtual_fields. "
"The column can contains the operator AVG, COUNT, MIN, MAX and SUM. "
"In that case the syntax is operator(tablename.fieldname. "
"The operator make sense with the group by directive. ")
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_formats = \
T("Dictionary associating the column and the function "
"used to represent the field. "
"The key is a column name encoded as tablename.fieldname "
"or operator(tablename.fieldname) ."
"The value is a name of the function defined in the table report_functions.")
tp_groupby = \
T("List of columns defining the group by directive. "
"The column is encode as 'tablename.fiedlname. ")
tp_labels = \
T("Dictionary associating the column name with the column label. "
"The key is a column name encoded as tablename.fieldname. "
"The value is a string.")
tp_name = T("Name of the object.")
tp_orderby = \
T("List of columns defining the order by directive. "
"The column is identified by its name encoded as tablename.fieldname. "
"Descending order are obtained using the syntax ~tablename.fieldname.")
tp_table = \
T("Name of the database table which will be displayed in the report. "
"Any fields of this table can be shown including foreign fields.")
tp_totals = \
T("List of columns appearing in the total row. "
"The column names are encoded as 'tablename.fieldname' "
"or 'operator(tablename.fieldname)'. ")
db.define_table("report_objects",
Field("name", "string", notnull=True, unique=True, comment=tp_name),
Field("type", "string", notnull=True, default='sqltable'),
Field("tablename", "string", notnull=True, comment=tp_table),
Field("conditions", "text", comment=tp_conditions),
Field("columns", "list:string", notnull=True, comment=tp_columns),
Field("labels", "json", comment=tp_labels),
Field("formats", "json", comment=tp_formats),
Field("alignments", "json", comment=tp_alignments),
Field("orderby", "list:string", comment=tp_orderby),
Field("groupby", "list:string", comment=tp_groupby),
Field("totals", "list:string", comment=tp_totals),
Field("note", "text"),
migrate="report_objects.table")
db.report_objects.tablename.requires = IS_IN_SET(db.tables())
db.report_objects.type.requires = IS_IN_SET(('sqltable',))
# NOTE in web2py 2.4.6 the validator for JSON field is not working
db.report_objects.alignments.requires = None
db.report_objects.formats.requires = None
db.report_objects.labels.requires = None
#
# report_virtualfields
#
virtualfield_code = "def xxx(row):\n"\
" return None\n"
db.define_table("report_virtualfields",
Field("field", "string", default="xxx", notnull=True, unique=True),
Field("python_code", "text", default=virtualfield_code),
Field("tests", "text", notnull=True, default='Not yet implemented'),
migrate="report_virtualfields.table")
db.report_virtualfields._before_insert.append(SET_NAME("field"))
db.report_virtualfields._before_update.append(SET_NAME("field"))
#-------------------------------------------------------------------------------
#
# report fields configuration
#
#-------------------------------------------------------------------------------
#
# report_functions
#
fieldsModifier = dbui.FieldsModifier('report_functions')
fieldsModifier.configure_field('function', hidden=True)
fieldsModifier.configure_field('python_code', height=230,
hideLabel=True,
xtype='xaceeditorfield')
fieldsModifier.configure_field('tests', hidden=True)
#
# report_objects
#
fieldsModifier = dbui.FieldsModifier('report_objects')
fieldsModifier.configure_field('columns', header='tablename.fieldname',
height=197,
hideLabel=True,
minimumRows=8)
fieldsModifier.configure_field('conditions', height=120)
fieldsModifier.configure_field('labels', dictCfg={},
headers=['tablename.fieldname', 'label'],
height=197,
hideLabel=True,
modifyKeys=True)
fieldsModifier.configure_field('formats', dictCfg={},
headers=['tablename.fieldname', 'function'],
height=197,
hideLabel=True,
modifyKeys=True)
fieldsModifier.configure_field('alignments', dictCfg={},
headers=['tablename.fieldname', 'alignment'],
height=197,
hideLabel=True,
modifyKeys=True)
fieldsModifier.configure_field('orderby', header='tablename.fieldname',
height=197,
hideLabel=True,
minimumRows=8)
fieldsModifier.configure_field('groupby', header='tablename.fieldname',
height=197,
hideLabel=True,
minimumRows=8)
fieldsModifier.configure_field('totals', header='tablename.fieldname',
height=197,
hideLabel=True,
minimumRows=8)
fieldsModifier.configure_field('note', height=197, hideLabel=True)
#
# report_virtualfields
#
fieldsModifier = dbui.FieldsModifier('report_virtualfields')
fieldsModifier.configure_field('field', hidden=True)
fieldsModifier.configure_field('python_code', height=230,
hideLabel=True,
xtype='xaceeditorfield')
fieldsModifier.configure_field('tests', hidden=True)
#-------------------------------------------------------------------------------
#
# report forms configuration
#
#-------------------------------------------------------------------------------
#
# report_functions
#
formModifier = dbui.FormModifier('report_functions')
formModifier.configure(buttonAlign='right',
width=605,
height=300)
#
# report_objects
#
formModifier = dbui.FormModifier('report_objects')
formModifier.merge_fields('name',
'type',
'tablename',
'conditions',
dbui.Spacer(height=45),
title=T('General'),
flex=1)
formModifier.merge_fields('columns',
title=T('Columns'),
flex=1)
formModifier.merge_fields('labels',
title=T('Labels'),
flex=1)
formModifier.merge_fields('formats',
title=T('Formats'),
flex=1)
formModifier.merge_fields('alignments',
title=T('Alignments'),
flex=1)
formModifier.merge_fields('orderby',
title=T('Order by'),
flex=1)
formModifier.merge_fields('groupby',
title=T('Group by'),
flex=1)
formModifier.merge_fields('totals',
title=T('Total Row'),
flex=1)
formModifier.merge_fields('note',
dbui.Spacer(height=128),
title=T('Note'),
flex=1)
formModifier.set_mapper(dbui.map_tabpanel)
formModifier.configure(buttonAlign='right',
labelWidth=70,
labelAlign='left',
width=400,
height=305,
defaults={'height': 245})
#
# report_virtualfields
#
formModifier = dbui.FormModifier('report_virtualfields')
formModifier.configure(buttonAlign='right',
width=605,
height=300)
#-------------------------------------------------------------------------------
#
# report grids configuration
#
#-------------------------------------------------------------------------------
#
# report_functions
#
gridModifier = dbui.GridModifier('report_functions')
gridModifier.configure(stripeRows=True)
gridModifier.hide_columns('python_code', 'tests')
gridModifier.set_rownumbering()
#
# report_objects
#
gridModifier = dbui.GridModifier('report_objects')
gridModifier.configure(stripeRows=True)
gridModifier.configure_column('tablename', width=30)
gridModifier.configure_column('type', width=30)
gridModifier.hide_columns('alignments',
'columns',
'formats',
'groupby',
'labels',
'orderby',
'totals')
gridModifier.set_rownumbering()
#
# report_virtualfields
#
gridModifier = dbui.GridModifier('report_virtualfields')
gridModifier.configure(stripeRows=True)
gridModifier.hide_columns('python_code', 'tests')
gridModifier.set_rownumbering()
......@@ -71,18 +71,20 @@ virtdb.define_table('my_list_selector',
Field('id_projects', 'reference projects', label=T('Project')),
Field('category', 'string'),
Field('id_people_categories', 'reference people_categories', label= T("Quality")),
Field('id_sqltable_configurations', 'reference sqltable_configurations', label=T('List')),
Field('id_report_objects', 'reference report_objects', label=T('List')),
Field('id_events', 'reference events', label=T('Event')),
Field('format', 'string', default='html'))
virtdb.my_list_selector.category.requires = IS_IN_SET((el.category for el in categories))
virtdb.my_list_selector.id_people_categories.requires = IS_IN_DB(db, 'people_categories.code')
virtdb.my_list_selector.id_events.requires = IS_IN_DB(db, 'events.event')
virtdb.my_list_selector.id_people.requires = IS_IN_DB(db, 'people.last_name')
virtdb.my_list_selector.id_projects.requires = IS_IN_DB(db, 'projects.project')
virtdb.my_list_selector.id_teams.requires = IS_IN_DB(db, 'teams.team')
virtdb.my_list_selector.id_sqltable_configurations.requires = \
IS_IN_DB(db, 'sqltable_configurations.sqltable')
virtdb.my_list_selector.id_report_objects.requires = \
IS_IN_DB(db, 'report_objects.name')
virtdb.my_list_selector.format.requires = IS_IN_SET(FORMATS)
......
......@@ -37,21 +37,11 @@ fieldsModifier.configure_field('period_start', flex=1)
fieldsModifier.configure_field('period_end', flex=1)
fieldsModifier.merge_fields('period_start', 'period_end', fieldLabel=T('Period'))
#
# my lists
#
fieldsModifier = dbui.FieldsModifier('my_lists')
fieldsModifier.configure_field('columns', height=140)
fieldsModifier.configure_field('headers', height=190, hideLabel=True)
fieldsModifier.configure_field('formats', height=190, hideLabel=True)
fieldsModifier.configure_field('orderby', height=190, hideLabel=True)
fieldsModifier.configure_field('note', height=190, hideLabel=True)
#
# my list selector
#
fieldsModifier = dbui.FieldsModifier('my_list_selector')
fieldsModifier.configure_field('id_sqltable_configurations', hidden=True)
fieldsModifier.configure_field('id_report_objects', hidden=True)
fieldsModifier.configure_field('id_people', editable='false', mode='local')
fieldsModifier.configure_field('period_start', flex=1)
fieldsModifier.configure_field('period_end', flex=1)
......@@ -74,28 +64,6 @@ fieldsModifier.configure_field('period_start', flex=1)
fieldsModifier.configure_field('period_end', flex=1)
fieldsModifier.merge_fields('period_start', 'period_end', fieldLabel=T('Period'))
#
# sqltable_configurations
#
fieldsModifier = dbui.FieldsModifier('sqltable_configurations')
fieldsModifier.configure_field('columns', height=140)
fieldsModifier.configure_field('labels', height=190, hideLabel=True)
fieldsModifier.configure_field('formats', height=190, hideLabel=True)
fieldsModifier.configure_field('orderby', height=190, hideLabel=True)
fieldsModifier.configure_field('note', height=190, hideLabel=True)
#
# sqltable_functions
#
fieldsModifier = dbui.FieldsModifier('sqltable_functions')
fieldsModifier.configure_field('python_code', height=215, hideLabel=True)