Commit 9be3d936 authored by Sebastien Robin's avatar Sebastien Robin

Improvement of the "monthly report":

- improve speed by not parsing all day of year day by day
- improve speed by looking at much less object in zodb and use
what provides getInventoryList
- do as little as possible object retrieval to display project lines title
- make this report working for task reports associated to projects
(before it was working only with project lines)
- make this report working in another context than a project, so this
means it will be able to show results for different projects

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@43603 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 0edd9659
...@@ -79,10 +79,18 @@ if depth == 0:\n ...@@ -79,10 +79,18 @@ if depth == 0:\n
month_dict = request.form.get(\'month_dict\', None)\n month_dict = request.form.get(\'month_dict\', None)\n
if month_dict is None:\n if month_dict is None:\n
month_dict = {}\n month_dict = {}\n
while current_date < at_date:\n current_date_year = current_date.year()\n
if (current_date.year(), current_date.month()) not in month_dict:\n current_date_month = current_date.month()\n
month_dict[(current_date.year(), current_date.month())] = 1\n at_date_year = at_date.year()\n
current_date += 1\n at_date_month = at_date.month()\n
while True:\n
month_dict[(current_date_year, current_date_month)] = 1\n
if current_date_year == at_date_year and current_date_month == at_date_month:\n
break\n
current_date_month += 1\n
if current_date_month == 13:\n
current_date_month = 0\n
current_date_year += 1\n
request.form[\'month_dict\'] = month_dict\n request.form[\'month_dict\'] = month_dict\n
\n \n
category_list = []\n category_list = []\n
...@@ -96,8 +104,14 @@ if depth == 0:\n ...@@ -96,8 +104,14 @@ if depth == 0:\n
i += 1\n i += 1\n
\n \n
else:\n else:\n
object_dict = here.object_dict\n
string_index = getattr(parent, \'string_index\')\n
object_sub_dict = object_dict.get(string_index, {})\n
object_url_dict = {}\n
project_to_display_dict = here.monthly_project_to_display_dict.get(string_index, {})\n
if depth == 1:\n if depth == 1:\n
parent_category_list = [\'source_project/\' + here.getRelativeUrl()]\n category_list = [x for x in here.project_list \n
if project_to_display_dict.has_key(x.getRelativeUrl())]\n
else:\n else:\n
parent_category_list = parent.getMembershipCriterionCategoryList()\n parent_category_list = parent.getMembershipCriterionCategoryList()\n
category_list = []\n category_list = []\n
...@@ -105,20 +119,18 @@ else:\n ...@@ -105,20 +119,18 @@ else:\n
# sor first, for performance, build a dict with all relative urls of project line that will\n # sor first, for performance, build a dict with all relative urls of project line that will\n
# need to be displayed for this month\n # need to be displayed for this month\n
object_dict = here.object_dict\n object_dict = here.object_dict\n
\n
object_sub_dict = object_dict.get(getattr(parent, \'string_index\'), {})\n object_sub_dict = object_dict.get(getattr(parent, \'string_index\'), {})\n
object_url_dict = {}\n object_url_dict = {}\n
for object_url in object_sub_dict.keys():\n
if not object_url_dict.has_key(object_url):\n
splitted_object_url = object_url.split(\'/\')\n
for x in xrange(0, len(splitted_object_url)):\n
object_url_dict[\'/\'.join(splitted_object_url[0:x+1])] = 1\n
for parent_category in parent_category_list:\n for parent_category in parent_category_list:\n
parent_category = \'/\'.join(parent_category.split(\'/\')[1:])\n parent_category = \'/\'.join(parent_category.split(\'/\')[1:])\n
if object_url_dict.has_key(parent_category):\n if project_to_display_dict.has_key(parent_category):\n
category_child_list = context.restrictedTraverse(parent_category).contentValues(portal_type=project_line_portal_type)\n \tparent_category_object = context.restrictedTraverse(parent_category)\n
for category_child in category_child_list:\n \tcategory_child_list = parent_category_object.contentValues(portal_type=project_line_portal_type)\n
if object_url_dict.has_key(category_child.getRelativeUrl()):\n \t#category_list.append(parent_category_object)\n
category_list.append(category_child)\n \tfor category_child in category_child_list:\n
\t if project_to_display_dict.has_key(category_child.getRelativeUrl()):\n
\t category_list.append(category_child)\n
\n \n
\n \n
i = 0\n i = 0\n
......
...@@ -71,7 +71,6 @@ else:\n ...@@ -71,7 +71,6 @@ else:\n
for k,v in returned_object.items():\n for k,v in returned_object.items():\n
if object_domain.test(v, strict_membership=1):\n if object_domain.test(v, strict_membership=1):\n
result_list.append(v)\n result_list.append(v)\n
\n
return result_list\n return result_list\n
</string> </value> </string> </value>
</item> </item>
......
...@@ -50,18 +50,18 @@ ...@@ -50,18 +50,18 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>context.log(\'object_dict\', object_dict)\n <value> <string>context = context.asContext(object_dict=object_dict,\n
\n
context = context.asContext(object_dict=object_dict,\n
summary_dict=summary_dict,\n summary_dict=summary_dict,\n
column_list=column_list)\n column_list=column_list,\n
project_list=project_list,\n
monthly_project_to_display_dict=monthly_project_to_display_dict)\n
\n \n
return context\n return context\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>object_dict, summary_dict, column_list, **kw</string> </value> <value> <string>object_dict, summary_dict, column_list, project_list, monthly_project_to_display_dict,**kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -55,14 +55,23 @@ ...@@ -55,14 +55,23 @@
from Products.ZSQLCatalog.SQLCatalog import Query\n from Products.ZSQLCatalog.SQLCatalog import Query\n
request = context.REQUEST\n request = context.REQUEST\n
\n \n
object_dict = {}\n object_dict = {} # it contains required temp object to display the report\n
total_object_dict = {}\n
\n \n
column_list= []\n column_list= []\n
worker_column_list = []\n worker_column_list = []\n
portal = context.getPortalObject()\n
temp_object_container = portal.project_module.newContent(temp_object=1)\n
\n \n
# find all Tasks\n # find all Tasks\n
source_project_uid_list = [x.uid for x in context.portal_catalog(\n inventory_kw = {}\n
if context.getPortalType() == \'Project\':\n
inventory_kw[\'project_uid\'] = [x.uid for x in portal.portal_catalog(\n
relative_url=\'%s/%%\' % context.getRelativeUrl())] + [context.getUid()]\n relative_url=\'%s/%%\' % context.getRelativeUrl())] + [context.getUid()]\n
worker_title_list = request.get(\'worker_title_list\')\n
if worker_title_list is not None and len(worker_title_list):\n
inventory_kw[\'node_uid\'] = [x.uid for x in portal.portal_catalog(\n
portal_type=\'Person\',title=worker_title_list)]\n
\n \n
from_date = request.get(\'from_date\', None)\n from_date = request.get(\'from_date\', None)\n
if from_date is None:\n if from_date is None:\n
...@@ -75,36 +84,57 @@ if at_date is None:\n ...@@ -75,36 +84,57 @@ if at_date is None:\n
simulation_state = request.get(\'simulation_state\', None)\n simulation_state = request.get(\'simulation_state\', None)\n
\n \n
\n \n
\n
# We will use inventory API in order to find all quantities\n # We will use inventory API in order to find all quantities\n
result_list = context.portal_simulation.getInventoryList(\n result_list = portal.portal_simulation.getInventoryList(\n
simulation_state = simulation_state,\n simulation_state = simulation_state,\n
project_uid = source_project_uid_list,\n portal_type=\'Task Report Line\',\n
from_date=from_date,\n from_date=from_date,\n
at_date=at_date)\n at_date=at_date, **inventory_kw)\n
\n \n
monthly_worker_quantity_dict = {} # Used to get quantity per month and per worker\n monthly_worker_quantity_dict = {} # Used to get quantity per month and per worker\n
monthly_project_to_display_dict = {} # Used to get project urls to display per month\n
# in the report tree\n
\n
source_uid_dict = {}\n
project_uid_dict = {}\n
project_relative_url_dict = {}\n
\n \n
for task_line in result_list:\n for task_line in result_list:\n
# initialize some variables\n # initialize some variables\n
source = task_line.getSource()\n source_uid = task_line.node_uid\n
if source is None:\n if source_uid is None:\n
# This should not happens, so display an error message\n # This should not happens, so display an error message\n
raise ValueError, context.Base_translateString(\\\n raise ValueError, context.Base_translateString(\\\n
"This task should have a source : ${task_relative_url}",\n "This task should have a source : ${task_relative_url}",\n
mapping = {\'task_relative_url\': task_line.getRelativeUrl()})\n mapping = {\'task_relative_url\': task_line.getRelativeUrl()})\n
source_title = task_line.getSourceTitle()\n source_dict = source_uid_dict.get(source_uid, None)\n
start_date_task = task_line.getStartDate()\n if source_dict is None:\n
stop_date_task = task_line.getStopDate()\n source_value = task_line.getSourceValue()\n
source_dict = {\'title\': source_value.getTitle(),\n
\'relative_url\': source_value.getRelativeUrl()}\n
source_uid_dict[source_uid] = source_dict\n
source_title = source_dict[\'title\']\n
source_relative_url = source_dict[\'relative_url\']\n
start_date_task = task_line.date\n
stop_date_task = task_line.mirror_date\n
year_start_date = start_date_task.year()\n year_start_date = start_date_task.year()\n
month_start_date = start_date_task.month()\n month_start_date = start_date_task.month()\n
\n \n
# create a list with people who works on the task\n # create a list with people who works on the task\n
current_column = (source, task_line.getSourceTitle())\n current_column = (source_relative_url, source_title)\n
if current_column not in worker_column_list:\n if current_column not in worker_column_list:\n
worker_column_list.append(current_column)\n worker_column_list.append(current_column)\n
project = task_line.getSourceProjectValue()\n project_uid = task_line.project_uid\n
quantity = task_line.getQuantity()\n project_dict = project_uid_dict.get(project_uid, None)\n
project_relative_url = project.getRelativeUrl()\n if project_dict is None:\n
project_value = task_line.getSourceProjectValue()\n
project_dict = {\'relative_url\': project_value.getRelativeUrl(),\n
\'title\': project_value.getTitle()}\n
project_uid_dict[project_uid] = project_dict\n
project_relative_url_dict[\'/\'.join(project_value.getRelativeUrl().split(\'/\')[0:2])] = 1\n
quantity = - task_line.inventory\n
project_relative_url = project_dict[\'relative_url\']\n
# diff in day between the begin and the end of the task\n # diff in day between the begin and the end of the task\n
diff_day = stop_date_task - start_date_task + 1\n diff_day = stop_date_task - start_date_task + 1\n
\n \n
...@@ -124,41 +154,50 @@ for task_line in result_list:\n ...@@ -124,41 +154,50 @@ for task_line in result_list:\n
quantity_dict = object_dict.setdefault(string_index, {})\n quantity_dict = object_dict.setdefault(string_index, {})\n
\n \n
worker_quantity_dict = monthly_worker_quantity_dict.setdefault(string_index, {})\n worker_quantity_dict = monthly_worker_quantity_dict.setdefault(string_index, {})\n
project_to_display_dict = monthly_project_to_display_dict.setdefault(string_index, {})\n
if project_to_display_dict.get(project_relative_url, None) is None:\n
splitted_project_url = project_relative_url.split(\'/\')\n
for x in xrange(0, len(splitted_project_url)):\n
project_to_display_dict[\'/\'.join(splitted_project_url[0:x+1])] = 1\n
\n \n
if not quantity_dict.has_key(project_relative_url):\n if not quantity_dict.has_key(project_relative_url):\n
temp_object = context.newContent(portal_type = \'Project Line\',\n temp_object = temp_object_container.newContent(portal_type = \'Project Line\',\n
temp_object=1,\n temp_object=1,\n
string_index = string_index,\n string_index = string_index,\n
category_list = [\'source_project/%s\' % project_relative_url])\n category_list = [\'source_project/%s\' % project_relative_url])\n
quantity_dict[project_relative_url] = temp_object\n quantity_dict[project_relative_url] = temp_object\n
current_temp_object = quantity_dict[project_relative_url]\n current_temp_object = quantity_dict[project_relative_url]\n
current_month_quantity = (min(next_timekeeper,stop_date_task+1) - timekeeper )/ diff_day * quantity\n current_month_quantity = (min(next_timekeeper,stop_date_task+1) - timekeeper )/ diff_day * quantity\n
object_quantity = current_month_quantity + current_temp_object.getProperty(source, 0)\n object_quantity = current_month_quantity + current_temp_object.getProperty(source_relative_url, 0)\n
worker_quantity_dict[source] = worker_quantity_dict.get(source, 0) + current_month_quantity\n worker_quantity_dict[source_relative_url] = worker_quantity_dict.get(source_relative_url, 0) + current_month_quantity\n
current_temp_object.setProperty(source, object_quantity)\n current_temp_object.setProperty(source_relative_url, object_quantity)\n
timekeeper = next_timekeeper\n timekeeper = next_timekeeper\n
\n \n
# Now build temp objects for quantity per month and per worker\n # Now build temp objects for quantity per month and per worker\n
summary_dict = {}\n summary_dict = {}\n
for string_index, worker_quantity_dict in monthly_worker_quantity_dict.items():\n for string_index, worker_quantity_dict in monthly_worker_quantity_dict.items():\n
temp_object = context.newContent(portal_type = \'Project Line\',\n temp_object = temp_object_container.newContent(portal_type = \'Project Line\',\n
temp_object=1,\n temp_object=1,\n
string_index = string_index)\n string_index = string_index)\n
summary_dict[string_index] = temp_object\n summary_dict[string_index] = temp_object\n
for source, quantity in worker_quantity_dict.items():\n for source_relative_url, quantity in worker_quantity_dict.items():\n
temp_object.setProperty(source, quantity)\n temp_object.setProperty(source_relative_url, quantity)\n
\n \n
column_list.extend(worker_column_list)\n column_list.extend(worker_column_list)\n
\n \n
selection_name = \'project_monthly_report_selection\'\n selection_name = \'project_monthly_report_selection\'\n
context.portal_selections.setListboxDisplayMode(request, \'ReportTreeMode\',\n portal.portal_selections.setListboxDisplayMode(request, \'ReportTreeMode\',\n
selection_name=selection_name)\n selection_name=selection_name)\n
\n \n
result = []\n result = []\n
from Products.ERP5Form.Report import ReportSection\n from Products.ERP5Form.Report import ReportSection\n
param_dict = {}\n param_dict = {}\n
\n \n
param_list = [object_dict, summary_dict, column_list]\n project_list = []\n
for project_relative_url in project_relative_url_dict.keys():\n
project_list.append(portal.restrictedTraverse(project_relative_url))\n
param_list = [object_dict, summary_dict, column_list, project_list,\n
monthly_project_to_display_dict]\n
\n \n
result.append(ReportSection(\n result.append(ReportSection(\n
path=context.getPhysicalPath(),\n path=context.getPhysicalPath(),\n
......
784 787
\ No newline at end of file \ No newline at end of file
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