Commit 37b1c21f authored by Rafael Monnerat's avatar Rafael Monnerat

Planning Box was completly refactored. Please update your business

templates in order to make it works.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@18275 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 7473d9ef
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
# Jonathan Loriette <john@nexedi.com> # Jonathan Loriette <john@nexedi.com>
# #
# WARNING: This program as such is intended to be used by professional # WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential # programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs # consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial # End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software # garantees and support are strongly adviced to contract a Free Software
# Service Company # Service Company
# #
# This program is Free Software; you can redistribute it and/or # This program is Free Software; you can redistribute it and/or
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
# this method should return a list of all the objects' urls that does not # this method should return a list of all the objects' urls that does not
# fit the constraints. # fit the constraints.
# Class monitoring access security control # Class monitoring access security control
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
from Globals import InitializeClass from Globals import InitializeClass
...@@ -248,6 +250,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -248,6 +250,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
if final_block['activity_origin'].name not in warning_activity_list: if final_block['activity_origin'].name not in warning_activity_list:
warning_activity_list.append(final_block['activity_origin'].name) warning_activity_list.append(final_block['activity_origin'].name)
block_moved['secondary_axis_start'] = secondary_axis_positions[0] block_moved['secondary_axis_start'] = secondary_axis_positions[0]
block_moved['secondary_axis_stop'] = secondary_axis_positions[1] block_moved['secondary_axis_stop'] = secondary_axis_positions[1]
...@@ -260,6 +263,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -260,6 +263,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
except KeyError: except KeyError:
activity_dict[final_block['activity_origin'].name] = [final_block] activity_dict[final_block['activity_origin'].name] = [final_block]
# getting object_dict to update object properties once activities are up to # getting object_dict to update object properties once activities are up to
# date. Activities values will be updated directly on the # date. Activities values will be updated directly on the
object_dict = self.getObjectDict(basic=basic, planning=planning) object_dict = self.getObjectDict(basic=basic, planning=planning)
...@@ -359,7 +363,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -359,7 +363,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# - dict with error results # - dict with error results
raise FormValidationError(errors_list, {}) raise FormValidationError(errors_list, {})
# the whole process is now finished, # the whole process is now finished,
# just need to return editor for updating data # just need to return editor for updating data
return PlanningBoxEditor(field.id, update_dict) return PlanningBoxEditor(field.id, update_dict)
...@@ -407,7 +411,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -407,7 +411,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
""" """
for block in content_list: for block in content_list:
if block.name == block_name: if block.name == block_name:
return block return block
def getDestinationGroup(self, basic, planning, block_moved, axis_groups, def getDestinationGroup(self, basic, planning, block_moved, axis_groups,
group_position, group_length): group_position, group_length):
...@@ -435,6 +440,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -435,6 +440,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
return group return group
return None return None
def getDestinationBounds(self, basic, planning, block_moved, block_object, def getDestinationBounds(self, basic, planning, block_moved, block_object,
planning_coordinates, axis_length, planning_coordinates, axis_length,
destination_group=None): destination_group=None):
...@@ -501,7 +507,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -501,7 +507,7 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
""" """
# getting list moved block names # getting list moved block names
block_moved_name_list = [x['block_moved']['name'] for x in activity_block_moved_list] block_moved_name_list = [x['block_moved']['name'] for x in activity_block_moved_list]
for activity_block in activity_block_list: for activity_block in activity_block_list:
if activity_block.name in block_moved_name_list: if activity_block.name in block_moved_name_list:
# the block composing the activity has been moved, not taking care of # the block composing the activity has been moved, not taking care of
...@@ -739,6 +745,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -739,6 +745,7 @@ class PlanningBoxWidget(Widget.Widget):
default=10, default=10,
required=1) required=1)
y_axis_position = fields.CheckBoxField('y_axis_position', y_axis_position = fields.CheckBoxField('y_axis_position',
title='Force Y axis to the right intead of left', title='Force Y axis to the right intead of left',
description='position of Y axis over the planning content.' \ description='position of Y axis over the planning content.' \
...@@ -754,6 +761,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -754,6 +761,7 @@ class PlanningBoxWidget(Widget.Widget):
default=0, default=0,
required=1) required=1)
default = fields.TextAreaField('default', default = fields.TextAreaField('default',
title='Default', title='Default',
description="Default value of the text in the widget.", description="Default value of the text in the widget.",
...@@ -761,6 +769,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -761,6 +769,7 @@ class PlanningBoxWidget(Widget.Widget):
width=20, height=3, width=20, height=3,
required=0) required=0)
delimiter = fields.IntegerField('delimiter', delimiter = fields.IntegerField('delimiter',
title='min number of delimiters over the secondary axis', title='min number of delimiters over the secondary axis',
description="min number of delimitations over the sec axis, required", description="min number of delimitations over the sec axis, required",
...@@ -803,6 +812,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -803,6 +812,7 @@ class PlanningBoxWidget(Widget.Widget):
default='', default='',
required=0) required=0)
title_line = fields.StringField('title_line', title_line = fields.StringField('title_line',
title="Specific method which fetches the title of each line", title="Specific method which fetches the title of each line",
description="Method for inserting title in line", description="Method for inserting title in line",
...@@ -860,6 +870,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -860,6 +870,7 @@ class PlanningBoxWidget(Widget.Widget):
default='', default='',
required=0) required=0)
sec_axis_script = fields.StringField('sec_axis_script', sec_axis_script = fields.StringField('sec_axis_script',
title='Name of script building secondary axis (ex. ' \ title='Name of script building secondary axis (ex. ' \
'Planning_generateAxis)', 'Planning_generateAxis)',
...@@ -947,7 +958,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -947,7 +958,7 @@ class PlanningBoxWidget(Widget.Widget):
# render_structure will call all method necessary to build the entire # render_structure will call all method necessary to build the entire
# structure relative to the planning # structure relative to the planning
# creates and fill up self.basic, self.planning and self.build_error_list # creates and fill up self.basic, self.planning and self.build_error_list
basic, planning = self.render_structure(field=field, REQUEST=REQUEST, basic, planning = self.render_structure(field=field, REQUEST=REQUEST,
context=context) context=context)
# getting CSS script generator # getting CSS script generator
planning_css_method = getattr(context, 'planning_css') planning_css_method = getattr(context, 'planning_css')
...@@ -974,7 +985,7 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -974,7 +985,7 @@ class PlanningBoxWidget(Widget.Widget):
planning = REQUEST.get('planning') planning = REQUEST.get('planning')
# getting HTML rendering Page Template # getting HTML rendering Page Template
planning_html_method = getattr(getContext(field, REQUEST), planning_html_method = getattr(getContext(field, REQUEST),
'planning_content') 'planning_content')
# recovering HTML data by calling Page Template document # recovering HTML data by calling Page Template document
HTML_data = planning_html_method(basic=basic, planning=planning) HTML_data = planning_html_method(basic=basic, planning=planning)
...@@ -1024,14 +1035,14 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -1024,14 +1035,14 @@ class PlanningBoxWidget(Widget.Widget):
# creating BasicStructure instance (and initializing its internal values) # creating BasicStructure instance (and initializing its internal values)
basic = BasicStructure(context=context, basic = BasicStructure(context=context,
form=form, field=field, form=form, field=field,
REQUEST=REQUEST, REQUEST=REQUEST,
list_method=list_method, list_method=list_method,
sec_layer_list_method=sec_layer_list_method, sec_layer_list_method=sec_layer_list_method,
selection=selection, params=params, selection=selection, params=params,
selection_name=selection_name, selection_name=selection_name,
title_line=title_line, title_line=title_line,
report_root_list=report_root_list, report_root_list=report_root_list,
portal_types=portal_types, portal_types=portal_types,
sort=sort, sort=sort,
list_error=list_error) list_error=list_error)
# call build method to generate BasicStructure # call build method to generate BasicStructure
...@@ -1216,7 +1227,7 @@ class BasicStructure: ...@@ -1216,7 +1227,7 @@ class BasicStructure:
selection_report_current = () selection_report_current = ()
else: else:
selection_report_current = self.selection.getReportList() selection_report_current = self.selection.getReportList()
# building report_tree_list # building report_tree_list
report_tree_list = makeTreeList(here=self.context, form=self.form, report_tree_list = makeTreeList(here=self.context, form=self.form,
root_dict=None, root_dict=None,
...@@ -1233,7 +1244,7 @@ class BasicStructure: ...@@ -1233,7 +1244,7 @@ class BasicStructure:
form_id=self.form.id) form_id=self.form.id)
if report_tree_list == []: if report_tree_list == []:
LOG("BasicStructure",0 ,"Report tree list is empty on %s" % LOG("BasicStructure",0 ,"Report tree list is empty on %s" %
self.field.absolute_url()) self.field.absolute_url())
########### GETTING MAIN AXIS BOUNDS ############# ########### GETTING MAIN AXIS BOUNDS #############
...@@ -1310,7 +1321,7 @@ class BasicStructure: ...@@ -1310,7 +1321,7 @@ class BasicStructure:
del kw['select_expression'] del kw['select_expression']
else: else:
kw['select_expression'] = original_select_expression kw['select_expression'] = original_select_expression
# adding current line to report_section where # adding current line to report_section where
# line is pure Summary # line is pure Summary
self.report_groups += [(object_tree_line,stat_list,info_dict)] self.report_groups += [(object_tree_line,stat_list,info_dict)]
...@@ -1325,7 +1336,7 @@ class BasicStructure: ...@@ -1325,7 +1336,7 @@ class BasicStructure:
if sec_layer_method_name not in (None,''): if sec_layer_method_name not in (None,''):
sec_layer_object_list = getattr(domain_obj,\ sec_layer_object_list = getattr(domain_obj,\
sec_layer_method_name)() sec_layer_method_name)()
# Default Values # Default Values
new_object_list = [] new_object_list = []
sec_new_object_list = [] sec_new_object_list = []
...@@ -1362,7 +1373,7 @@ class BasicStructure: ...@@ -1362,7 +1373,7 @@ class BasicStructure:
object_list = new_object_list object_list = new_object_list
self.sec_layer_uid_list.extend([obj.getUid() for obj in sec_layer_object_list]) self.sec_layer_uid_list.extend([obj.getUid() for obj in sec_layer_object_list])
# The order is important # The order is important
sec_layer_object_list.extend(object_list) sec_layer_object_list.extend(object_list)
object_list = sec_layer_object_list object_list = sec_layer_object_list
...@@ -1395,6 +1406,7 @@ class BasicStructure: ...@@ -1395,6 +1406,7 @@ class BasicStructure:
self.report_groups += [(object_tree_line,object_list,info_dict)] self.report_groups += [(object_tree_line,object_list,info_dict)]
self.nbr_groups += 1 self.nbr_groups += 1
# reset to original value # reset to original value
self.selection.edit(report = None) self.selection.edit(report = None)
#self.selection.edit(report_list=None) # comment to save report_list status #self.selection.edit(report_list=None) # comment to save report_list status
...@@ -1410,6 +1422,7 @@ class BasicStructure: ...@@ -1410,6 +1422,7 @@ class BasicStructure:
unfolded_list.append(report_line.getObject().getRelativeUrl()) unfolded_list.append(report_line.getObject().getRelativeUrl())
self.selection.edit(report_list=unfolded_list) self.selection.edit(report_list=unfolded_list)
############## CHECKING CONSTRAINTS ############## ############## CHECKING CONSTRAINTS ##############
# XXX Constraints checking should be called here # XXX Constraints checking should be called here
# and results saved in a list (list of url corresponding to objects not # and results saved in a list (list of url corresponding to objects not
...@@ -1535,6 +1548,7 @@ class BasicStructure: ...@@ -1535,6 +1548,7 @@ class BasicStructure:
self.calendar_range = calendar_range self.calendar_range = calendar_range
return secondary_axis_occurence return secondary_axis_occurence
def getSecondaryAxisInfo(self): def getSecondaryAxisInfo(self):
""" """
secondary_axis_ocurence holds couples of data (begin,end) related to secondary_axis_ocurence holds couples of data (begin,end) related to
...@@ -1547,7 +1561,7 @@ class BasicStructure: ...@@ -1547,7 +1561,7 @@ class BasicStructure:
# recovering zoom properties # recovering zoom properties
axis_dict['zoom_start'] = int(self.params.get('zoom_start',0)) axis_dict['zoom_start'] = int(self.params.get('zoom_start',0))
axis_dict['zoom_level'] = float(self.params.get('zoom_level',1)) axis_dict['zoom_level'] = float(self.params.get('zoom_level',1))
if not use_dz: if not use_dz:
if len(self.secondary_axis_occurence) != 0: if len(self.secondary_axis_occurence) != 0:
axis_dict['bound_begin'] = self.secondary_axis_occurence[0][0] axis_dict['bound_begin'] = self.secondary_axis_occurence[0][0]
...@@ -1576,11 +1590,11 @@ class BasicStructure: ...@@ -1576,11 +1590,11 @@ class BasicStructure:
if len(self.secondary_axis_occurence) == 1: if len(self.secondary_axis_occurence) == 1:
self.secondary_axis_occurence = [] self.secondary_axis_occurence = []
return 1 return 1
axis_dict['bound_range'] = axis_dict['bound_end'] - axis_dict['bound_begin'] axis_dict['bound_range'] = axis_dict['bound_end'] - axis_dict['bound_begin']
# now start and stop have the extreme values of the second axis bound. # now start and stop have the extreme values of the second axis bound.
# this represents in fact the size of the Planning's secondary axis # this represents in fact the size of the Planning's secondary axis
# can now get selection informations ( float range 0..1) # can now get selection informations ( float range 0..1)
axis_dict['bound_start'] = 0 axis_dict['bound_start'] = 0
axis_dict['bound_stop'] = 1 axis_dict['bound_stop'] = 1
...@@ -1593,20 +1607,20 @@ class BasicStructure: ...@@ -1593,20 +1607,20 @@ class BasicStructure:
except AttributeError: except AttributeError:
# bounds were not defined, escaping test # bounds were not defined, escaping test
pass pass
# getting secondary axis page step # getting secondary axis page step
axis_zoom_step = axis_dict['bound_range'] / axis_dict['zoom_level'] axis_zoom_step = axis_dict['bound_range'] / axis_dict['zoom_level']
# now setting bound_start # now setting bound_start
axis_dict['bound_start'] = axis_dict['zoom_start'] * axis_zoom_step + \ axis_dict['bound_start'] = axis_dict['zoom_start'] * axis_zoom_step + \
axis_dict['bound_begin'] axis_dict['bound_begin']
# for bound_stop just add page step # for bound_stop just add page step
axis_dict['bound_stop'] = axis_dict['bound_start'] + axis_zoom_step axis_dict['bound_stop'] = axis_dict['bound_start'] + axis_zoom_step
# saving current zoom values # saving current zoom values
self.params['zoom_level'] = axis_dict['zoom_level'] self.params['zoom_level'] = axis_dict['zoom_level']
self.params['zoom_start'] = axis_dict['zoom_start'] self.params['zoom_start'] = axis_dict['zoom_start']
else: else:
# Use dz_zoom feature # Use dz_zoom feature
axis_dict['zoom_begin'] = self.params.get('zoom_begin',None) axis_dict['zoom_begin'] = self.params.get('zoom_begin',None)
...@@ -1623,7 +1637,7 @@ class BasicStructure: ...@@ -1623,7 +1637,7 @@ class BasicStructure:
validate_method = getattr(self.context, 'planning_validate_date_list', None) validate_method = getattr(self.context, 'planning_validate_date_list', None)
axis_dict['bound_start'], axis_dict['bound_stop'] = \ axis_dict['bound_start'], axis_dict['bound_stop'] = \
validate_method( DateTime(), axis_dict['zoom_level']) validate_method( DateTime(), axis_dict['zoom_level'])
# For Keep compatibility # For Keep compatibility
axis_dict['zoom_begin'] = axis_dict['bound_start'] axis_dict['zoom_begin'] = axis_dict['bound_start']
axis_dict['zoom_end'] = axis_dict['bound_stop'] axis_dict['zoom_end'] = axis_dict['bound_stop']
...@@ -1635,6 +1649,7 @@ class BasicStructure: ...@@ -1635,6 +1649,7 @@ class BasicStructure:
# everything is OK, returning 'true' flag # everything is OK, returning 'true' flag
return axis_dict return axis_dict
def getMainAxisInfo(self, report_tree_list): def getMainAxisInfo(self, report_tree_list):
""" """
Getting main axis properties (total pages, current page, groups per page) Getting main axis properties (total pages, current page, groups per page)
...@@ -1698,6 +1713,7 @@ class BasicStructure: ...@@ -1698,6 +1713,7 @@ class BasicStructure:
return main_axis_dict return main_axis_dict
def buildGroupStructure(self): def buildGroupStructure(self):
""" """
This procedure builds BasicGroup instances corresponding to the This procedure builds BasicGroup instances corresponding to the
...@@ -1761,6 +1777,7 @@ class BasicStructure: ...@@ -1761,6 +1777,7 @@ class BasicStructure:
return 1 return 1
class BasicGroup: class BasicGroup:
""" """
A BasicGroup holds informations about an ERP5Object and is stored A BasicGroup holds informations about an ERP5Object and is stored
...@@ -1894,7 +1911,7 @@ class BasicGroup: ...@@ -1894,7 +1911,7 @@ class BasicGroup:
object = activity_content object = activity_content
url='' url=''
else: else:
# getting info text from activity itself if exists # getting info text from activity itself if exists
info_center_method = getattr(activity_content,info_center,None) info_center_method = getattr(activity_content,info_center,None)
info_topright_method = getattr(activity_content,info_topright,None) info_topright_method = getattr(activity_content,info_topright,None)
...@@ -1942,13 +1959,13 @@ class BasicGroup: ...@@ -1942,13 +1959,13 @@ class BasicGroup:
stat_context.absolute_url = \ stat_context.absolute_url = \
lambda x: activity_content.getObject().absolute_url() lambda x: activity_content.getObject().absolute_url()
object = stat_context.getObject() object = stat_context.getObject()
# check if the activity_content has some special method for URL # check if the activity_content has some special method for URL
# This approach is also used by ListBox, but in Planning Box # This approach is also used by ListBox, but in Planning Box
# the parameters are not important for now. In future, can be define # the parameters are not important for now. In future, can be define
# special sublinks using this implementation. # special sublinks using this implementation.
#if getattr(activity_content, 'getListItemUrl', None): #if getattr(activity_content, 'getListItemUrl', None):
# url = activity_content.getListItemUrl(cname_id='', # url = activity_content.getListItemUrl(cname_id='',
# selection_index='', # selection_index='',
# selection_name=self.field.get_value('selection_name')) # selection_name=self.field.get_value('selection_name'))
#else: #else:
...@@ -2088,6 +2105,7 @@ class BasicActivity: ...@@ -2088,6 +2105,7 @@ class BasicActivity:
self.error = error self.error = error
self.property_dict = property_dict # dict containing specific properties self.property_dict = property_dict # dict containing specific properties
class PlanningStructure: class PlanningStructure:
""" """
class aimed to generate the Planning final structure, including : class aimed to generate the Planning final structure, including :
...@@ -2102,6 +2120,7 @@ class PlanningStructure: ...@@ -2102,6 +2120,7 @@ class PlanningStructure:
self.content = [] self.content = []
self.content_delimiters = None self.content_delimiters = None
def build(self, basic_structure=None, field=None, REQUEST=None): def build(self, basic_structure=None, field=None, REQUEST=None):
""" """
main procedure for building Planning Structure main procedure for building Planning Structure
...@@ -2201,9 +2220,9 @@ class PlanningStructure: ...@@ -2201,9 +2220,9 @@ class PlanningStructure:
# using relative coordinates # using relative coordinates
for delimiter in delimiter_list: for delimiter in delimiter_list:
link = None link = None
if delimiter.has_key('link'): link = delimiter['link'] if delimiter.has_key('link'): link = delimiter['link']
axis_group = AxisGroup(name='Group_sec_' + str(axis_group_number), axis_group = AxisGroup(name='Group_sec_' + str(axis_group_number),
title=delimiter['title'], title=delimiter['title'],
delimiter_type=delimiter['delimiter_type'], delimiter_type=delimiter['delimiter_type'],
link=link) link=link)
axis_group.tooltip = delimiter['tooltip'] axis_group.tooltip = delimiter['tooltip']
...@@ -2228,6 +2247,7 @@ class PlanningStructure: ...@@ -2228,6 +2247,7 @@ class PlanningStructure:
axis_group_number += 1 axis_group_number += 1
return axis_group_list return axis_group_list
def completeAxis(self): def completeAxis(self):
""" """
...@@ -2385,6 +2405,7 @@ class PlanningStructure: ...@@ -2385,6 +2405,7 @@ class PlanningStructure:
return 1 return 1
return axis_element_already_present return axis_element_already_present
def buildBlocs(self, basic_structure=None, REQUEST=None): def buildBlocs(self, basic_structure=None, REQUEST=None):
""" """
iterate the whole planning structure to get various activities and build iterate the whole planning structure to get various activities and build
...@@ -2427,6 +2448,7 @@ class PlanningStructure: ...@@ -2427,6 +2448,7 @@ class PlanningStructure:
# no problem during process, returning 'true' flag # no problem during process, returning 'true' flag
return 1 return 1
class Activity: class Activity:
""" """
Class representing a task in the Planning, for example an appointment or Class representing a task in the Planning, for example an appointment or
...@@ -2468,11 +2490,13 @@ class Activity: ...@@ -2468,11 +2490,13 @@ class Activity:
self.calendar_view = calendar_view self.calendar_view = calendar_view
self.property_dict = property_dict self.property_dict = property_dict
# XXX Still used ? # XXX Still used ?
def get_error_message(self, Error): def get_error_message(self, Error):
# need to update the error message # need to update the error message
return 'task %s (%s)not validated' % (self.name, self.title) return 'task %s (%s)not validated' % (self.name, self.title)
def isValidPosition(self, bound_begin, bound_end): def isValidPosition(self, bound_begin, bound_end):
""" """
can check if actual activity can fit within the bounds, returns : can check if actual activity can fit within the bounds, returns :
...@@ -2667,6 +2691,8 @@ class Activity: ...@@ -2667,6 +2691,8 @@ class Activity:
# # return new list # # return new list
# return returned_list # return returned_list
class Bloc: class Bloc:
""" """
structure that will be rendered as a bloc, a task element. structure that will be rendered as a bloc, a task element.
...@@ -2780,6 +2806,7 @@ class Position: ...@@ -2780,6 +2806,7 @@ class Position:
self.relative_end = relative_end self.relative_end = relative_end
self.relative_range = relative_range self.relative_range = relative_range
class Axis: class Axis:
""" """
Structure holding informations about a specified axis. Can be X or Y axis. Structure holding informations about a specified axis. Can be X or Y axis.
...@@ -2809,6 +2836,7 @@ class Axis: ...@@ -2809,6 +2836,7 @@ class Axis:
# dict containing all class properties with their values # dict containing all class properties with their values
self.render_dict=None self.render_dict=None
class AxisGroup: class AxisGroup:
""" """
Class representing an item, that can have the following properties : Class representing an item, that can have the following properties :
...@@ -2828,7 +2856,7 @@ class AxisGroup: ...@@ -2828,7 +2856,7 @@ class AxisGroup:
property_dict={}): property_dict={}):
self.name = name self.name = name
self.title = title self.title = title
# link to fold or unfold report in report-tree mode and also # link to fold or unfold report in report-tree mode and also
# special link on header columns # special link on header columns
self.link = link self.link = link
self.info_title = Info(info=self.title, link=self.link, title=self.title) self.info_title = Info(info=self.title, link=self.link, title=self.title)
...@@ -2871,6 +2899,7 @@ class AxisGroup: ...@@ -2871,6 +2899,7 @@ class AxisGroup:
self.secondary_axis_range = secondary_axis_range self.secondary_axis_range = secondary_axis_range
self.property_dict = property_dict self.property_dict = property_dict
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declarePublic('setTitle') security.declarePublic('setTitle')
...@@ -2902,6 +2931,7 @@ class AxisGroup: ...@@ -2902,6 +2931,7 @@ class AxisGroup:
self.tooltip = info_title.info self.tooltip = info_title.info
def addActivity(self, activity=None, axis_element_already_insered=0, def addActivity(self, activity=None, axis_element_already_insered=0,
basic_structure=None): basic_structure=None):
""" """
...@@ -2991,6 +3021,7 @@ class AxisGroup: ...@@ -2991,6 +3021,7 @@ class AxisGroup:
self.axis_element_list = [] self.axis_element_list = []
self.axis_element_list.append(new_axis_element) self.axis_element_list.append(new_axis_element)
def addStatActivities(self, basic_activity_list=None, axis_group_number=0, def addStatActivities(self, basic_activity_list=None, axis_group_number=0,
axis_element_already_present= 0, calendar_view=0, axis_element_already_present= 0, calendar_view=0,
primary_axis_block=None, property_dict={}): primary_axis_block=None, property_dict={}):
...@@ -3043,6 +3074,7 @@ class AxisGroup: ...@@ -3043,6 +3074,7 @@ class AxisGroup:
activity_number +=1 activity_number +=1
def updateStatBlocks(self): def updateStatBlocks(self):
""" """
called once the blocks have been defined on all activities called once the blocks have been defined on all activities
...@@ -3101,6 +3133,7 @@ class AxisElement: ...@@ -3101,6 +3133,7 @@ class AxisElement:
self.render_dict=None self.render_dict=None
self.parent_axis_group = parent_axis_group self.parent_axis_group = parent_axis_group
class Info: class Info:
""" """
Class holding all informations to display an info text div inside of a block Class holding all informations to display an info text div inside of a block
...@@ -3122,6 +3155,7 @@ class Info: ...@@ -3122,6 +3155,7 @@ class Info:
# declaring validator instance # declaring validator instance
PlanningBoxValidatorInstance = PlanningBoxValidator() PlanningBoxValidatorInstance = PlanningBoxValidator()
class PlanningBox(ZMIField): class PlanningBox(ZMIField):
meta_type = "PlanningBox" meta_type = "PlanningBox"
widget = PlanningBoxWidgetInstance widget = PlanningBoxWidgetInstance
......
...@@ -664,8 +664,8 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -664,8 +664,8 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
return self.checkAll(list_selection_name, uids, REQUEST=REQUEST, query_string=query_string) return self.checkAll(list_selection_name, uids, REQUEST=REQUEST, query_string=query_string)
# PlanningBox related methods # PlanningBox related methods
security.declareProtected(ERP5Permissions.View, 'setZoomLevel') security.declareProtected(ERP5Permissions.View, 'setLanePath')
def setZoomLevel(self, uids=None, REQUEST=None, form_id=None, def setLanePath(self, uids=None, REQUEST=None, form_id=None,
query_string=None): query_string=None):
""" """
Set graphic zoom level in PlanningBox Set graphic zoom level in PlanningBox
...@@ -677,62 +677,24 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -677,62 +677,24 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST) selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is not None: if selection is not None:
params = selection.getParams() params = selection.getParams()
zoom_level = request.form.get('zoom_level', None) lane_path = request.form.get('lane_path', None)
if zoom_level is None: if lane_path is None:
# If zoom_level is not defined try to # If lane_path is not defined try to
# use the last one from params # use the last one from params
zoom_level = params.get('zoom_level', 1) lane_path = params.get('lane_path',1)
bound_start = request.form.get('bound_start', None)
# for keep compatibility with the old zoom if bound_start is not None:
zoom_start = request.form.get('zoom_start',0) params['bound_start'] = bound_start
if zoom_level <= zoom_start: params['lane_path'] = lane_path
zoom_start = max(int(float(zoom_level)),1) - 1 params['zoom_variation'] = 0
params['zoom_start'] = zoom_start
# XXX URL currently pass string parameter and not int
# This is a dirty fix!
# It should be fixed by cleaning the date zoom level
# in a generic way
zoom_level = int(zoom_level)
zoom_begin = request.form.get('zoom_begin', None)
#zoom_end = request.form.get('zoom_end', None)
zoom_date_start = request.form.get('zoom_date_start', None)
if zoom_date_start is not None:
zoom_begin = zoom_date_start
if zoom_begin is None:
zoom_begin = params.get('zoom_begin', None)
params['zoom_level'] = zoom_level
# Calculating New zoom Dates Range.
validate_method = getattr(self, 'planning_validate_date_list', None)
date_range = validate_method(zoom_begin,zoom_level)
params['from_date'] = params['zoom_begin'] = date_range[0]
params['to_date'] = params['zoom_end'] = date_range[1]
selection.edit(params=params) selection.edit(params=params)
if REQUEST is not None: if REQUEST is not None:
return self._redirectToOriginalForm(REQUEST=REQUEST, return self._redirectToOriginalForm(REQUEST=REQUEST,
form_id=form_id, form_id=form_id,
query_string=query_string) query_string=query_string)
security.declareProtected(ERP5Permissions.View, 'setZoom') security.declareProtected(ERP5Permissions.View, 'nextLanePage')
def setZoom(self, uids=None, REQUEST=None, form_id=None, query_string=None): def nextLanePage(self, uids=None, REQUEST=None, form_id=None, query_string=None):
"""
Set graphic zoom in PlanningBox
"""
if uids is None: uids = []
request = REQUEST
selection_name=request.list_selection_name
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is not None:
params = selection.getParams()
zoom_start = request.form.get('zoom_start',0)
params['zoom_start'] = zoom_start
selection.edit(params=params)
if REQUEST is not None:
return self._redirectToOriginalForm(REQUEST=REQUEST, form_id=form_id,
query_string=query_string)
security.declareProtected(ERP5Permissions.View, 'nextZoom')
def nextZoom(self, uids=None, REQUEST=None, form_id=None, query_string=None):
""" """
Set next graphic zoom start in PlanningBox Set next graphic zoom start in PlanningBox
""" """
...@@ -743,28 +705,15 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -743,28 +705,15 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST) selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is not None: if selection is not None:
params = selection.getParams() params = selection.getParams()
zoom_level = params.get('zoom_level', 1) params['bound_variation'] = 1
zoom_variation = + 1
zoom_begin = request.form.get('zoom_begin', None)
# for keep the compatibility
zoom_start = params.get('zoom_start',0)
params['zoom_start'] = int(zoom_start) + 1
if zoom_begin is None:
zoom_begin = params.get('zoom_begin', None)
validate_method = getattr(self, 'planning_validate_date_list', None)
date_range = validate_method(zoom_begin,zoom_level,zoom_variation)
params['zoom_begin'] = params['from_date'] = date_range[0]
params['zoom_end'] = params['to_date'] = date_range[1]
selection.edit(params=params) selection.edit(params=params)
if REQUEST is not None: if REQUEST is not None:
return self._redirectToOriginalForm(REQUEST=REQUEST, return self._redirectToOriginalForm(REQUEST=REQUEST,
form_id=form_id, form_id=form_id,
query_string=query_string) query_string=query_string)
security.declareProtected(ERP5Permissions.View, 'previousZoom') security.declareProtected(ERP5Permissions.View, 'previousLanePage')
def previousZoom(self, uids=None, REQUEST=None, form_id=None, query_string=None): def previousLanePage(self, uids=None, REQUEST=None, form_id=None, query_string=None):
""" """
Set previous graphic zoom in PlanningBox Set previous graphic zoom in PlanningBox
""" """
...@@ -775,20 +724,7 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -775,20 +724,7 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
selection = self.getSelectionFor(selection_name, REQUEST=REQUEST) selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
if selection is not None: if selection is not None:
params = selection.getParams() params = selection.getParams()
zoom_level = params.get('zoom_level', 1) params['bound_variation'] = -1
zoom_variation = -1
zoom_begin = request.form.get('zoom_begin', None)
# for keep the compatibility
zoom_start = params.get('zoom_start',0)
params['zoom_start'] = int(zoom_start) - 1
if zoom_begin is None:
zoom_begin = params.get('zoom_begin', None)
validate_method = getattr(self, 'planning_validate_date_list', None)
date_range = validate_method(zoom_begin,zoom_level,zoom_variation)
params['zoom_begin'] = params['from_date'] = date_range[0]
params['zoom_end'] = params['to_date'] = date_range[1]
selection.edit(params=params) selection.edit(params=params)
if REQUEST is not None: if REQUEST is not None:
return self._redirectToOriginalForm(REQUEST=REQUEST, return self._redirectToOriginalForm(REQUEST=REQUEST,
......
...@@ -108,10 +108,10 @@ class TestPlanningBox(ERP5TypeTestCase): ...@@ -108,10 +108,10 @@ class TestPlanningBox(ERP5TypeTestCase):
def stepCheckPlanning(self, sequence = None, sequence_list = None, **kw): def stepCheckPlanning(self, sequence = None, sequence_list = None, **kw):
planning = sequence.get('planning') planning = sequence.get('planning')
self.assertEquals(planning.calendar_view, 0) self.assertEquals(planning.vertical_view, 0)
self.assertEquals(len(planning.content), 1) self.assertEquals(len(planning.content), 1)
bloc = planning.content[0] bloc = planning.content[0]
self.assertEquals(bloc.name , 'Group_1_Activity_1_Block_1') self.assertEquals(bloc.name , 'group_1_activity_1_block_1')
self.assertEquals(bloc.title , 'Title 0') self.assertEquals(bloc.title , 'Title 0')
for info in bloc.info.values(): for info in bloc.info.values():
self.assertEquals(info.info,'Title 0') self.assertEquals(info.info,'Title 0')
...@@ -129,7 +129,7 @@ class TestPlanningBox(ERP5TypeTestCase): ...@@ -129,7 +129,7 @@ class TestPlanningBox(ERP5TypeTestCase):
basic = sequence.get('basic') basic = sequence.get('basic')
self.assertEquals(len(basic.report_groups), 1) self.assertEquals(len(basic.report_groups), 1)
# Note that this test use the use_date_zoom enabled. # Note that this test use the use_date_zoom enabled.
sec_axis_info = basic.getSecondaryAxisInfo() sec_axis_info = basic.getLaneAxisInfo()
date = DateTime() date = DateTime()
today = DateTime('%s/%s/%s' % (date.year(),date.month(),date.day())) today = DateTime('%s/%s/%s' % (date.year(),date.month(),date.day()))
self.assertEquals(sec_axis_info['zoom_begin'], today) self.assertEquals(sec_axis_info['zoom_begin'], today)
......
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