changeset 327:cdce64340e6c

Apply field definition overlays
author Sylvain Beucler <beuc@beuc.net>
date Sat, 21 Aug 2010 18:17:00 +0200
parents f34eba406e57
children 91a6a6c540d4
files doc/scripts/tracker_defsgen.py savane/tracker/defs.py savane/tracker/models.py
diffstat 3 files changed, 275 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/doc/scripts/tracker_defsgen.py
+++ b/doc/scripts/tracker_defsgen.py
@@ -14,14 +14,16 @@
 
 defs = {}
 field_names = []
-c.execute("""SELECT * FROM bugs_field""")
+complex_defs = {}
+
 def process_field_row(row):
     name = row[1]
     field_names.append(name)
     defs[name] = ''
     defs[name] += "    '"+name+"' : {\n"
     for i,val in enumerate(row):
-        if i <= 0:
+        if i <= 0 \
+                or (complex_defs[name]['display_type'] not in ('TA', 'TF') and tfields[i] == 'display_size'):
             continue
         else:
             defs[name] += "        " \
@@ -45,10 +47,29 @@
                 defs[name] += "'"+val+"',"
             defs[name] += "\n"
 
+query = """SELECT * FROM bugs_field"""
+c.execute(query)
+for row in c.fetchall():
+    name = row[1]
+    complex_defs[name] = {}
+    for i,val in enumerate(row):
+        complex_defs[name][tfields[i]] = val
+complex_defs['priority']['required'] = 0
+complex_defs['resolution_id']['required'] = 0
+c.execute(query)
 for row in c.fetchall():
     process_field_row(row)
 
-c.execute("""SELECT * FROM task_field WHERE field_name IN ('planned_starting_date', 'planned_close_date')""")
+query = """SELECT * FROM task_field WHERE field_name IN ('planned_starting_date', 'planned_close_date')"""
+c.execute(query)
+for row in c.fetchall():
+    name = row[1]
+    complex_defs[name] = {}
+    for i,val in enumerate(row):
+        complex_defs[name][tfields[i]] = val
+complex_defs['planned_starting_date']['required'] = 0
+complex_defs['planned_close_date']['required'] = 0
+c.execute(query)
 for row in c.fetchall():
     process_field_row(row)
 
@@ -64,12 +85,10 @@
            'custom_description','custom_display_size',
            'custom_empty_ok','custom_keep_history',
            'transition_default_auth']
-c.execute("""SELECT bugs_field.field_name,bugs_field_usage.*
-  FROM bugs_field_usage JOIN bugs_field USING (bug_field_id) WHERE group_id=100""")
+tfields[6] = 'rank' 
+
 def process_field_usage_row(row):
     name = row[0]
-    if name == 'place':
-        name = 'rank'
     for i,val in enumerate(row):
         if i <= 2:
             continue
@@ -78,6 +97,8 @@
                 or tfields[i] == 'custom_display_size' \
                 or tfields[i] == 'custom_empty_ok' \
                 or tfields[i] == 'custom_keep_history' \
+                or (complex_defs[name]['required'] == 1 and tfields[i] == 'use_it') \
+                or (complex_defs[name]['display_type'] != 'SB' and tfields[i] == 'transition_default_auth') \
                 :
             # overlays, duplicates of bugs_field in this context
             continue
@@ -106,13 +127,18 @@
                 defs[name] += "'"+val+"',"
             defs[name] += "\n"
     defs[name] += "    },\n"
+
+c.execute("""SELECT bugs_field.field_name,bugs_field_usage.*
+  FROM bugs_field_usage JOIN bugs_field USING (bug_field_id) WHERE group_id=100""")
 for row in c.fetchall():
     process_field_usage_row(row)
+
 c.execute("""SELECT task_field.field_name,task_field_usage.*
   FROM task_field_usage JOIN task_field USING (bug_field_id) WHERE group_id=100
   AND field_name IN ('planned_starting_date', 'planned_close_date')""")
 for row in c.fetchall():
     process_field_usage_row(row)
 
