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

Polish the class MySelector.

parent 9b84dd68
...@@ -3,11 +3,7 @@ ...@@ -3,11 +3,7 @@
""" """
from reporting_tools import (MySelector, from reporting_tools import (MySelector,
Hardware, Hardware,
Person, Person)
get_header)
TIME_FIELDS = ('year', 'period_start', 'period_end')
def hardware(): def hardware():
...@@ -15,30 +11,22 @@ def hardware(): ...@@ -15,30 +11,22 @@ def hardware():
""" """
selector = MySelector(db) selector = MySelector(db)
# build the query
query = selector.query('hardware', exclude_fields=TIME_FIELDS)
if selector.period_start and selector.period_end:
q = db.hardware.start_date <= selector.period_end
q = (q) & ((db.hardware.end_date == None) | (db.hardware.end_date >= selector.period_start))
query = (query) & (q)
# define virtual field to compute time data # define virtual field to compute time data
# to be added in the report via extra columns # to be added in the report via extra columns
db.hardware.duration = Field.Virtual(Hardware(selector).duration) db.hardware.duration = Field.Virtual(Hardware(selector).duration)
# build the query
query = selector.query_active_items('hardware')
# select the records # retrieve the records
rows = db(query).select(db.hardware.ALL, rows = db(query).select(db.hardware.ALL,
db.people.ALL, db.people.ALL,
orderby=(db.hardware.model, db.people.last_name)) orderby=(db.hardware.model, db.people.last_name))
header = get_header(selector, prefix='List of hardware ') header = '%s %s' % (T('List of hardware'), selector)
return dict(footer='', return dict(footer='', header=header, rows=rows)
header=header,
rows=rows,
selector=selector)
def history(): def history():
...@@ -62,11 +50,10 @@ def history(): ...@@ -62,11 +50,10 @@ def history():
db.teams.ALL, db.teams.ALL,
orderby=(db.people.last_name, db.history.start_date)) orderby=(db.people.last_name, db.history.start_date))
header = get_header(selector, prefix='History ') header = '%s %s' % (T('History'), selector)
return dict(footer='',
header=header, return dict(footer='', header=header, rows=rows)
rows=rows,
selector=selector)
def index(): def index():
return 'List section' return 'List section'
...@@ -77,33 +64,25 @@ def people(): ...@@ -77,33 +64,25 @@ def people():
""" """
selector = MySelector(db) selector = MySelector(db)
# build the query
query = selector.query('history', exclude_fields=TIME_FIELDS)
if selector.period_start and selector.period_end:
q = db.history.start_date <= selector.period_end
q = (q) & ((db.history.end_date == None) | (db.history.end_date >= selector.period_start))
query = (query) & (q)
# avoid the category "stage"
q = db.categories.usual != 'stagiaire'
query = (query) & (q)
# define virtual field to compute time data # define virtual field to compute time data
# to be added in the report via extra columns # to be added in the report via extra columns
tool = Person(selector) tool = Person(selector)
db.history.time_coverage = Field.Virtual(tool.coverage) db.history.time_coverage = Field.Virtual(tool.coverage)
db.people.age = Field.Virtual(tool.age) db.people.age = Field.Virtual(tool.age)
# build the query avoiding the category "stage"
query = selector.query_active_items('history')
q = db.categories.usual != 'stagiaire'
query = (query) & (q)
# retrieve the records # retrieve the records
rows = db(query).select(db.categories.ALL, rows = db(query).select(db.categories.ALL,
db.history.ALL, db.history.ALL,
db.people.ALL, db.people.ALL,
orderby=(db.categories.usual, db.people.last_name)) orderby=(db.categories.usual, db.people.last_name))
header = '%s %s' % (T('List of people '), selector)
header = get_header(selector, prefix='List of people ') return dict(footer='', header=header, rows=rows)
return dict(footer='', \ No newline at end of file
header=header,
rows=rows,
selector=selector)
\ No newline at end of file
# coding: utf8 # coding: utf8
{ {
'%s between %s and %s': '%s du %s au %s',
'%s in %s': '%s en %s',
'%Y-%m-%d': '%Y-%m-%d', '%Y-%m-%d': '%Y-%m-%d',
'Age': 'Age', 'Age': 'Age',
'Agencies': 'Agencies', 'Agencies': 'Agencies',
...@@ -66,6 +68,7 @@ ...@@ -66,6 +68,7 @@
'Line': 'Ligne', 'Line': 'Ligne',
'List of hardware': 'Liste de matériel', 'List of hardware': 'Liste de matériel',
'List of people': 'Liste de personne', 'List of people': 'Liste de personne',
'List of people ': 'Liste des personnes ',
'Lists': 'Lists', 'Lists': 'Lists',
'Max Records': 'Max Records', 'Max Records': 'Max Records',
'Model': 'Modèle', 'Model': 'Modèle',
...@@ -82,9 +85,9 @@ ...@@ -82,9 +85,9 @@
'Period End': 'Period End', 'Period End': 'Period End',
'Period Start': 'Period Start', 'Period Start': 'Period Start',
'Person': 'Persone', 'Person': 'Persone',
'Phd': 'Phd',
'PHD': 'PHD', 'PHD': 'PHD',
'PhD': 'PhD', 'PhD': 'PhD',
'Phd': 'Phd',
'Phd Date': 'Phd Date', 'Phd Date': 'Phd Date',
'Phd defense date': 'Date de la soutenance de la thèse', 'Phd defense date': 'Date de la soutenance de la thèse',
'plugin not install': 'plugin not install', 'plugin not install': 'plugin not install',
......
...@@ -2,54 +2,109 @@ ...@@ -2,54 +2,109 @@
""" """
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from gluon import current
from plugin_dbui import Selector from plugin_dbui import Selector
class MySelector(Selector): class MySelector(Selector):
"""Custom version of the selector. """Custom version of the selector.
It determines the period range which can be defined in several It contains all the tools to play with the period range
different ways. which can be defined in several different ways.
The argument period_start and period_end are datetime.Date
while the year is an integer
""" """
def __init__(self, db, extfield='format'): def __init__(self, db, extfield='format'):
self.year = None
self.period_start = None
self.periode_end = None
Selector.__init__(self, db, extfield) Selector.__init__(self, db, extfield)
if 'period_start' not in self and 'period_end' not in self: if self.year:
return self.year = int(self.year)
self.period_start = date(self.year, 1, 1)
self.period_end = date(self.year, 12, 31)
if self.period_start and isinstance(self.period_start, str):
ds = datetime.strptime(self.period_start, '%Y-%m-%dT%H:%M:%S')
self.period_start = date(ds.year, ds.month, ds.day)
if self.period_end and isinstance(self.period_end, str):
de = datetime.strptime(self.period_end, '%Y-%m-%dT%H:%M:%S')
self.period_end = date(de.year, de.month, de.day)
def __str__(self):
if 'year' in self and self.year: db = self._db
self.period_start = "%s-01-01" % self.year s = ""
self.period_end = "%s-12-31" % self.year
# team and or project
if not self.id_projects and self.id_teams:
s = db.teams[self.id_teams].team
elif self.id_projects and not self.id_teams:
s = db.projects[self.id_projects].project
elif self.id_projects and self.id_teams:
s = "%s/%s" % (db.teams[self.id_teams].team,
db.projects[self.id_projects].project)
# person
if "id_people" in self and self.id_people:
s = "%s %s" % (s, db.people[self.id_people].last_name)
# time period
if self.year:
s = current.T("%s in %s") % (s, self.year)
elif self.period_start and self.period_end: elif self.period_start and self.period_end:
for field in ('period_start', 'period_end'): s = current.T("%s between %s and %s") % (s,
s = self[field] self.period_start.strftime("%d %b %Y"),
self[field] = s[:s.find('T')] self.period_end.strftime("%d %b %Y"))
return s
def query_active_items(self, tablename):
"""Build the database query for the table tablename
including inner join for foreign keys and selector constraints.
The query is tuned to selected active items during the selected
period of time. It also assume that the item has the database
field start_date and end_date.
"""
db = self._db
query = self.query(tablename, exclude_fields=('year',
'period_start',
'period_end'))
if self.period_start and self.period_end:
q = db[tablename].start_date <= self.period_end
q = (q) & ((db[tablename].end_date == None) | (db[tablename].end_date >= self.period_start))
query = (query) & (q)
return query
class Base(object): class Base(object):
"""Base class for reporting tool. """Base class for reporting tool.
The base class translate selector period fields in python date.
""" """
def __init__(self, selector): def __init__(self, selector):
now = datetime.now() now = datetime.now()
self.now = date(now.year, now.month, now.day) self.now = date(now.year, now.month, now.day)
self.period_start = None self.period_start = selector.period_start
self.period_end = None self.period_end = selector.period_end
if 'period_start' in selector:
ds = datetime.strptime(selector.period_start, '%Y-%m-%d')
self.period_start = date(ds.year, ds.month, ds.day)
if 'period_end' in selector:
de = datetime.strptime(selector.period_end, '%Y-%m-%d')
self.period_end = date(de.year, de.month, de.day)
class Hardware(Base): class Hardware(Base):
"""Tool associate to a hardware item. """Tool associate to a hardware item.
...@@ -57,7 +112,8 @@ class Hardware(Base): ...@@ -57,7 +112,8 @@ class Hardware(Base):
""" """
def duration(self, row): def duration(self, row):
"""Compute the duration of an hardware item. """Compute the duration of an hardware item.
Return a timedelta Return a datetime.TimeDelta
""" """
start = row.hardware.start_date start = row.hardware.start_date
end = row.hardware.end_date end = row.hardware.end_date
...@@ -125,44 +181,9 @@ class Person(Base): ...@@ -125,44 +181,9 @@ class Person(Base):
return timedelta return timedelta
def get_header(selector, prefix="", suffix=""):
"""Helper function returning the header for the report.
The return string contains the team, the project and some
indication on the time period:
'prefix'+'team/project in years'+'suffix'
'prefix'+'team/group between date and date'+'suffix'
The element team/project van be team, project or team/project.
"""
db = selector._db
header = ""
if not selector.id_projects and selector.id_teams:
header = db.teams[selector.id_teams].team
elif selector.id_projects and not selector.id_teams:
header = db.projects[selector.id_projects].project
elif selector.id_projects and selector.id_teams:
header = "%s/%s" % (db.teams[selector.id_teams].team,
db.projects[selector.id_projects].project)
if selector.year:
header = "%s in %s" % (header, selector.year)
elif selector.period_start and selector.period_end:
header = "%s between %s and %s" % (header,
selector.period_start,
selector.period_end)
return "%s%s%s" % (prefix, header, suffix)
def repr_timedelta(dt): def repr_timedelta(dt):
"""Helper function to convert a datetime.TimeDelta """Helper function to convert a datetime.TimeDelta
into a string 'x years y months'. into a string 'x years y months'.
""" """
ny = dt.days / 365 ny = dt.days / 365
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
HEAD HEAD
- Migrate to plugin_dbui 0.4.9 to develop filter on date. - Migrate to plugin_dbui 0.4.9 to develop filter on date.
- Add the class MySelector, Base, Hardware and Person.
- Build the list of history, hardware and people.
0.1.0 (July 2012) 0.1.0 (July 2012)
- First running version based on dbui 0.4.7.6 - First running version based on dbui 0.4.7.6
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