+
 for name in field_names:
     print defs[name],
--- a/savane/tracker/defs.py
+++ b/savane/tracker/defs.py
@@ -64,8 +64,9 @@
 """
 
 from django.utils.translation import ugettext, ugettext_lazy as _
+from copy import deepcopy
 
-fields = {}
+default_fields = {}
 
 common = {
     'bug_id' : {
@@ -80,12 +81,10 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 10,
-        'transition_default_auth': 'A',
+        'rank': 10,
     },
     'group_id' : {
         'field_name': 'group_id',
@@ -99,17 +98,14 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 30,
-        'transition_default_auth': 'A',
+        'rank': 30,
     },
     'submitted_by' : {
         'field_name': 'submitted_by',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Submitted by"),
         'description': _("User who originally submitted the item"),
         'scope': 'S',
@@ -118,17 +114,15 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 20,
+        'rank': 20,
         'transition_default_auth': 'A',
     },
     'date' : {
         'field_name': 'date',
         'display_type': 'DF',
-        'display_size': '10/15',
         'label': _("Submitted on"),
         'description': _("Date and time of the initial submission"),
         'scope': 'S',
@@ -137,17 +131,14 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40,
-        'transition_default_auth': 'A',
+        'rank': 40,
     },
     'close_date' : {
         'field_name': 'close_date',
         'display_type': 'DF',
-        'display_size': '10/15',
         'label': _("Closed on"),
         'description': _("Date and time when the item  status was changed to 'Closed'"),
         'scope': 'S',
@@ -156,17 +147,14 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50,
-        'transition_default_auth': 'A',
+        'rank': 50,
     },
     'status_id' : {
         'field_name': 'status_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Open/Closed"),
         'description': _("Most basic status"),
         'scope': 'S',
@@ -175,17 +163,15 @@
         'keep_history': 1,
         'special': 0,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 600,
+        'rank': 600,
         'transition_default_auth': 'A',
     },
     'severity' : {
         'field_name': 'severity',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Severity"),
         'description': _("Impact of the item on the system (Critical, Major,...)"),
         'scope': 'S',
@@ -195,16 +181,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 200,
+        'rank': 200,
         'transition_default_auth': 'A',
     },
     'category_id' : {
         'field_name': 'category_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Category"),
         'description': _("Generally high level modules or functionalities of the software (e.g. User interface, Configuration Manager, etc)"),
         'scope': 'P',
@@ -214,16 +199,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 100,
+        'rank': 100,
         'transition_default_auth': 'A',
     },
     'assigned_to' : {
         'field_name': 'assigned_to',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Assigned to"),
         'description': _("Who is in charge of handling this item"),
         'scope': 'S',
@@ -232,11 +216,10 @@
         'keep_history': 1,
         'special': 0,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 500,
+        'rank': 500,
         'transition_default_auth': 'A',
     },
     'summary' : {
@@ -251,12 +234,10 @@
         'keep_history': 1,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 700000,
-        'transition_default_auth': 'A',
+        'rank': 700000,
     },
     'details' : {
         'field_name': 'details',
@@ -270,17 +251,14 @@
         'keep_history': 1,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 700001,
-        'transition_default_auth': 'A',
+        'rank': 700001,
     },
     'bug_group_id' : {
         'field_name': 'bug_group_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Item Group"),
         'description': _("Characterizes the nature of the item (e.g. Crash Error, Documentation Typo, Installation Problem, etc"),
         'scope': 'P',
@@ -290,16 +268,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 300,
+        'rank': 300,
         'transition_default_auth': 'A',
     },
     'resolution_id' : {
         'field_name': 'resolution_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Status"),
         'description': _("Current resolution of the item"),
         'scope': 'P',
@@ -309,16 +286,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 400,
+        'rank': 400,
         'transition_default_auth': 'A',
     },
     'privacy' : {
         'field_name': 'privacy',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Privacy"),
         'description': _("Determines whether the item can be seen by members of the project only or anybody."),
         'scope': 'S',
@@ -328,10 +304,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 402,
+        'rank': 402,
         'transition_default_auth': 'A',
     },
     'vote' : {
@@ -347,16 +323,14 @@
         'special': 1,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 405,
-        'transition_default_auth': 'A',
+        'rank': 405,
     },
     'category_version_id' : {
         'field_name': 'category_version_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Component Version"),
         'description': _("Version of the System Component (aka Item Category) impacted by the item"),
         'scope': 'P',
@@ -366,16 +340,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1000,
+        'rank': 1000,
         'transition_default_auth': 'A',
     },
     'platform_version_id' : {
         'field_name': 'platform_version_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Operating System"),
         'description': _("Operating System impacted by the issue"),
         'scope': 'P',
@@ -385,16 +358,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1100,
+        'rank': 1100,
         'transition_default_auth': 'A',
     },
     'reproducibility_id' : {
         'field_name': 'reproducibility_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Reproducibility"),
         'description': _("How easy it is to reproduce the item"),
         'scope': 'S',
@@ -404,16 +376,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1200,
+        'rank': 1200,
         'transition_default_auth': 'A',
     },
     'size_id' : {
         'field_name': 'size_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Size (loc)"),
         'description': _("Estimated size of the code to be developed or reworked to fix the item"),
         'scope': 'S',
@@ -423,16 +394,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1300,
+        'rank': 1300,
         'transition_default_auth': 'A',
     },
     'fix_release_id' : {
         'field_name': 'fix_release_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Fixed Release"),
         'description': _("Release in which the item was actually fixed"),
         'scope': 'P',
@@ -442,16 +412,15 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1400,
+        'rank': 1400,
         'transition_default_auth': 'A',
     },
     'comment_type_id' : {
         'field_name': 'comment_type_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Comment Type"),
         'description': _("Specify the nature of the follow up comment attached to this item"),
         'scope': 'P',
@@ -460,11 +429,10 @@
         'keep_history': 0,
         'special': 1,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1500,
+        'rank': 1500,
         'transition_default_auth': 'A',
     },
     'hours' : {
@@ -480,16 +448,14 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1700,
-        'transition_default_auth': 'A',
+        'rank': 1700,
     },
     'plan_release_id' : {
         'field_name': 'plan_release_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Planned Release"),
         'description': _("Release in which it is planned to have the item fixed"),
         'scope': 'P',
@@ -499,10 +465,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1600,
+        'rank': 1600,
         'transition_default_auth': 'A',
     },
     'component_version' : {
@@ -518,11 +484,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1800,
-        'transition_default_auth': 'A',
+        'rank': 1800,
     },
     'fix_release' : {
         'field_name': 'fix_release',
@@ -537,11 +502,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 1900,
-        'transition_default_auth': 'A',
+        'rank': 1900,
     },
     'plan_release' : {
         'field_name': 'plan_release',
@@ -556,16 +520,14 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 2000,
-        'transition_default_auth': 'A',
+        'rank': 2000,
     },
     'priority' : {
         'field_name': 'priority',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Priority"),
         'description': _("How quickly the item should be handled"),
         'scope': 'S',
@@ -575,10 +537,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 200,
+        'rank': 200,
         'transition_default_auth': 'A',
     },
     'keywords' : {
@@ -594,16 +556,14 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 3000,
-        'transition_default_auth': 'A',
+        'rank': 3000,
     },
     'release_id' : {
         'field_name': 'release_id',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Release"),
         'description': _("Release (global version number) impacted by the item"),
         'scope': 'P',
@@ -613,10 +573,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 800,
+        'rank': 800,
         'transition_default_auth': 'A',
     },
     'release' : {
@@ -632,11 +592,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 800,
-        'transition_default_auth': 'A',
+        'rank': 800,
     },
     'originator_name' : {
         'field_name': 'originator_name',
@@ -651,11 +610,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 550,
-        'transition_default_auth': 'A',
+        'rank': 550,
     },
     'originator_email' : {
         'field_name': 'originator_email',
@@ -670,11 +628,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 1,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 1,
         'show_on_add_members': 0,
-        'place': 560,
-        'transition_default_auth': 'A',
+        'rank': 560,
     },
     'originator_phone' : {
         'field_name': 'originator_phone',
@@ -689,16 +646,14 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 570,
-        'transition_default_auth': 'A',
+        'rank': 570,
     },
     'percent_complete' : {
         'field_name': 'percent_complete',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Percent Complete"),
         'description': _(""),
         'scope': 'S',
@@ -708,10 +663,10 @@
         'special': 0,
         'custom': 0,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 500,
+        'rank': 500,
         'transition_default_auth': 'A',
     },
     'custom_tf1' : {
@@ -727,11 +682,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30000,
-        'transition_default_auth': 'A',
+        'rank': 30000,
     },
     'custom_tf2' : {
         'field_name': 'custom_tf2',
@@ -746,11 +700,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30100,
-        'transition_default_auth': 'A',
+        'rank': 30100,
     },
     'custom_tf3' : {
         'field_name': 'custom_tf3',
@@ -765,11 +718,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30200,
-        'transition_default_auth': 'A',
+        'rank': 30200,
     },
     'custom_tf4' : {
         'field_name': 'custom_tf4',
@@ -784,11 +736,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30300,
-        'transition_default_auth': 'A',
+        'rank': 30300,
     },
     'custom_tf5' : {
         'field_name': 'custom_tf5',
@@ -803,11 +754,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30400,
-        'transition_default_auth': 'A',
+        'rank': 30400,
     },
     'custom_tf6' : {
         'field_name': 'custom_tf6',
@@ -822,11 +772,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30500,
-        'transition_default_auth': 'A',
+        'rank': 30500,
     },
     'custom_tf7' : {
         'field_name': 'custom_tf7',
@@ -841,11 +790,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30600,
-        'transition_default_auth': 'A',
+        'rank': 30600,
     },
     'custom_tf8' : {
         'field_name': 'custom_tf8',
@@ -860,11 +808,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30700,
-        'transition_default_auth': 'A',
+        'rank': 30700,
     },
     'custom_tf9' : {
         'field_name': 'custom_tf9',
@@ -879,11 +826,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30800,
-        'transition_default_auth': 'A',
+        'rank': 30800,
     },
     'custom_tf10' : {
         'field_name': 'custom_tf10',
@@ -898,11 +844,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 30900,
-        'transition_default_auth': 'A',
+        'rank': 30900,
     },
     'custom_ta1' : {
         'field_name': 'custom_ta1',
@@ -917,11 +862,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40000,
-        'transition_default_auth': 'A',
+        'rank': 40000,
     },
     'custom_ta2' : {
         'field_name': 'custom_ta2',
@@ -936,11 +880,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40100,
-        'transition_default_auth': 'A',
+        'rank': 40100,
     },
     'custom_ta3' : {
         'field_name': 'custom_ta3',
@@ -955,11 +898,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40200,
-        'transition_default_auth': 'A',
+        'rank': 40200,
     },
     'custom_ta4' : {
         'field_name': 'custom_ta4',
@@ -974,11 +916,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40300,
-        'transition_default_auth': 'A',
+        'rank': 40300,
     },
     'custom_ta5' : {
         'field_name': 'custom_ta5',
@@ -993,11 +934,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40400,
-        'transition_default_auth': 'A',
+        'rank': 40400,
     },
     'custom_ta6' : {
         'field_name': 'custom_ta6',
@@ -1012,11 +952,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40500,
-        'transition_default_auth': 'A',
+        'rank': 40500,
     },
     'custom_ta7' : {
         'field_name': 'custom_ta7',
@@ -1031,11 +970,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40600,
-        'transition_default_auth': 'A',
+        'rank': 40600,
     },
     'custom_ta8' : {
         'field_name': 'custom_ta8',
@@ -1050,11 +988,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40700,
-        'transition_default_auth': 'A',
+        'rank': 40700,
     },
     'custom_ta9' : {
         'field_name': 'custom_ta9',
@@ -1069,11 +1006,10 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40800,
-        'transition_default_auth': 'A',
+        'rank': 40800,
     },
     'custom_ta10' : {
         'field_name': 'custom_ta10',
@@ -1088,16 +1024,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 40900,
-        'transition_default_auth': 'A',
+        'rank': 40900,
     },
     'custom_sb1' : {
         'field_name': 'custom_sb1',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #1"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1107,16 +1041,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50000,
+        'rank': 50000,
         'transition_default_auth': 'A',
     },
     'custom_sb2' : {
         'field_name': 'custom_sb2',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #2"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1126,16 +1059,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50100,
+        'rank': 50100,
         'transition_default_auth': 'A',
     },
     'custom_sb3' : {
         'field_name': 'custom_sb3',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #3"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1145,16 +1077,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50200,
+        'rank': 50200,
         'transition_default_auth': 'A',
     },
     'custom_sb4' : {
         'field_name': 'custom_sb4',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #4"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1164,16 +1095,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50300,
+        'rank': 50300,
         'transition_default_auth': 'A',
     },
     'custom_sb5' : {
         'field_name': 'custom_sb5',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #5"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1183,16 +1113,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50400,
+        'rank': 50400,
         'transition_default_auth': 'A',
     },
     'custom_sb6' : {
         'field_name': 'custom_sb6',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #6"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1202,16 +1131,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50500,
+        'rank': 50500,
         'transition_default_auth': 'A',
     },
     'custom_sb7' : {
         'field_name': 'custom_sb7',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #7"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1221,16 +1149,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50600,
+        'rank': 50600,
         'transition_default_auth': 'A',
     },
     'custom_sb8' : {
         'field_name': 'custom_sb8',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #8"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1240,16 +1167,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50700,
+        'rank': 50700,
         'transition_default_auth': 'A',
     },
     'custom_sb9' : {
         'field_name': 'custom_sb9',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #9"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1259,16 +1185,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50800,
+        'rank': 50800,
         'transition_default_auth': 'A',
     },
     'custom_sb10' : {
         'field_name': 'custom_sb10',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Custom Select Box #10"),
         'description': _("Customizable Select Box (pull down menu with predefined values)"),
         'scope': 'P',
@@ -1278,16 +1203,15 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 50900,
+        'rank': 50900,
         'transition_default_auth': 'A',
     },
     'custom_df1' : {
         'field_name': 'custom_df1',
         'display_type': 'DF',
-        'display_size': '10/10',
         'label': _("Custom Date Field #1"),
         'description': _("Customizable Date Field"),
         'scope': 'P',
@@ -1297,16 +1221,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 60000,
-        'transition_default_auth': 'A',
+        'rank': 60000,
     },
     'custom_df2' : {
         'field_name': 'custom_df2',
         'display_type': 'DF',
-        'display_size': '10/10',
         'label': _("Custom Date Field #2"),
         'description': _("Customizable Date Field"),
         'scope': 'P',
@@ -1316,16 +1238,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 60100,
-        'transition_default_auth': 'A',
+        'rank': 60100,
     },
     'custom_df3' : {
         'field_name': 'custom_df3',
         'display_type': 'DF',
-        'display_size': '10/10',
         'label': _("Custom Date Field #3"),
         'description': _("Customizable Date Field"),
         'scope': 'P',
@@ -1335,16 +1255,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 60200,
-        'transition_default_auth': 'A',
+        'rank': 60200,
     },
     'custom_df4' : {
         'field_name': 'custom_df4',
         'display_type': 'DF',
-        'display_size': '10/10',
         'label': _("Custom Date Field #4"),
         'description': _("Customizable Date Field"),
         'scope': 'P',
@@ -1354,16 +1272,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 60300,
-        'transition_default_auth': 'A',
+        'rank': 60300,
     },
     'custom_df5' : {
         'field_name': 'custom_df5',
         'display_type': 'DF',
-        'display_size': '10/10',
         'label': _("Custom Date Field #5"),
         'description': _("Customizable Date Field"),
         'scope': 'P',
@@ -1373,16 +1289,14 @@
         'special': 0,
         'custom': 1,
         'use_it': 0,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 60400,
-        'transition_default_auth': 'A',
+        'rank': 60400,
     },
     'discussion_lock' : {
         'field_name': 'discussion_lock',
         'display_type': 'SB',
-        'display_size': '',
         'label': _("Discussion Lock"),
         'description': _("Determines whether comments can still be added to the item"),
         'scope': 'S',
@@ -1391,17 +1305,15 @@
         'keep_history': 1,
         'special': 0,
         'custom': 0,
-        'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 0,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 0,
-        'place': 800,
+        'rank': 800,
         'transition_default_auth': 'A',
     },
     'planned_close_date' : {
         'field_name': 'planned_close_date',
         'display_type': 'DF',
-        'display_size': '10/15',
         'label': _("Should be Finished on"),
         'description': _("Date and time when the item should be completed"),
         'scope': 'S',
@@ -1411,16 +1323,14 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 56,
-        'transition_default_auth': 'A',
+        'rank': 56,
     },
     'planned_starting_date' : {
         'field_name': 'planned_starting_date',
         'display_type': 'DF',
-        'display_size': '10/15',
         'label': _("Should Start On"),
         'description': _("Date and time when someone should start working on the item"),
         'scope': 'S',
@@ -1430,54 +1340,62 @@
         'special': 0,
         'custom': 0,
         'use_it': 1,
+        'show_on_add_anonymous': 0,
         'show_on_add_connected': 1,
-        'show_on_add_anonymous': 0,
         'show_on_add_members': 1,
-        'place': 55,
-        'transition_default_auth': 'A',
+        'rank': 55,
     },
 }
 
-fields['bugs']    = common.copy()
-fields['patch']   = common.copy()
-fields['support'] = common.copy()
-fields['task']    = common.copy()
+default_fields['bugs']    = deepcopy(common)
+default_fields['patch']   = deepcopy(common)
+default_fields['support'] = deepcopy(common)
+default_fields['task']    = deepcopy(common)
 
 # A couple changes per-tracker in the default configuration
 #submitted_by     92 -> (use_it=0)(patch,support) | (use_it=1)(bugs,task)
-fields['patch']['submitted_by']['use_it'] = fields['support']['submitted_by']['use_it'] = 0
+default_fields['patch']['submitted_by']['use_it'] = default_fields['support']['submitted_by']['use_it'] = 0
 #severity    102 -> (use_it,show_on_add,show_on_add_members=0)(patch,task) | (use_it,show_on_add,show_on_add_members=1)(bugs,support)
-fields['patch']['severity']['use_it'] = fields['task']['severity']['use_it'] = 0
-fields['patch']['severity']['show_on_add'] = fields['task']['severity']['show_on_add'] = 0
-fields['patch']['severity']['show_on_add_members'] = fields['task']['severity']['show_on_add_members'] = 0
+default_fields['patch']['severity']['use_it'] = default_fields['task']['severity']['use_it'] = 0
+default_fields['patch']['severity']['show_on_add'] = default_fields['task']['severity']['show_on_add'] = 0
+default_fields['patch']['severity']['show_on_add_members'] = default_fields['task']['severity']['show_on_add_members'] = 0
 #bug_group_id    107 -> (show_on_add,show_on_add_members=0)(patch,support) | (show_on_add,show_on_add_members=1)(bugs,task) [but use_it=0]
-#fields['patch']['bug_group_id']['show_on_add'] = fields['support']['bug_group_id']['show_on_add'] = 0
-#fields['patch']['bug_group_id']['show_on_add_members'] = fields['support']['bug_group_id']['show_on_add_members'] = 0
+#default_fields['patch']['bug_group_id']['show_on_add'] = default_fields['support']['bug_group_id']['show_on_add'] = 0
+#default_fields['patch']['bug_group_id']['show_on_add_members'] = default_fields['support']['bug_group_id']['show_on_add_members'] = 0
 #platform_version_id    201 -> (use_it,show_on_add,show_on_add_members=0)(bugs,patch,task) | (use_it,show_on_add,show_on_add_members=1)(support)
-fields['support']['platform_version_id']['use_it'] = 1
-fields['support']['platform_version_id']['show_on_add'] = 1
-fields['support']['platform_version_id']['show_on_add_members'] = 1
+default_fields['support']['platform_version_id']['use_it'] = 1
+default_fields['support']['platform_version_id']['show_on_add'] = 1
+default_fields['support']['platform_version_id']['show_on_add_members'] = 1
 #hours    201 -> (use_it,show_on_add,show_on_add_members=0)(bugs,patch,support) | (use_it,show_on_add,show_on_add_members=1)(task)
-fields['task']['hours']['use_it'] = 1
-fields['task']['hours']['show_on_add'] = 1
-fields['task']['hours']['show_on_add_members'] = 1
+default_fields['task']['hours']['use_it'] = 1
+default_fields['task']['hours']['show_on_add'] = 1
+default_fields['task']['hours']['show_on_add_members'] = 1
 #priority    211 -> (show_on_add,show_on_add_members,place)
 #           bugs: 0,1,200
 #           patch: 1,1,150
-fields['patch']['priority']['show_on_add'] = 1
-fields['patch']['priority']['show_on_add_members'] = 1
-fields['patch']['priority']['place'] = 150
+default_fields['patch']['priority']['show_on_add'] = 1
+default_fields['patch']['priority']['show_on_add_members'] = 1
+default_fields['patch']['priority']['place'] = 150
 #           support: 0,0,150
-fields['support']['priority']['show_on_add'] = 0
-fields['support']['priority']['show_on_add_members'] = 0
-fields['support']['priority']['place'] = 150
+default_fields['support']['priority']['show_on_add'] = 0
+default_fields['support']['priority']['show_on_add_members'] = 0
+default_fields['support']['priority']['place'] = 150
 #           task: 1,1,200
-fields['task']['priority']['show_on_add'] = 1
-fields['task']['priority']['show_on_add_members'] = 1
-fields['task']['priority']['place'] = 200
+default_fields['task']['priority']['show_on_add'] = 1
+default_fields['task']['priority']['show_on_add_members'] = 1
+default_fields['task']['priority']['place'] = 200
 #originator_email    216 -> (use_it,show_on_add=0)(task) | (use_it=1,show_on_add=2)(bugs,patch,support)
-fields['task']['originator_email']['use_it'] = 0
-fields['task']['originator_email']['show_on_add'] = 0
+default_fields['task']['originator_email']['use_it'] = 0
+default_fields['task']['originator_email']['show_on_add'] = 0
 #percent_complete    220 -> (use_it,show_on_add_members=0)(bugs,patch,support) | (use_it,show_on_add_members=1)(task)
-fields['task']['originator_email']['use_it'] = 1
-fields['task']['originator_email']['show_on_add_members'] = 1
+default_fields['task']['originator_email']['use_it'] = 1
+default_fields['task']['originator_email']['show_on_add_members'] = 1
+
+# 'planned_starting_date' was initially specific to 'task'
+default_fields['bugs']   ['planned_starting_date']['use_it'] = 0
+default_fields['patch']  ['planned_starting_date']['use_it'] = 0
+default_fields['support']['planned_starting_date']['use_it'] = 0
+# 'same for planned_close_date'
+default_fields['bugs']   ['planned_close_date']['use_it'] = 0
+default_fields['patch']  ['planned_close_date']['use_it'] = 0
+default_fields['support']['planned_close_date']['use_it'] = 0
--- a/savane/tracker/models.py
+++ b/savane/tracker/models.py
@@ -21,7 +21,9 @@
 import django.contrib.auth.models as auth_models
 from django.utils.safestring import mark_safe
 import datetime
+from copy import deepcopy
 from savane.utils import htmlentitydecode, unescape
+from defs import *
 
 ##
 # Trackers definition
@@ -37,6 +39,13 @@
 # EDIT: actually I think only forms fields cannot be overriden, it
 # still can be done programmatically
 
+DISPLAY_TYPE_CHOICES = (('DF', _('date field')),
+                        ('SB', _('select box')),
+                        ('TA', _('text area')),
+                        ('TF', _('text field')),)
+SCOPE_CHOICES = (('S', _('system')), # user cannot modify related FieldValue's (TF)
+                 ('P', _('project')),)  # user can modify related FieldValue's (TF)
+
 RESTRICTION_CHOICES = (('2', _('anonymous')),
                        ('3', _('logged-in user')),
                        ('5', _('project member')),)
@@ -178,6 +187,7 @@
     display_size = models.CharField(max_length=255, blank=True, null=True)
       # The default value is in Field.display_size
       #   rather than FieldUsage(group_id=100).custom_display_size
+
     # If !Field.special
     keep_history = models.BooleanField(_("keep field value changes in history"))
 
@@ -186,6 +196,28 @@
     label = models.CharField(max_length=255, blank=True, null=True)
     description = models.CharField(max_length=255, blank=True, null=True)
 
+    def apply_on(field_definition):
+        """
+        Modify a default field definition with FieldOverlay's override
+        values.  Only apply sensible overlays.
+        """
+        if not field_definition['required']:
+            field_definition['use_it'] = overlay.use_it
+            field_definition['show_on_add_anonymous'] = overlay.show_on_add_anonymous
+            field_definition['show_on_add_connected'] = overlay.show_on_add_connected
+            field_definition['show_on_add_members'] = overlay.show_on_add_members
+        field_definition['empty_ok'] = overlay.empty_ok
+        field_definition['rank'] = overlay.rank
+        if field_definition['type'] == 'SB':
+            field_definition['transition_default_auth'] = overlay.transition_default_auth
+        elif field_definition['type'] in ('TA', 'TF'):
+            field_definition['display_size'] = overlay.display_size
+        if field_definition['special'] == 1:
+            field_definition['keep_history'] = overlay.keep_history
+        if field_definition['custom'] == 1:
+            field_definition['label'] = overlay.label
+            field_definition['description'] = overlay.description
+
 class FieldValue(models.Model):
     """
     Per-group tracker select box values override
@@ -380,17 +412,37 @@
         from string import ascii_letters
         return "prior" + ascii_letters[self.priority-1]
 
-    def get_form_fields(self):
-        fields = self.tracker.field_set.filter(special=0)
-        usages_default = self.tracker.fieldusage_set.filter(group=None, field__special=0)
-        usages_group   = self.tracker.fieldusage_set.filter(group=self.group, field__special=0)
+    def get_fields(self):
+        """
+        Return fields definition for this group tracker (default
+        values + group-specific overlay).  Only apply sensible
+        overlay values (cf. FieldOverlay model definition).
+        """
+        fields = deepcopy(default_fields[self.tracker_id])
+        overlays = FieldOverlay.objects.filter(group=self.group)
+        for overlay in overlays:
+            name = overlay.field_name
+            overlay.apply_on[fields[name]]
         return fields
 
+    def get_form_fields(self, user=None):
+        """
+        Return displayable fields, ordered by rank
+        """
+        fields = self.get_fields().copy()
+        ret = []
+        for name in fields.keys():
+            if (not (fields[name]['required'] or fields[name]['use_it'])
+                or fields[name]['special']):
+                continue
+            ret.append((name,fields[name]))
+        ret.sort(key=lambda x: x[1]['rank'])
+        return ret
+
     def get_form(self, user=None):
         # TODO: privacy
         form_fields = self.get_form_fields()
-        print form_fields
-        return mark_safe(''.join([f.name + '<br />' for f in form_fields]))
+        return mark_safe(''.join(['%s (%d)<br />' % (f, v['rank']) for f,v in form_fields]))
 
     def __unicode__(self):
         return "%s #%d" % (self.tracker_id, self.get_public_id())