Commit a5c577a6 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

Merge branch 'master' into erp5-component

parents 84e6cf10 649a5769
Changes Changes
======= =======
0.4.19 (2012-12-17)
------------------
* erp5.util.testnode:
- Fixed undefined variable [Sebastien Robin]
0.4.18 (2012-12-14)
------------------
* erp5.util.testnode:
- Solve ascii issues when deleting software [Sebastien Robin]
0.4.17 (2012-12-10)
------------------
* erp5.util.testnode:
- Add thread Timer to terminate locked processes [Sebastien Robin]
- Add more unit tests [Pere Cortes]
0.4.16 (2012-11-14)
------------------
* erp5.util.testnode:
- Improve handling of Xvfb and firefox [Sebastien Robin]
- check supported parameters of runTestSuite [Pere Cortes]
- add unit for runTestSuite [Pere Cortes]
0.4.15 (2012-11-07)
------------------
* erp5.util.testnode:
- fixed profile generation when software repos is not defined first
[Sebastien Robin]
- ask wich test has priority to master more often [Sebastien Robin]
0.4.14 (2012-11-05)
------------------
* erp5.util.testnode:
- force rebuilding software to avoid using old soft/code [Sebastien Robin]
* erp5.util.taskdistribution:
- handle another possible error with master [Sebastien Robin]
0.4.13 (2012-10-31)
------------------
* erp5.util.testnode:
- Add unit test for erp5testnode (with some hardcoded path that
needs to be fixed ASAP) [Sebastien Robin]
- Split long functions into several more simple ones for code
simplicity and readability [Sebastien Robin]
0.4.12 (2012-10-25)
------------------
* erp5.util.testnode:
- Fixed several issues introduced by the management of test
suite by the master [Sebastien Robin]
0.4.11 (2012-10-22)
------------------
* erp5.util.testnode:
- Take test suite parameters from the master, to allow distribution
of the work by the master [Pere Cortes], [Sebastien Robin]
0.4.10 (2012-10-01) 0.4.10 (2012-10-01)
------------------ ------------------
......
...@@ -54,13 +54,12 @@ ...@@ -54,13 +54,12 @@
"""Get the report sections for general ledger\n """Get the report sections for general ledger\n
"""\n """\n
from Products.ZSQLCatalog.SQLCatalog import Query\n from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n
from Products.ERP5Form.Report import ReportSection\n from Products.ERP5Form.Report import ReportSection\n
portal = context.portal_url.getPortalObject()\n portal = context.portal_url.getPortalObject()\n
request = portal.REQUEST\n request = portal.REQUEST\n
cat_tool = portal.portal_categories\n cat_tool = portal.portal_categories\n
sim_tool = portal.portal_simulation\n Base_translateString = portal.Base_translateString\n
Base_translateString = context.Base_translateString\n
\n \n
at_date = request[\'at_date\']\n at_date = request[\'at_date\']\n
section_category = request[\'section_category\']\n section_category = request[\'section_category\']\n
...@@ -110,19 +109,40 @@ if funding_category:\n ...@@ -110,19 +109,40 @@ if funding_category:\n
if funding_category == \'None\':\n if funding_category == \'None\':\n
params[\'funding_uid\'] = Query(funding_uid=None)\n params[\'funding_uid\'] = Query(funding_uid=None)\n
else:\n else:\n
params[\'funding_category\'] = funding_category\n funding_value = portal.restrictedTraverse(funding_category, None)\n
if funding_value is not None and funding_value.getPortalType() != \'Category\':\n
params[\'funding_uid\'] = funding_value.getUid()\n
else:\n
params[\'funding_category\'] = funding_category\n
\n
function_category = request.get(\'function\')\n function_category = request.get(\'function\')\n
if function_category:\n if function_category:\n
if function_category == \'None\':\n if function_category == \'None\':\n
params[\'function_uid\'] = Query(function_uid=None)\n params[\'function_uid\'] = Query(function_uid=None)\n
else:\n else:\n
params[\'function_category\'] = function_category\n function_value = portal.restrictedTraverse(function_category, None)\n
if function_value is not None and function_value.getPortalType() != \'Category\':\n
params[\'function_uid\'] = function_value.getUid()\n
else:\n
params[\'function_category\'] = function_category\n
\n
if mirror_section:\n if mirror_section:\n
mirror_section_uid = portal.restrictedTraverse(mirror_section).getUid()\n mirror_section_uid = portal.restrictedTraverse(mirror_section).getUid()\n
params[\'mirror_section_uid\'] = mirror_section_uid\n params[\'mirror_section_uid\'] = mirror_section_uid\n
\n \n
default_selection_params = params.copy()\n default_selection_params = params.copy()\n
\n \n
# if user request report without grouping reference, don\'t show accounts that only have grouped lines in the period.\n
if request.get(\'omit_grouping_reference\', False):\n
if at_date:\n
params[\'grouping_query\'] = ComplexQuery(\n
Query(grouping_reference=None),\n
Query(grouping_date=at_date, range="min"),\n
operator="OR")\n
else:\n
params[\'grouping_reference\'] = None\n
\n
\n
analytic_column_list = ()\n analytic_column_list = ()\n
if hide_analytic:\n if hide_analytic:\n
default_selection_params[\'group_by\'] = ( \'explanation_uid\',\n default_selection_params[\'group_by\'] = ( \'explanation_uid\',\n
...@@ -187,7 +207,7 @@ def getFullAccountName(account_info):\n ...@@ -187,7 +207,7 @@ def getFullAccountName(account_info):\n
\n \n
\n \n
# look at inventories to decide which sections will be shown\n # look at inventories to decide which sections will be shown\n
balance_sheet_account_type_list = [c[0] for c in \n balance_sheet_account_type_list = [c[0] for c in\n
cat_tool.account_type.asset.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False ) + \\\n cat_tool.account_type.asset.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False ) + \\\n
cat_tool.account_type.equity.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) + \\\n cat_tool.account_type.equity.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) + \\\n
cat_tool.account_type.liability.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) ]\n cat_tool.account_type.liability.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) ]\n
......
...@@ -284,7 +284,7 @@ ...@@ -284,7 +284,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: context.AccountModule_getBankAccountItemList( section_category=request.get(\'your_section_category\'), section_category_strict_membership=request.get(\'your_section_category_strict\'))</string> </value> <value> <string>python: context.AccountModule_getBankAccountItemList( section_category=request.get(\'your_section_category\', request.get(\'field_your_section_category\', preferences.getPreferredAccountingTransactionSectionCategory())), section_category_strict_membership=request.get(\'your_section_category_strict\'))</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
"""Reset the grouping reference after a copy & paste.\n """Reset the grouping reference after a copy & paste.\n
"""\n """\n
context.setGroupingReference(None)\n context.setGroupingReference(None)\n
context.setGroupingDate(None)\n
]]></string> </value> ]]></string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""This script is a placeholder for projects to implement extra constraint to prevent grouping of accounting transaction lines.\n
Note that the sequence of letters will still remain unique for section, mirror_section and node, regardless of extra grouping parameters.\n
\n
For instance, we can refuse to group together lines for different order by returning the reference of the order in that script.\n
\n
The returned value must be hashable.\n
"""\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>source=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>AccountingTransactionLine_getGroupingExtraParameterList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -90,11 +90,12 @@ line_list = portal.portal_simulation.getMovementHistoryList(\n ...@@ -90,11 +90,12 @@ line_list = portal.portal_simulation.getMovementHistoryList(\n
mirror_section_uid=mirror_section_uid)\n mirror_section_uid=mirror_section_uid)\n
\n \n
# If the group is still valid, we may want to keep it as is.\n # If the group is still valid, we may want to keep it as is.\n
if round(sum([(l.total_price or 0) for l in line_list]), precision) == 0 and keep_if_valid_group:\n if keep_if_valid_group and round(sum([(l.total_price or 0) for l in line_list]), precision) == 0:\n
return\n return\n
\n \n
for line in line_list:\n for line in line_list:\n
line.setGroupingReference(None)\n line.setGroupingReference(None)\n
line.setGroupingDate(None)\n
\n \n
return line_list\n return line_list\n
</string> </value> </string> </value>
......
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
<string>my_source_credit</string> <string>my_source_credit</string>
<string>my_resource</string> <string>my_resource</string>
<string>my_grouping_reference</string> <string>my_grouping_reference</string>
<string>my_grouping_date</string>
</list> </list>
</value> </value>
</item> </item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_grouping_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Grouping Date</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
<string>my_destination_credit</string> <string>my_destination_credit</string>
<string>my_resource</string> <string>my_resource</string>
<string>my_grouping_reference</string> <string>my_grouping_reference</string>
<string>my_grouping_date</string>
</list> </list>
</value> </value>
</item> </item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_grouping_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Grouping Date</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,7 +50,10 @@ ...@@ -50,7 +50,10 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>sort_dict = { \'income\': 0,\n <value> <string>if not portal_type:\n
portal_type = context.getPortalObject().getPortalAccountingMovementTypeList()\n
\n
sort_dict = { \'income\': 0,\n
\'expense\': -2,\n \'expense\': -2,\n
\'receivable\': -2,\n \'receivable\': -2,\n
\'payable\': 0,\n \'payable\': 0,\n
...@@ -60,10 +63,7 @@ ...@@ -60,10 +63,7 @@
def getAccountingTransactionLineSortKey(line):\n def getAccountingTransactionLineSortKey(line):\n
return sort_dict.get(line.getId(), line.getIntIndex() or line.getIntId())\n return sort_dict.get(line.getId(), line.getIntIndex() or line.getIntId())\n
\n \n
object_list = list(context.contentValues(\n return sorted(context.contentValues(portal_type=portal_type), key=getAccountingTransactionLineSortKey)\n
filter={\'portal_type\': portal_type}))\n
object_list.sort(key=getAccountingTransactionLineSortKey)\n
return object_list\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
...@@ -50,17 +50,18 @@ ...@@ -50,17 +50,18 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string>"""Guess a grouping references for lines whose uids are passed as\n
"""Guess a grouping references for lines whose uids are passed as\n
accounting_transaction_line_uid_list.\n accounting_transaction_line_uid_list.\n
If accounting_transaction_line_uid_list is not passed, this script assumes that\n If accounting_transaction_line_uid_list is not passed, this script assumes that\n
it\'s called on the context of an accounting transaction and it guess the group\n it\'s called on the context of an accounting transaction and it guess the grouping\n
of accounting transaction using causality relations.\n of related accounting transactions using causality.\n
"""\n """\n
\n \n
# this dict associates (node, section, mirror_section) to a list of\n from Products.ERP5Type.Utils import int2letter\n
# accounting lines info (ie total_price and path).\n \n
# this dict associates (node, section, mirror_section,\n
# extra_grouping_parameter) to a list of\n
# accounting lines info (total_price, date and path).\n
lines_per_node = {}\n lines_per_node = {}\n
\n \n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
...@@ -69,15 +70,6 @@ ctool = portal.portal_catalog\n ...@@ -69,15 +70,6 @@ ctool = portal.portal_catalog\n
allow_grouping_with_different_quantity = portal.portal_preferences.getPreference(\n allow_grouping_with_different_quantity = portal.portal_preferences.getPreference(\n
\'preferred_grouping_with_different_quantities\', 0)\n \'preferred_grouping_with_different_quantities\', 0)\n
\n \n
def int2letter(i):\n
"""Convert an integer to letters, to use as a grouping reference code.\n
A, B, C ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA ...\n
"""\n
if i < 26:\n
return (chr(i + ord(\'A\')))\n
d, m = divmod(i, 26)\n
return int2letter(d - 1) + int2letter(m)\n
\n
\n \n
accounting_transaction_line_value_list = []\n accounting_transaction_line_value_list = []\n
if accounting_transaction_line_uid_list is None:\n if accounting_transaction_line_uid_list is None:\n
...@@ -107,8 +99,11 @@ for line in accounting_transaction_line_value_list:\n ...@@ -107,8 +99,11 @@ for line in accounting_transaction_line_value_list:\n
lines_per_node.setdefault(\n lines_per_node.setdefault(\n
(line.getSource(portal_type=\'Account\'),\n (line.getSource(portal_type=\'Account\'),\n
section_relative_url,\n section_relative_url,\n
line.getDestinationSection(), ), []).append(\n line.getDestinationSection(),\n
line.AccountingTransactionLine_getGroupingExtraParameterList(source=True),\n
), []).append(\n
dict(total_price=line.getSourceInventoriatedTotalAssetPrice() or 0,\n dict(total_price=line.getSourceInventoriatedTotalAssetPrice() or 0,\n
date=line.getStartDate(),\n
path=line.getRelativeUrl()))\n path=line.getRelativeUrl()))\n
else:\n else:\n
section_relative_url = None\n section_relative_url = None\n
...@@ -121,12 +116,15 @@ for line in accounting_transaction_line_value_list:\n ...@@ -121,12 +116,15 @@ for line in accounting_transaction_line_value_list:\n
lines_per_node.setdefault(\n lines_per_node.setdefault(\n
(line.getDestination(portal_type=\'Account\'),\n (line.getDestination(portal_type=\'Account\'),\n
section_relative_url,\n section_relative_url,\n
line.getSourceSection(), ), []).append(\n line.getSourceSection(),\n
line.AccountingTransactionLine_getGroupingExtraParameterList(source=False),\n
), []).append(\n
dict(total_price=line.getDestinationInventoriatedTotalAssetPrice() or 0,\n dict(total_price=line.getDestinationInventoriatedTotalAssetPrice() or 0,\n
date=line.getStopDate(),\n
path=line.getRelativeUrl()))\n path=line.getRelativeUrl()))\n
\n \n
changed_lines = []\n changed_line_list = []\n
for (node, section, mirror_section), line_info_list in lines_per_node.items():\n for (node, section, mirror_section, extra_parameter), line_info_list in lines_per_node.items():\n
if node is None:\n if node is None:\n
continue\n continue\n
total_price = sum([l[\'total_price\'] for l in line_info_list])\n total_price = sum([l[\'total_price\'] for l in line_info_list])\n
...@@ -143,20 +141,22 @@ for (node, section, mirror_section), line_info_list in lines_per_node.items():\n ...@@ -143,20 +141,22 @@ for (node, section, mirror_section), line_info_list in lines_per_node.items():\n
grouping_reference = portal.portal_ids.generateNewId(id_generator=\'uid\',\n grouping_reference = portal.portal_ids.generateNewId(id_generator=\'uid\',\n
id_group=id_group,\n id_group=id_group,\n
default=previous_default + 1)\n default=previous_default + 1)\n
\n \n
# convert from int to letters\n # convert from int to letters\n
string_reference = int2letter(grouping_reference)\n string_reference = int2letter(grouping_reference)\n
\n
# get the grouping date\n
date = max([line[\'date\'] for line in line_info_list])\n
\n \n
for line in line_info_list:\n for line in line_info_list:\n
line_obj = portal.restrictedTraverse(line[\'path\'])\n line_obj = portal.restrictedTraverse(line[\'path\'])\n
line_obj.setGroupingReference(string_reference)\n line_obj.setGroupingReference(string_reference)\n
line_obj.setGroupingDate(date)\n
line_obj.reindexObject(activate_kw=dict(tag=\'accounting_grouping_reference\'))\n line_obj.reindexObject(activate_kw=dict(tag=\'accounting_grouping_reference\'))\n
changed_lines.append(line[\'path\'])\n changed_line_list.append(line[\'path\'])\n
\n \n
return changed_lines\n return changed_line_list\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
...@@ -68,7 +68,8 @@ params = {}\n ...@@ -68,7 +68,8 @@ params = {}\n
if kw.get(\'no_from_date\', False): from_date = None\n if kw.get(\'no_from_date\', False): from_date = None\n
\n \n
if simulation_state: params[\'simulation_state\'] = simulation_state\n if simulation_state: params[\'simulation_state\'] = simulation_state\n
if section_category: params[\'section_category\'] = section_category\n params[\'section_uid\'] = context.Base_getSectionUidListForSectionCategory(section_category)\n
\n
\n \n
if kw.has_key(\'node_uid\') : params[\'node_uid\'] = kw[\'node_uid\']\n if kw.has_key(\'node_uid\') : params[\'node_uid\'] = kw[\'node_uid\']\n
if kw.has_key(\'portal_type\'): params[\'portal_type\'] = kw[\'portal_type\']\n if kw.has_key(\'portal_type\'): params[\'portal_type\'] = kw[\'portal_type\']\n
...@@ -83,7 +84,7 @@ if from_date is not None:\n ...@@ -83,7 +84,7 @@ if from_date is not None:\n
get_inventory_kw.update({ \'omit_simulation\' : True\n get_inventory_kw.update({ \'omit_simulation\' : True\n
, \'payment_uid\' : context.getUid()\n , \'payment_uid\' : context.getUid()\n
, \'to_date\' : from_date\n , \'to_date\' : from_date\n
, \'where_expression\': " section.portal_type = \'Organisation\' "\n # , \'where_expression\': " section.portal_type = \'Organisation\' "\n
, \'stat\' : True\n , \'stat\' : True\n
})\n })\n
\n \n
......
...@@ -65,6 +65,7 @@ def getAccountingPeriodStartDateForSectionCategory(section_category, date):\n ...@@ -65,6 +65,7 @@ def getAccountingPeriodStartDateForSectionCategory(section_category, date):\n
section_category, strict_membership=False))\n section_category, strict_membership=False))\n
period_start_date = None\n period_start_date = None\n
for uid in section_uid:\n for uid in section_uid:\n
if uid == -1: continue # Base_getSectionUidListForSectionCategory returns [-1] if no section_uid exists \n
section = portal.portal_catalog.getObject(uid)\n section = portal.portal_catalog.getObject(uid)\n
for ap in section.contentValues(portal_type=\'Accounting Period\',\n for ap in section.contentValues(portal_type=\'Accounting Period\',\n
checked_permission=\'Access contents information\'):\n checked_permission=\'Access contents information\'):\n
......
...@@ -75,7 +75,7 @@ def getCurrencyForSection(section_url):\n ...@@ -75,7 +75,7 @@ def getCurrencyForSection(section_url):\n
return currency\n return currency\n
\n \n
# then from mapping category\n # then from mapping category\n
mapping = section.getMappingValue(portal_type=\'Organisation\')\n mapping = section.getMappingRelatedValue(portal_type=\'Organisation\')\n
if mapping is not None and mapping.getPriceCurrency():\n if mapping is not None and mapping.getPriceCurrency():\n
return mapping.getPriceCurrency()\n return mapping.getPriceCurrency()\n
\n \n
......
...@@ -75,6 +75,9 @@ Here, a group of movement means:\n ...@@ -75,6 +75,9 @@ Here, a group of movement means:\n
mirror_section_uid is the same\n mirror_section_uid is the same\n
node_uid is the same\n node_uid is the same\n
grouping_reference is the same\n grouping_reference is the same\n
\n
XXX now that grouping_date exists, this script will become useless.\n
\n
</dtml-comment>\n </dtml-comment>\n
\n \n
( SELECT catalog.path as path,\n ( SELECT catalog.path as path,\n
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
from Products.ZSQLCatalog.SQLCatalog import Query\n from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n
from Products.ERP5Type.Message import translateString\n from Products.ERP5Type.Message import translateString\n
from Products.ERP5Type.Log import log\n from Products.ERP5Type.Log import log\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
...@@ -137,11 +137,20 @@ if params.get(\'node_uid\'):\n ...@@ -137,11 +137,20 @@ if params.get(\'node_uid\'):\n
or node.isMemberOf(\'account_type/income\')\n or node.isMemberOf(\'account_type/income\')\n
\n \n
\n \n
period_start_date = params.pop(\'period_start_date\', None)\n
if is_pl_account and not from_date:\n if is_pl_account and not from_date:\n
from_date = params.get(\'period_start_date\')\n from_date = period_start_date\n
\n
if portal.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
if params.get(\'at_date\'):\n
params[\'grouping_query\'] = ComplexQuery(\n
Query(grouping_reference=None),\n
Query(grouping_date=params[\'at_date\'], range="min"),\n
operator="OR")\n
else:\n
params[\'grouping_reference\'] = None\n
\n \n
if from_date or is_pl_account:\n if from_date or is_pl_account:\n
period_start_date = None\n
# Create a new parameter list to get the previous balance\n # Create a new parameter list to get the previous balance\n
get_inventory_kw = params.copy()\n get_inventory_kw = params.copy()\n
\n \n
...@@ -150,11 +159,10 @@ if from_date or is_pl_account:\n ...@@ -150,11 +159,10 @@ if from_date or is_pl_account:\n
# ignore any at_date that could lay in params\n # ignore any at_date that could lay in params\n
get_inventory_kw.pop(\'at_date\', None)\n get_inventory_kw.pop(\'at_date\', None)\n
\n \n
if params.has_key(\'period_start_date\'):\n if period_start_date:\n
if is_pl_account:\n if is_pl_account:\n
# if we have on an expense / income account, only take into account\n # if we have on an expense / income account, only take into account\n
# movements from the current period.\n # movements from the current period.\n
period_start_date = params[\'period_start_date\']\n
if initial_balance_from_date:\n if initial_balance_from_date:\n
initial_balance_from_date = max(period_start_date,\n initial_balance_from_date = max(period_start_date,\n
initial_balance_from_date)\n initial_balance_from_date)\n
...@@ -162,7 +170,6 @@ if from_date or is_pl_account:\n ...@@ -162,7 +170,6 @@ if from_date or is_pl_account:\n
initial_balance_from_date = period_start_date\n initial_balance_from_date = period_start_date\n
else:\n else:\n
# for all other accounts, we calculate initial balance\n # for all other accounts, we calculate initial balance\n
period_start_date = params[\'period_start_date\']\n
if not initial_balance_from_date:\n if not initial_balance_from_date:\n
# I don\'t think this should happen\n # I don\'t think this should happen\n
log(\'from_date not passed, defaulting to period_start_date\')\n log(\'from_date not passed, defaulting to period_start_date\')\n
...@@ -230,8 +237,6 @@ if from_date or is_pl_account:\n ...@@ -230,8 +237,6 @@ if from_date or is_pl_account:\n
previous_balance.edit(Movement_getExplanationTitle=\'\')\n previous_balance.edit(Movement_getExplanationTitle=\'\')\n
\n \n
new_result = [previous_balance]\n new_result = [previous_balance]\n
if context.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
params[\'where_expression\'] = \'catalog.grouping_reference is NULL\'\n
new_result.extend(\n new_result.extend(\n
portal.portal_simulation.getMovementHistoryList(\n portal.portal_simulation.getMovementHistoryList(\n
from_date=from_date,\n from_date=from_date,\n
...@@ -244,9 +249,6 @@ if from_date or is_pl_account:\n ...@@ -244,9 +249,6 @@ if from_date or is_pl_account:\n
**params))\n **params))\n
return new_result\n return new_result\n
\n \n
if context.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
params[\'where_expression\'] = \'catalog.grouping_reference is NULL\'\n
\n
# We try not to convert to a list, hence the copy & paste\n # We try not to convert to a list, hence the copy & paste\n
return portal.portal_simulation.getMovementHistoryList(\n return portal.portal_simulation.getMovementHistoryList(\n
from_date=from_date,\n from_date=from_date,\n
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>from Products.ZSQLCatalog.SQLCatalog import Query\n <value> <string>from Products.ZSQLCatalog.SQLCatalog import Query\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
\n
params = portal.ERP5Accounting_getParams(selection_name=selection_name)\n params = portal.ERP5Accounting_getParams(selection_name=selection_name)\n
getInventoryAssetPrice = portal.portal_simulation.getInventoryAssetPrice\n getInventoryAssetPrice = portal.portal_simulation.getInventoryAssetPrice\n
getSelectionDomainDictFor = context.portal_selections.getSelectionDomainDictFor\n getSelectionDomainDictFor = context.portal_selections.getSelectionDomainDictFor\n
...@@ -116,7 +117,9 @@ if kw.get(\'where_expression\'):\n ...@@ -116,7 +117,9 @@ if kw.get(\'where_expression\'):\n
if not \'parent_portal_type\' in params:\n if not \'parent_portal_type\' in params:\n
params.setdefault(\'portal_type\', portal.getPortalAccountingMovementTypeList())\n params.setdefault(\'portal_type\', portal.getPortalAccountingMovementTypeList())\n
\n \n
if params.get(\'period_start_date\', 0) and params.get(\'node_uid\'):\n period_start_date = params.pop(\'period_start_date\', None)\n
\n
if period_start_date and params.get(\'node_uid\'):\n
# find the node for this node_uid\n # find the node for this node_uid\n
if context.getUid() == params[\'node_uid\']: # I bet it\'s context\n if context.getUid() == params[\'node_uid\']: # I bet it\'s context\n
node = context\n node = context\n
...@@ -129,12 +132,11 @@ if params.get(\'period_start_date\', 0) and params.get(\'node_uid\'):\n ...@@ -129,12 +132,11 @@ if params.get(\'period_start_date\', 0) and params.get(\'node_uid\'):\n
# beginning is passed explicitly.\n # beginning is passed explicitly.\n
# if we are in the regular user interface, we only limit\n # if we are in the regular user interface, we only limit\n
if \'from_date\' in kw:\n if \'from_date\' in kw:\n
params[\'from_date\'] = min(kw[\'from_date\'], params[\'period_start_date\'])\n params[\'from_date\'] = min(kw[\'from_date\'], period_start_date)\n
else:\n else:\n
# for other account, we calculate the initial balance as the "absolute"\n # for other account, we calculate the initial balance as the "absolute"\n
# balance at the beginning of the period, plus debit or credit from this\n # balance at the beginning of the period, plus debit or credit from this\n
# beginning of period to the from_date\n # beginning of period to the from_date\n
period_start_date = params[\'period_start_date\']\n
at_date = params.pop(\'at_date\', None)\n at_date = params.pop(\'at_date\', None)\n
period_openning_balance = getInventoryAssetPrice(\n period_openning_balance = getInventoryAssetPrice(\n
selection_domain=getSelectionDomainDictFor(selection_name),\n selection_domain=getSelectionDomainDictFor(selection_name),\n
......
1483 1505
\ No newline at end of file \ No newline at end of file
...@@ -135,6 +135,14 @@ ...@@ -135,6 +135,14 @@
<string>owner_title</string> <string>owner_title</string>
<string>Owner</string> <string>Owner</string>
</tuple> </tuple>
<tuple>
<string>creation_date</string>
<string>Creation Date</string>
</tuple>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list> </list>
</value> </value>
</item> </item>
...@@ -170,10 +178,6 @@ ...@@ -170,10 +178,6 @@
<string>translated_simulation_state_title</string> <string>translated_simulation_state_title</string>
<string>State</string> <string>State</string>
</tuple> </tuple>
<tuple>
<string>owner_title</string>
<string>Owner</string>
</tuple>
<tuple> <tuple>
<string>total_debit</string> <string>total_debit</string>
<string>Debit</string> <string>Debit</string>
......
2 3
\ No newline at end of file \ No newline at end of file
...@@ -85,43 +85,37 @@ Test changing state in accounting module (with custom search)\n ...@@ -85,43 +85,37 @@ Test changing state in accounting module (with custom search)\n
</tr>\n </tr>\n
<tr>\n <tr>\n
<td>assertText</td>\n <td>assertText</td>\n
<td>//span[@class="listbox-current-page-total-number"]</td>\n <td>//span[@class="listbox-current-page-total-number workflow_action_listbox-current-page-total-number"]</td>\n
<td>2 records</td>\n <td>2 records</td>\n
</tr>\n </tr>\n
<tr>\n <tr>\n
<td>assertText</td>\n <td>assertText</td>\n
<td>//tr[@class=\'listbox-data-line-0 DataA\']/td[1]/a</td>\n <td>//tr[@class=\'workflow_action_listbox-data-line-0 DataA\']/td[1]/a</td>\n
<td>1</td>\n <td>1</td>\n
</tr>\n </tr>\n
<tr>\n <tr>\n
<td>assertText</td>\n <td>assertText</td>\n
<td>//tr[@class=\'listbox-data-line-0 DataA\']/td[2]/a</td>\n <td>//tr[@class=\'workflow_action_listbox-data-line-0 DataA\']/td[2]/a</td>\n
<td>Accounting Transaction</td>\n <td>Accounting Transaction</td>\n
</tr>\n </tr>\n
<tr>\n <tr>\n
<td>assertText</td>\n <td>assertText</td>\n
<td>//tr[@class=\'listbox-data-line-0 DataA\']/td[3]/a</td>\n <td>//tr[@class=\'workflow_action_listbox-data-line-0 DataA\']/td[3]/a</td>\n
<td>Posted to General Ledger</td>\n <td>Posted to General Ledger</td>\n
</tr>\n </tr>\n
\n \n
<tr>\n <tr>\n
<td>select</td>\n <td>select</td>\n
<td>//tr[@class=\'listbox-data-line-0 DataA\']/td[5]/select</td>\n <td>//tr[@class=\'workflow_action_listbox-data-line-0 DataA\']/td[5]/select</td>\n
<td>label=Cancel Transaction</td>\n <td>label=Cancel Transaction</td>\n
</tr>\n </tr>\n
\n \n
\n
<tr>\n <tr>\n
<td>clickAndWait</td>\n <td>clickAndWait</td>\n
<td>Base_callDialogMethod:method</td>\n <td>Base_callDialogMethod:method</td>\n
<td></td>\n <td></td>\n
</tr>\n </tr>\n
\n \n
<tr>\n
<td>assertText</td>\n
<td>//span[@class="listbox-current-page-total-number"]</td>\n
<td>1 records</td>\n
</tr>\n
<tr>\n <tr>\n
<td>clickAndWait</td>\n <td>clickAndWait</td>\n
<td>Base_callDialogMethod:method</td>\n <td>Base_callDialogMethod:method</td>\n
......
188 189
\ No newline at end of file \ No newline at end of file
...@@ -389,7 +389,16 @@ ...@@ -389,7 +389,16 @@
<item> <item>
<key> <string>editable_columns</string> </key> <key> <string>editable_columns</string> </key>
<value> <value>
<list/> <list>
<tuple>
<string>quantity</string>
<string>Number</string>
</tuple>
<tuple>
<string>total_price</string>
<string>Amount</string>
</tuple>
</list>
</value> </value>
</item> </item>
<item> <item>
......
...@@ -114,9 +114,7 @@ ...@@ -114,9 +114,7 @@
</item> </item>
<item> <item>
<key> <string>default</string> </key> <key> <string>default</string> </key>
<value> <value> <string></string> </value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -203,7 +201,7 @@ ...@@ -203,7 +201,7 @@
</item> </item>
<item> <item>
<key> <string>editable</string> </key> <key> <string>editable</string> </key>
<value> <int>1</int> </value> <value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>enabled</string> </key> <key> <string>enabled</string> </key>
...@@ -231,11 +229,11 @@ ...@@ -231,11 +229,11 @@
</item> </item>
<item> <item>
<key> <string>required</string> </key> <key> <string>required</string> </key>
<value> <int>1</int> </value> <value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Montant</string> </value> <value> <string>Amount</string> </value>
</item> </item>
<item> <item>
<key> <string>whitespace_preserve</string> </key> <key> <string>whitespace_preserve</string> </key>
...@@ -247,23 +245,4 @@ ...@@ -247,23 +245,4 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<tuple>
<string>Products.Formulator.TALESField</string>
<string>TALESMethod</string>
</tuple>
<none/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.Integer_toString(int(here.getTotalPrice(fast=0)))</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData> </ZopeData>
...@@ -63,14 +63,15 @@ ...@@ -63,14 +63,15 @@
<value> <value>
<list> <list>
<string>listbox</string> <string>listbox</string>
<string>listbox_start_date</string>
</list> </list>
</value> </value>
</item> </item>
<item> <item>
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <value>
<list/> <list>
<string>listbox_start_date</string>
</list>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -50,27 +50,26 @@ ...@@ -50,27 +50,26 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>selection_name = \'workflow_action_dialog_proxy_selection\'\n <value> <string>from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n
selection_tool = context.getPortalObject().portal_selections\n
\n \n
selection_tool.setSelectionParamsFor(selection_name,\n portal = context.getPortalObject()\n
dict(proxy_form_id=form_id))\n
\n \n
request = container.REQUEST\n reference_list = [x.reference for x in\n
request.set(\'proxy_form_id\', form_id)\n portal.portal_catalog(SimpleQuery(reference=None,\n
request.set(\'reset\', 1)\n comparison_operator="is not"),\n
request.set(\'ignore_hide_rows\', 1)\n select_list=[\'reference\'],\n
portal_type="Person", title=value)]\n
\n \n
return context.Folder_viewWorkflowActionDocumentListDialogRenderer(REQUEST=request)\n return SimpleQuery(owner=reference_list or -1)\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>form_id=\'\', **kw</string> </value> <value> <string>value</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Folder_viewWorkflowActionDocumentListDialog</string> </value> <value> <string>SQLCatalog_makeOwnerTitleSearchQuery</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
<key>child_telephone_SearchableText | catalog,full_text/SearchableText/z_related_child_telephone</key> <key>child_telephone_SearchableText | catalog,full_text/SearchableText/z_related_child_telephone</key>
<key>default_email_text | catalog,email/url_string/z_related_default_email</key> <key>default_email_text | catalog,email/url_string/z_related_default_email</key>
<key>destination_person_title | category,catalog/title/z_related_destination_person</key> <key>destination_person_title | category,catalog/title/z_related_destination_person</key>
<key>owner_title | catalog/title/z_related_owner_title</key>
<key>related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use</key> <key>related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use</key>
<key>source_organisation_title | category,catalog/title/z_related_source_organisation</key> <key>source_organisation_title | category,catalog/title/z_related_source_organisation</key>
<key>source_person_title | category,catalog/title/z_related_source_person</key> <key>source_person_title | category,catalog/title/z_related_source_person</key>
......
<key_list>
<key>owner_title | SQLCatalog_makeOwnerTitleSearchQuery</key>
</key_list>
\ No newline at end of file
def generateBarcodeImage(self, barcode_type, data): def generateBarcodeImage(self, barcode_type, data, REQUEST=None):
# huBarcode's DataMatrix support has limitation for data size. # huBarcode's DataMatrix support has limitation for data size.
# huBarcode's QRCode support is broken. # huBarcode's QRCode support is broken.
# more 1-D barcode types can be added by pyBarcode library. # more 1-D barcode types can be added by pyBarcode library.
...@@ -30,7 +30,6 @@ def generateBarcodeImage(self, barcode_type, data): ...@@ -30,7 +30,6 @@ def generateBarcodeImage(self, barcode_type, data):
output = fp.read() output = fp.read()
else: else:
raise NotImplementedError, 'barcode_type=%s is not supported' % barcode_type raise NotImplementedError, 'barcode_type=%s is not supported' % barcode_type
RESPONSE = self.REQUEST.RESPONSE if REQUEST is not None:
RESPONSE.setHeader('Content-Type', 'image/png') REQUEST.RESPONSE.setHeader('Content-Type', 'image/png')
RESPONSE.setHeader('Content-Length', len(output))
return output return output
...@@ -55,14 +55,15 @@ ...@@ -55,14 +55,15 @@
This will only return organisations member of this section category.\n This will only return organisations member of this section category.\n
If \'strict_membership\' is true, then only organisations strictly member\n If \'strict_membership\' is true, then only organisations strictly member\n
of the category will be returned.\n of the category will be returned.\n
If no organisations are member of this section category, then [-1] is returned.\n
"""\n """\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
\n \n
section = portal.portal_categories.restrictedTraverse(section_category)\n section = portal.portal_categories.restrictedTraverse(section_category)\n
return [x.getUid() for x in\n return [x.uid for x in\n
section.getGroupRelatedValueList(portal_type=\'Organisation\',\n section.getGroupRelatedValueList(portal_type=\'Organisation\',\n
strict_membership=strict_membership,\n strict_membership=strict_membership,\n
checked_permission=\'View\')]\n checked_permission=\'View\')] or [-1]\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
...@@ -132,9 +132,20 @@ def getTaxLineList(order):\n ...@@ -132,9 +132,20 @@ def getTaxLineList(order):\n
return tax_line_list\n return tax_line_list\n
\n \n
\n \n
\n
line_base_contribution_list = []\n
number = 0\n
line_novat_totalprice = 0\n
line_list = []\n line_list = []\n
line_not_vat = []\n
line_vat = []\n
line_not_vat_has_no_vat = {}\n
total_price = 0.0\n total_price = 0.0\n
total_vat = 0.0\n total_vat = 0.0\n
total_vat_price = 0.0\n
vat_total_list = []\n
taxnumber = 0\n
taxname = \'\'\n
\n \n
def unicodeDict(d):\n def unicodeDict(d):\n
for k, v in d.items():\n for k, v in d.items():\n
...@@ -176,8 +187,23 @@ for line in getSubLineList(context):\n ...@@ -176,8 +187,23 @@ for line in getSubLineList(context):\n
display_id = \'translated_title\'\n display_id = \'translated_title\'\n
if request.get(\'international_form\'):\n if request.get(\'international_form\'):\n
display_id = \'title\'\n display_id = \'title\'\n
desc = (\', \'.join([x[0] for x in\n desc = (\', \'.join([x[0] for x in line.getVariationCategoryItemList(display_id=display_id)]),)\n
line.getVariationCategoryItemList(display_id=display_id)]),)\n is_vat=0\n
portal_preferences = context.getPortalObject().portal_preferences\n
if portal_preferences.getPreferredTaxUseList()==[] :\n
vat="use/trade/tax"\n
is_vat=line.isMemberOf(vat) \n
else:\n
vatlist=portal_preferences.getPreferredTaxUseList() \n
for vat in vatlist:\n
is_vat = is_vat or line.isMemberOf(vat)\n
if not is_vat:\n
if line.getBaseContribution() not in line_base_contribution_list:\n
line_base_contribution_list.append(line.getBaseContribution())\n
taxnumber=line_base_contribution_list.index(line.getBaseContribution())+1\n
else:\n
taxname=line.getBaseContribution()\n
\n
line_dict = {\n line_dict = {\n
\'style_name\': \'Table_20_Contents\',\n \'style_name\': \'Table_20_Contents\',\n
\'left_style_name\': \'Table_20_Contents_20_Left\',\n \'left_style_name\': \'Table_20_Contents_20_Left\',\n
...@@ -187,16 +213,44 @@ for line in getSubLineList(context):\n ...@@ -187,16 +213,44 @@ for line in getSubLineList(context):\n
\'reference\': line.getResource() is not None\\\n \'reference\': line.getResource() is not None\\\n
and line.getResourceValue().getReference() or \'\',\n and line.getResourceValue().getReference() or \'\',\n
\'description\': desc,\n \'description\': desc,\n
\'base_contribution\':line.getBaseContribution() or None,\n
\'use_type\':line.getResourceValue().getUse() or \'\',\n
\'use_type_tax\':is_vat,\n
\'total_quantity\': line.getTotalQuantity() or \'\',\n \'total_quantity\': line.getTotalQuantity() or \'\',\n
\'tax_name\':taxname or \'\',\n
\'tax_number\':taxnumber or \'\',\n
\'quantity_unit\': line.getQuantityUnitTranslatedTitle() or (\n \'quantity_unit\': line.getQuantityUnitTranslatedTitle() or (\n
line.getResource() and line.getResourceValue().getQuantityUnitTranslatedTitle()) or \'\',\n line.getResource() and line.getResourceValue().getQuantityUnitTranslatedTitle()) or \'\',\n
\'stop_date\': getOrderedDate(line.getStopDate()) or \'\',\n \'stop_date\': getOrderedDate(line.getStopDate()) or \'\',\n
\'base_price\': line.getPrice() or \'\',\n \'base_price\': line.getPrice() or \'\',\n
\'total_price\': line.getTotalPrice() or \'\',\n \'total_price\': line.getTotalPrice() or 0,\n
\'specialise_title\' : line.getProperty(\'specialise_title\', \'\'),\n \'specialise_title\' : line.getProperty(\'specialise_title\', \'\'),\n
}\n }\n
total_price += line.getTotalPrice() or 0.0\n \n
if line_dict[\'use_type_tax\']:\n
total_vat_price+=line.getTotalPrice() or 0.0\n
line_vat.append(unicodeDict(line_dict.copy()))\n
else:\n
total_price += line.getTotalPrice() or 0.0\n
line_not_vat.append(unicodeDict(line_dict.copy()))\n
if line_dict[\'base_contribution\'] is None:\n
line_novat_totalprice = line_novat_totalprice + line_dict[\'total_price\']\n
line_not_vat_has_no_vat = {\n
\'tax_name\': None ,\n
\'total_quantity\': line_novat_totalprice,\n
\'base_price\': 0.00 ,\n
\'total_price\': 0.00 ,\n
}\n
line_list.append(unicodeDict(line_dict.copy()))\n line_list.append(unicodeDict(line_dict.copy()))\n
if line_not_vat_has_no_vat != {} :\n
line_vat.append(unicodeDict(line_not_vat_has_no_vat.copy()))\n
for line_each in line_vat:\n
if line_each[\'tax_name\'] in line_base_contribution_list :\n
vatNumber=line_base_contribution_list.index(line_each[\'tax_name\'])+1\n
else:\n
vatNumber=0\n
line_each.update({\'vat_number\': vatNumber})\n
line_vat.sort(key=lambda obj:obj.get(\'vat_number\'))\n
\n \n
inch_cm_ratio = 2.54 / 100.0\n inch_cm_ratio = 2.54 / 100.0\n
\n \n
...@@ -397,11 +451,15 @@ data_dict = {\n ...@@ -397,11 +451,15 @@ data_dict = {\n
\'delivery_mode\': context.getDeliveryModeTranslatedTitle() or \'\',\n \'delivery_mode\': context.getDeliveryModeTranslatedTitle() or \'\',\n
\'incoterm\': context.getIncoterm() and context.getIncotermValue().getCodification() or \'\',\n \'incoterm\': context.getIncoterm() and context.getIncotermValue().getCodification() or \'\',\n
\n \n
\'vat_name_list\':line_base_contribution_list,\n
\'total_price\':total_price+total_vat_price,\n
\'total_price_novat\': total_price,\n \'total_price_novat\': total_price,\n
\'vat_list\': getTaxLineList(context),\n \'vat_list\': total_vat,\n
\'vat_total_price\':total_vat_price,\n
\'description\': getFieldAsLineList(context.getDescription()),\n \'description\': getFieldAsLineList(context.getDescription()),\n
\'specialise_title\': context.getProperty(\'specialise_title\',\'\'),\n \'specialise_title\': context.getProperty(\'specialise_title\',\'\'),\n
\n \'line_vat\':line_vat,\n
\'line_not_vat\':line_not_vat,\n
\'line_list\': line_list,\n \'line_list\': line_list,\n
}\n }\n
\n \n
......
1026 1031
\ No newline at end of file \ No newline at end of file
erp5_mysql_innodb/SQLCatalog_makeOwnerTitleSearchQuery
erp5_mysql_innodb/z_related_child_address erp5_mysql_innodb/z_related_child_address
erp5_mysql_innodb/z_related_child_telephone erp5_mysql_innodb/z_related_child_telephone
erp5_mysql_innodb/z_related_default_email erp5_mysql_innodb/z_related_default_email
erp5_mysql_innodb/z_related_destination_person erp5_mysql_innodb/z_related_destination_person
erp5_mysql_innodb/z_related_owner_title
erp5_mysql_innodb/z_related_resource_use erp5_mysql_innodb/z_related_resource_use
erp5_mysql_innodb/z_related_source_organisation erp5_mysql_innodb/z_related_source_organisation
erp5_mysql_innodb/z_related_source_person erp5_mysql_innodb/z_related_source_person
\ No newline at end of file
...@@ -3,6 +3,5 @@ source_person_title | category,catalog/title/z_related_source_person ...@@ -3,6 +3,5 @@ source_person_title | category,catalog/title/z_related_source_person
destination_person_title | category,catalog/title/z_related_destination_person destination_person_title | category,catalog/title/z_related_destination_person
default_email_text | catalog,email/url_string/z_related_default_email default_email_text | catalog,email/url_string/z_related_default_email
related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use related_resource_use_uid | category,category,catalog,catalog/uid/z_related_resource_use
owner_title | catalog/title/z_related_owner_title
child_address_SearchableText | catalog,full_text/SearchableText/z_related_child_address child_address_SearchableText | catalog,full_text/SearchableText/z_related_child_address
child_telephone_SearchableText | catalog,full_text/SearchableText/z_related_child_telephone child_telephone_SearchableText | catalog,full_text/SearchableText/z_related_child_telephone
\ No newline at end of file
owner_title | SQLCatalog_makeOwnerTitleSearchQuery
\ No newline at end of file
portal_introspections portal_introspections
\ No newline at end of file portal_solver_processes
\ No newline at end of file
...@@ -37,14 +37,13 @@ ...@@ -37,14 +37,13 @@
<value> <unicode encoding="cdata"><![CDATA[ <value> <unicode encoding="cdata"><![CDATA[
<h4 i18n:translate=""\n <h4 i18n:translate=""\n
i18n:domain="ui"> All needed information is collected.</h4>\n i18n:domain="ui"> You are going to install your selected configuration.</h4>\n
\n \n
<p i18n:translate=""\n <p i18n:translate=""\n
i18n:domain="ui">\n i18n:domain="ui">\n
Please proceed using Install button below. \n Please proceed using Install button below. \n
In the next page you will receive automatically updated installation status report.\n In the next page you will receive automatically updated installation status report.\n
</p>\n </p>
]]></unicode> </value> ]]></unicode> </value>
</item> </item>
......
545 547
\ No newline at end of file \ No newline at end of file
...@@ -211,7 +211,8 @@ system_prefs = dict(\n ...@@ -211,7 +211,8 @@ system_prefs = dict(\n
preferred_client_role_list = [\'client\'],\n preferred_client_role_list = [\'client\'],\n
preferred_sale_use_list = [\'trade/sale\'],\n preferred_sale_use_list = [\'trade/sale\'],\n
preferred_purchase_use_list = [\'trade/purchase\'],\n preferred_purchase_use_list = [\'trade/purchase\'],\n
preferred_packing_use_list = [\'trade/container\'])\n preferred_packing_use_list = [\'trade/container\'],\n
preferred_tax_use_list=[\'trade/tax\'])\n
\n \n
configuration_save.addConfigurationItem(\n configuration_save.addConfigurationItem(\n
\'System Preference Configurator Item\',\n \'System Preference Configurator Item\',\n
......
...@@ -36,7 +36,6 @@ from Products.ERP5Type.tests.runUnitTest import tests_home ...@@ -36,7 +36,6 @@ from Products.ERP5Type.tests.runUnitTest import tests_home
from Products.ERP5Type.tests.utils import FileUpload from Products.ERP5Type.tests.utils import FileUpload
from Products.ERP5Configurator.tests.ConfiguratorTestMixin import \ from Products.ERP5Configurator.tests.ConfiguratorTestMixin import \
TestLiveConfiguratorWorkflowMixin TestLiveConfiguratorWorkflowMixin
from AccessControl import Unauthorized
class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin): class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin):
""" """
...@@ -367,6 +366,7 @@ class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -367,6 +366,7 @@ class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin):
self.assertEquals(['trade/sale'], preference_tool.getPreferredSaleUseList()) self.assertEquals(['trade/sale'], preference_tool.getPreferredSaleUseList())
self.assertEquals(['trade/purchase'], preference_tool.getPreferredPurchaseUseList()) self.assertEquals(['trade/purchase'], preference_tool.getPreferredPurchaseUseList())
self.assertEquals(['trade/container'], preference_tool.getPreferredPackingUseList()) self.assertEquals(['trade/container'], preference_tool.getPreferredPackingUseList())
self.assertEquals(['trade/tax'], preference_tool.getPreferredTaxUseList())
def stepCheckModulesBusinessApplication(self, sequence=None, sequence_list=None, **kw): def stepCheckModulesBusinessApplication(self, sequence=None, sequence_list=None, **kw):
""" """
......
641 645
\ No newline at end of file \ No newline at end of file
417 418
\ No newline at end of file \ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>table_0\r\n
table_1\r\n
</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_related_destination_decision_versioning</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-var table_1>.uid = <dtml-var table_0>.category_uid\n
AND <dtml-var table_0>.base_category_uid = <dtml-var "portal_categories.destination_decision.getUid()">\n
AND <dtml-var table_0>.uid = catalog.uid\n
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<key_list> <key_list>
<key>destination_decision_language | category,versioning/language/z_related_destination_decision_versioning</key>
<key>event_causality_ticket_uid | category,catalog,category,catalog/uid/z_related_event_causality_ticket</key> <key>event_causality_ticket_uid | category,catalog,category,catalog/uid/z_related_event_causality_ticket</key>
<key>related_source_decision_or_destination_decision | category,catalog,catalog/uid/z_related_source_decision_or_destination_decision</key> <key>related_source_decision_or_destination_decision | category,catalog,catalog/uid/z_related_source_decision_or_destination_decision</key>
<key>related_source_or_destination | category,catalog,catalog/uid/z_related_source_or_destination</key> <key>related_source_or_destination | category,catalog,catalog/uid/z_related_source_or_destination</key>
......
...@@ -10,15 +10,16 @@ ...@@ -10,15 +10,16 @@
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list> <list>
<string>editable_columns</string> <string>columns</string>
<string>sort</string>
<string>description</string>
<string>title</string>
<string>count_method</string> <string>count_method</string>
<string>selection_name</string> <string>description</string>
<string>editable</string>
<string>editable_columns</string>
<string>list_method</string> <string>list_method</string>
<string>portal_types</string> <string>portal_types</string>
<string>columns</string> <string>selection_name</string>
<string>sort</string>
<string>title</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -130,6 +131,10 @@ ...@@ -130,6 +131,10 @@
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>List of all events related to the follow up ticket</string> </value> <value> <string>List of all events related to the follow up ticket</string> </value>
</item> </item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>editable_columns</string> </key> <key> <string>editable_columns</string> </key>
<value> <value>
...@@ -237,10 +242,7 @@ ...@@ -237,10 +242,7 @@
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<tuple> <global name="Method" module="Products.Formulator.MethodField"/>
<global name="Method" module="Products.Formulator.MethodField"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -253,10 +255,7 @@ ...@@ -253,10 +255,7 @@
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<tuple> <global name="Method" module="Products.Formulator.MethodField"/>
<global name="Method" module="Products.Formulator.MethodField"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
......
2012-10-30 Kazuhiko
* add destination_decision_language related key.
2011-12-13 Kazuhiko 2011-12-13 Kazuhiko
* use event_simulation_workflow instead of event_workflow for Event-type portal types. use portal_alarms/upgrader_migrate_event_workflow_history for migration. * use event_simulation_workflow instead of event_workflow for Event-type portal types. use portal_alarms/upgrader_migrate_event_workflow_history for migration.
......
597 599
\ No newline at end of file \ No newline at end of file
erp5_mysql_innodb/z_related_destination_decision_versioning
erp5_mysql_innodb/z_related_event_causality_ticket erp5_mysql_innodb/z_related_event_causality_ticket
erp5_mysql_innodb/z_related_source_decision_or_destination_decision erp5_mysql_innodb/z_related_source_decision_or_destination_decision
erp5_mysql_innodb/z_related_source_or_destination erp5_mysql_innodb/z_related_source_or_destination
......
...@@ -4,4 +4,5 @@ related_source_or_destination | category,catalog,catalog/uid/z_related_source_or ...@@ -4,4 +4,5 @@ related_source_or_destination | category,catalog,catalog/uid/z_related_source_or
related_source_section_or_destination_section | category,catalog,catalog/uid/z_related_source_section_or_destination_section related_source_section_or_destination_section | category,catalog,catalog/uid/z_related_source_section_or_destination_section
related_source_decision_or_destination_decision | category,catalog,catalog/uid/z_related_source_decision_or_destination_decision related_source_decision_or_destination_decision | category,catalog,catalog/uid/z_related_source_decision_or_destination_decision
related_source_or_source_decision_or_destination_or_destination_decision | category,catalog,catalog/uid/z_related_source_or_source_decision_or_destination_or_destination_decision related_source_or_source_decision_or_destination_or_destination_decision | category,catalog,catalog/uid/z_related_source_or_source_decision_or_destination_or_destination_decision
related_source_or_source_section_or_destination_or_destination_section | category,catalog,catalog/uid/z_related_source_or_source_section_or_destination_or_destination_section related_source_or_source_section_or_destination_or_destination_section | category,catalog,catalog/uid/z_related_source_or_source_section_or_destination_or_destination_section
\ No newline at end of file destination_decision_language | category,versioning/language/z_related_destination_decision_versioning
\ No newline at end of file
...@@ -83,7 +83,7 @@ for k, v in request.form.items():\n ...@@ -83,7 +83,7 @@ for k, v in request.form.items():\n
\'PUBLISHED\', \'AcceptLanguage\', \'AcceptCharset\', \'RESPONSE\',\n \'PUBLISHED\', \'AcceptLanguage\', \'AcceptCharset\', \'RESPONSE\',\n
\'ACTUAL_URL\'):\n \'ACTUAL_URL\'):\n
# XXX proxy fields stores a cache in request.other that cannot be pickled\n # XXX proxy fields stores a cache in request.other that cannot be pickled\n
if k.startswith(\'field__proxyfield\'):\n if str(k).startswith(\'field__proxyfield\'):\n
continue\n continue\n
# Remove FileUpload parameters\n # Remove FileUpload parameters\n
elif getattr(v, \'headers\', \'\'):\n elif getattr(v, \'headers\', \'\'):\n
......
...@@ -53,9 +53,6 @@ ...@@ -53,9 +53,6 @@
<value> <string>request = container.REQUEST\n <value> <string>request = container.REQUEST\n
RESPONSE = request.RESPONSE\n RESPONSE = request.RESPONSE\n
\n \n
format = request.get(\'format\', \'\')\n
skin_name = request[\'deferred_portal_skin\']\n
\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
N_ = portal.Base_translateString\n N_ = portal.Base_translateString\n
\n \n
...@@ -69,23 +66,13 @@ if person_value.getDefaultEmailText(\'\') in (\'\', None):\n ...@@ -69,23 +66,13 @@ if person_value.getDefaultEmailText(\'\') in (\'\', None):\n
portal.changeSkin(None)\n portal.changeSkin(None)\n
return context.Base_redirect(\'view\', keep_items=dict(\n return context.Base_redirect(\'view\', keep_items=dict(\n
portal_status_message=N_("You haven\'t defined your email address")))\n portal_status_message=N_("You haven\'t defined your email address")))\n
\n
active_process = portal.portal_activities.newActiveProcess()\n
user_name = person_value.getReference()\n
\n \n
tag = \'active-report-%s\' % random.randint(0, 1000)\n
priority = 3\n
\n \n
# compute list of report section to render\n user_name = person_value.getReference()\n
if form.meta_type == \'ERP5 Report\':\n tag = \'active-report-%s\' % random.randint(0, 1000)\n
report_section_list = getattr(context, form.report_method)()\n priority = 2\n
elif form.meta_type == \'ERP5 Form\':\n format = request.get(\'format\', \'\')\n
report_section_list = []\n skin_name = request[\'deferred_portal_skin\']\n
for field in form.get_fields():\n
if field.getRecursiveTemplateField().meta_type == \'ReportBox\':\n
report_section_list.extend(field.render())\n
else:\n
raise ValueError, \'form meta_type unknown\'\n
\n \n
# save request parameters (after calling the report_method which may tweak the\n # save request parameters (after calling the report_method which may tweak the\n
# request). XXX we exclude some reserved names in a very ad hoc way\n # request). XXX we exclude some reserved names in a very ad hoc way\n
...@@ -96,45 +83,25 @@ for k, v in request.items():\n ...@@ -96,45 +83,25 @@ for k, v in request.items():\n
\'PUBLISHED\', \'AcceptLanguage\', \'AcceptCharset\', \'RESPONSE\', \'SESSION\',\n \'PUBLISHED\', \'AcceptLanguage\', \'AcceptCharset\', \'RESPONSE\', \'SESSION\',\n
\'ACTUAL_URL\'):\n \'ACTUAL_URL\'):\n
# XXX proxy fields stores a cache in request.other that cannot be pickled\n # XXX proxy fields stores a cache in request.other that cannot be pickled\n
if k.startswith(\'field__proxyfield\'):\n if same_type(k, \'\') and k.startswith(\'field__proxyfield\'):\n
continue\n continue\n
# Remove FileUpload parameters\n # Remove FileUpload parameters\n
elif getattr(v, \'headers\', \'\'):\n elif getattr(v, \'headers\', \'\'):\n
continue\n continue\n
request_other[k] = v\n request_other[k] = v\n
\n \n
localizer_language = portal.Localizer.get_selected_language()\n
\n
for idx, report_section in enumerate(report_section_list):\n
if report_section.getPath():\n
doc = report_section.getObject(portal)\n
else:\n
doc = context\n
doc.activate(activity=\'SQLQueue\',\n
active_process=active_process,\n
tag=tag,\n
priority=priority,\n
).Base_renderReportSection(skin_name=skin_name,\n
localizer_language=localizer_language,\n
report_section=report_section,\n
report_section_idx=idx,\n
request_other=request_other)\n
\n \n
activity_context = context\n
if activity_context == portal:\n
# portal is not an active object\n
activity_context = portal.portal_simulation\n
\n \n
activity_context.activate(activity=\'SQLQueue\', after_tag=tag, priority=priority).Base_report(\n context.activate(activity="SQLQueue", tag=tag, \n
active_process_url=active_process.getRelativeUrl(),\n priority=priority).Base_computeReportSection(\n
skin_name=skin_name,\n form=form.getId(), \n
localizer_language=localizer_language,\n request_other=request_other, \n
title=N_(form.getProperty(\'title\')),\n user_name=user_name, \n
request_other=request_other,\n tag=tag,\n
form_path=form.getPhysicalPath(),\n skin_name=skin_name, \n
user_name=user_name,\n format=format,\n
format=format,\n priority=priority, \n
)\n **kw)\n
\n \n
context.activate(activity=\'SQLQueue\', after_tag=tag).getTitle()\n context.activate(activity=\'SQLQueue\', after_tag=tag).getTitle()\n
\n \n
......
...@@ -50,73 +50,88 @@ ...@@ -50,73 +50,88 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Log import log\n <value> <string>portal = context.getPortalObject()\n
portal = context.getPortalObject()\n N_ = portal.Base_translateString\n
portal_preferences = portal.portal_preferences\n
system_preference = None\n
clear_cache = 0\n
conversion_check = False\n
\n \n
log(conversion_server)\n form = context.restrictedTraverse(form)\n
log(kumo)\n request = container.REQUEST\n
log(memcached)\n request.other.update(request_other)\n
\n \n
if form.meta_type == \'ERP5 Report\':\n
report_section_list = getattr(context, form.report_method)()\n
elif form.meta_type == \'ERP5 Form\':\n
report_section_list = []\n
for field in form.get_fields():\n
if field.getRecursiveTemplateField().meta_type == \'ReportBox\':\n
report_section_list.extend(field.render())\n
else:\n
raise ValueError, \'form meta_type (%r) unknown\' %(form.meta_type,)\n
\n \n
if conversion_server is not None:\n # Rebuild request_other as report section can have modify request content\n
conversion_server_address, conversion_server_port = conversion_server.split(":")\n request_other = dict()\n
for k, v in request.items():\n
if k not in (\'TraversalRequestNameStack\', \'AUTHENTICATED_USER\', \'URL\',\n
\'SERVER_URL\', \'AUTHENTICATION_PATH\', \'USER_PREF_LANGUAGES\', \'PARENTS\',\n
\'PUBLISHED\', \'AcceptLanguage\', \'AcceptCharset\', \'RESPONSE\', \'SESSION\',\n
\'ACTUAL_URL\'):\n
# XXX proxy fields stores a cache in request.other that cannot be pickled\n
if same_type(k, \'\') and str(k).startswith(\'field__proxyfield\'):\n
continue\n
# Remove FileUpload parameters\n
elif getattr(v, \'headers\', \'\'):\n
continue\n
request_other[k] = v\n
\n \n
def getActiveSystemPreference():\n localizer_language = portal.Localizer.get_selected_language()\n
system_preference = portal_preferences.getActiveSystemPreference()\n active_process = portal.portal_activities.newActiveProcess()\n
if system_preference is None:\n
system_preference = portal_preferences.newContent(\n
portal_type="System Preference", \n
title="Automatically Created.")\n
system_preference.enable()\n
return system_preference\n
\n \n
if portal_preferences.getPreferredOoodocServerAddress() != conversion_server_address:\n for idx, report_section in enumerate(report_section_list):\n
system_preference = getActiveSystemPreference()\n if report_section.getPath():\n
system_preference.setPreferredOoodocServerAddress(conversion_server_address)\n doc = report_section.getObject(portal)\n
clear_cache = 1\n else:\n
doc = context\n
doc.activate(activity=\'SQLQueue\',\n
active_process=active_process,\n
tag=tag,\n
priority=priority,\n
).Base_renderReportSection(skin_name=skin_name,\n
localizer_language=localizer_language,\n
report_section=report_section,\n
report_section_idx=idx,\n
request_other=request_other)\n
\n \n
if int(portal_preferences.getPreferredOoodocServerPortNumber("-1")) != int(conversion_server_port):\n activity_context = context\n
if system_preference is None:\n if activity_context == portal:\n
system_preference = getActiveSystemPreference()\n # portal is not an active object\n
system_preference.setPreferredOoodocServerPortNumber(int(conversion_server_port))\n activity_context = portal.portal_simulation\n
clear_cache = 1\n
\n \n
if memcached is not None:\n activity_context.activate(activity=\'SQLQueue\', after_tag=tag, priority=priority).Base_report(\n
default_memcached_plugin = getattr(portal.portal_memcached, "default_memcached_plugin", None)\n active_process_url=active_process.getRelativeUrl(),\n
if default_memcached_plugin.getUrlString() != memcached:\n skin_name=skin_name,\n
default_memcached_plugin.setUrlString(memcached)\n localizer_language=localizer_language,\n
\n title=N_(form.getProperty(\'title\')),\n
if kumo is not None:\n request_other=request_other,\n
persistent_memcached_plugin = getattr(portal.portal_memcached, "persistent_memcached_plugin", None)\n form_path=form.getPhysicalPath(),\n
if persistent_memcached_plugin is not None:\n user_name=user_name,\n
if persistent_memcached_plugin.getUrlString() != kumo:\n format=format,\n
persistent_memcached_plugin.setUrlString(kumo)\n )\n
\n
\n
if clear_cache:\n
portal.portal_caches.clearAllCache()\n
\n
if conversion_server is not None:\n
conversion_check = (portal_preferences.getPreferredOoodocServerAddress() == conversion_server_address) and \\\n
(int(portal_preferences.getPreferredOoodocServerPortNumber()) == int(conversion_server_port))\n
\n
return conversion_check and \\\n
default_memcached_plugin.getUrlString() == memcached and \\\n
persistent_memcached_plugin is not None and \\\n
persistent_memcached_plugin.getUrlString() == kumo\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>conversion_server=None, memcached=None, kumo=None, **kw</string> </value> <value> <string>form, request_other, user_name, tag, skin_name, format, priority, **kw</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>ERP5Site_assertExternalServiceList</string> </value> <value> <string>Base_computeReportSection</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -76,7 +76,7 @@ attachment_list = (\n ...@@ -76,7 +76,7 @@ attachment_list = (\n
# XXX Use notification message to improve message content\n # XXX Use notification message to improve message content\n
portal.portal_notifications.sendMessage(\n portal.portal_notifications.sendMessage(\n
recipient=user_name,\n recipient=user_name,\n
subject=attachment_name.rsplit(\'.\', 1)[0],\n subject=str(attachment_name.rsplit(\'.\', 1)[0]),\n
message=str(translateString(\'Your report is attached.\\n\')),\n message=str(translateString(\'Your report is attached.\\n\')),\n
message_text_format=\'text/plain\',\n message_text_format=\'text/plain\',\n
notifier_list=(\'Mail Message\',),\n notifier_list=(\'Mail Message\',),\n
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Generate reference from a string by escaping all non ascii characters.\n
XXX: add support for non-ascii characters using unidecode python library\n
"""\n
transliterate_list = [\'?\', \':\', \';\', \'/\', \'&\', \'=\', \'^\', \'@\', \'>\', \'<\', \']\', \'[\', \'^\', \'\\\\\']\n
\n
def removeNonAscii(s): \n
return "".join(i for i in s if ord(i)>44 and ord(i)<123)\n
\n
# reference can be used for permanent URL so be friendly to spaces (SEO)\n
s = s.strip()\n
s =s.replace(\' \', \'-\')\n
\n
s = removeNonAscii(s)\n
for item in transliterate_list:\n
s = s.replace(item, \'-\')\n
\n
return s.strip(\'-\')\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>s</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_generateReferenceFromString</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -52,39 +52,38 @@ ...@@ -52,39 +52,38 @@
discussion_post_stripped_html discussion_post_object/asStrippedHTML;\n discussion_post_stripped_html discussion_post_object/asStrippedHTML;\n
isUserAllowedToPost python: discussion_post_object.getParentValue().DiscussionThread_isUserAllowedToPost()">\n isUserAllowedToPost python: discussion_post_object.getParentValue().DiscussionThread_isUserAllowedToPost()">\n
\n \n
<div class="discussion-post-header"\n <div class="discussion-post-header">\n
tal:attributes="style python: test(is_author_thumbnai_available, \'height:104px\',\'\')">\n
\n \n
<div class="thumbnail"\n <div class="thumbnail"\n
tal:condition="is_author_thumbnai_available">\n tal:condition="is_author_thumbnai_available">\n
<img tal:attributes="src string:${author_thumbnail_url}?display=thumbnail&format=png"/>\n <img tal:attributes="src string:${author_thumbnail_url}?display=thumbnail&amp;format=png" />\n
</div>\n </div>\n
\n \n
<div class="title">\n <div class="title">\n
<a class="discussion-post-title"\n <a class="discussion-post-title"\n
tal:attributes="href string:${discussion_post_url}/view;\n tal:attributes="href string:${discussion_post_url}/view;\n
name discussion_post_uid"\n name discussion_post_uid"\n
tal:content="discussion_post_title"/>\n tal:content="discussion_post_title"></a>\n
by\n by\n
<a class="discussion-post-creator-title-link"\n <a class="discussion-post-creator-title-link"\n
tal:attributes="href author_url"\n tal:attributes="href author_url"\n
tal:content="author_title"/>\n tal:content="author_title"></a>\n
at \n at \n
<span tal:content="discussion_post_creation_date" />\n <span tal:content="discussion_post_creation_date"></span>\n
</div>\n </div>\n
\n \n
</div>\n </div>\n
\n \n
<div class="discussion-post-body-container"\n <div class="discussion-post-body-container"\n
tal:content="structure discussion_post_stripped_html"/>\n tal:content="structure discussion_post_stripped_html"></div>\n
\n \n
<div tal:condition="python: author_signature is not None"\n <div tal:condition="python: author_signature is not None"\n
class="discussion-post-author-signature-container"\n class="discussion-post-author-signature-container"\n
tal:content="author_signature"/>\n tal:content="author_signature"></div>\n
\n \n
<div class="discussion-post-actions">\n <div class="discussion-post-actions">\n
<button tal:condition="isUserAllowedToPost" type="submit"\n <button tal:condition="isUserAllowedToPost"\n
title="Reply"\n type="submit" title="Reply"\n
name="DiscussionThread_redirectCreateNewDiscussionPost:method"\n name="DiscussionThread_redirectCreateNewDiscussionPost:method"\n
tal:attributes="onClick python: \'redirectCreateCitedNewDiscussionPost(\\\'%s\\\')\' %discussion_post_id"\n tal:attributes="onClick python: \'redirectCreateCitedNewDiscussionPost(\\\'%s\\\')\' %discussion_post_id"\n
class="discussion-post-action-button">Reply</button>\n class="discussion-post-action-button">Reply</button>\n
...@@ -98,6 +97,10 @@ ...@@ -98,6 +97,10 @@
<key> <string>content_type</string> </key> <key> <string>content_type</string> </key>
<value> <string>text/html</string> </value> <value> <string>text/html</string> </value>
</item> </item>
<item>
<key> <string>expand</string> </key>
<value> <int>1</int> </value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>DiscussionPost_getSummaryAsHTML</string> </value> <value> <string>DiscussionPost_getSummaryAsHTML</string> </value>
...@@ -106,6 +109,10 @@ ...@@ -106,6 +109,10 @@
<key> <string>output_encoding</string> </key> <key> <string>output_encoding</string> </key>
<value> <string>iso-8859-15</string> </value> <value> <string>iso-8859-15</string> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -50,7 +50,9 @@ ...@@ -50,7 +50,9 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>"""\n <value> <string encoding="cdata"><![CDATA[
"""\n
This script allows to create a new Discussion Post in context.\n This script allows to create a new Discussion Post in context.\n
"""\n """\n
from DateTime import DateTime\n from DateTime import DateTime\n
...@@ -76,21 +78,29 @@ discussion_post = discussion_thread.newContent(\n ...@@ -76,21 +78,29 @@ discussion_post = discussion_thread.newContent(\n
language = portal.Localizer.get_selected_language(),\n language = portal.Localizer.get_selected_language(),\n
text_format = \'text/html\')\n text_format = \'text/html\')\n
\n \n
# depending on security model Post can be submited for review\n # depending on security model Post can be submitted for review\n
portal_status_message = context.Base_translateString("New post created in background.")\n portal_status_message = context.Base_translateString("New post created.")\n
\n \n
# a parent thread is actually just a logical container so it\'s modified\n # a parent thread is actually just a logical container so it\'s modified\n
# whenever a new post is done\n # whenever a new post is done\n
discussion_thread.edit(modification_date = DateTime())\n discussion_thread.edit(modification_date = DateTime())\n
\n \n
# pass current post\'s relative url in request so next view\n
# is able to show it without waiting for indexation\n
post_relative_url = discussion_post.getRelativeUrl()\n
\n
if not is_temp_object:\n if not is_temp_object:\n
return discussion_thread.Base_redirect(form_id,\n return discussion_thread.Base_redirect(form_id,\n
keep_items = dict(portal_status_message=portal_status_message))\n keep_items = dict(portal_status_message=portal_status_message,\n
post_relative_url = post_relative_url))\n
else:\n else:\n
# redirect using again reference\n # redirect using again reference\n
redirect_url = \'%s?portal_status_message=%s\' %(context.REQUEST[\'URL1\'],portal_status_message)\n redirect_url = \'%s?portal_status_message=%s&post_relative_url=%s\' \\\n
%(context.REQUEST[\'URL1\'],portal_status_message,post_relative_url)\n
context.REQUEST.RESPONSE.redirect(redirect_url)\n context.REQUEST.RESPONSE.redirect(redirect_url)\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
This script gets list of Discussion Posts for a Discussion Thread \n
using catalog. \n
Due to asynchronous nature of catalog it can use\n
passed from REQUEST not index yet posts.\n
"""\n
post_relative_url = context.REQUEST.get(\'post_relative_url\')\n
discussion_post_list = [x.getObject() for x in context.searchFolder(**kw)]\n
\n
if post_relative_url is not None:\n
post = context.restrictedTraverse(post_relative_url)\n
if post is not None and post not in discussion_post_list:\n
discussion_post_list.append(post)\n
return discussion_post_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>DiscussionThread_getDiscussionPostList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -66,7 +66,7 @@ if discussion_post_uid is not None:\n ...@@ -66,7 +66,7 @@ if discussion_post_uid is not None:\n
context.REQUEST.set(\'discussion_post_title\', title)\n context.REQUEST.set(\'discussion_post_title\', title)\n
if preferred_forum_quote_original_message:\n if preferred_forum_quote_original_message:\n
author_dict = discussion_post.DiscussionPost_getAuthorDict()\n author_dict = discussion_post.DiscussionPost_getAuthorDict()\n
text_content = \'<blockquote style="background-color: #E9E9E9;border: 1px solid #8CACBB;margin: 5px;padding: 10px 15px;">From: %s<br/>%s</blockquote>\' %(author_dict[\'author_title\'],\n text_content = \'<blockquote style="background-color: #E9E9E9;border: 1px solid #8CACBB;margin: 5px;padding: 10px 15px;">From: %s<br/>%s</blockquote><br/>\' %(author_dict[\'author_title\'],\n
discussion_post.getTextContent())\n discussion_post.getTextContent())\n
context.REQUEST.set(\'discussion_post_text_content\', text_content)\n context.REQUEST.set(\'discussion_post_text_content\', text_content)\n
\n \n
......
...@@ -178,7 +178,7 @@ ...@@ -178,7 +178,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>method_name</string> </key> <key> <string>method_name</string> </key>
<value> <string>searchFolder</string> </value> <value> <string>DiscussionThread_getDiscussionPostList</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <unicode encoding="cdata"><![CDATA[ <value> <unicode encoding="cdata"><![CDATA[
<tal:block tal:define="author_dict python: here.DiscussionPost_getAuthorDict();\n <tal:block tal:define="author_dict python: here.objectValues()[0].DiscussionPost_getAuthorDict();\n
is_author_link_available python:author_dict[\'author_url\'] is not None;">\n is_author_link_available python:author_dict[\'author_url\'] is not None;">\n
\n \n
<a class="listbox-row-discussion-thread-author-link"\n <a class="listbox-row-discussion-thread-author-link"\n
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<key> <string>group_list</string> </key> <key> <string>group_list</string> </key>
<value> <value>
<list> <list>
<string>left</string> <string>left reply-dialog</string>
<string>right</string> <string>right</string>
<string>center</string> <string>center</string>
<string>bottom</string> <string>bottom</string>
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>left</string> </key> <key> <string>left reply-dialog</string> </key>
<value> <value>
<list> <list>
<string>your_title</string> <string>your_title</string>
......
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string>"""\n
"""\n
This script allows to create a new Discussion Thread.\n This script allows to create a new Discussion Thread.\n
"""\n """\n
from zExceptions import Unauthorized\n
\n
MARKER = [\'\', None, []]\n MARKER = [\'\', None, []]\n
\n \n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
...@@ -62,7 +62,13 @@ person = portal.ERP5Site_getAuthenticatedMemberPersonValue()\n ...@@ -62,7 +62,13 @@ person = portal.ERP5Site_getAuthenticatedMemberPersonValue()\n
\n \n
version = \'001\'\n version = \'001\'\n
language = portal.Localizer.get_selected_language()\n language = portal.Localizer.get_selected_language()\n
user_assignment_dict = portal.ERP5Site_getPersonAssignmentDict()\n \n
try:\n
user_assignment_dict = portal.ERP5Site_getPersonAssignmentDict()\n
except Unauthorized:\n
# not in all cases current logged in user may access its details\n
user_assignment_dict = {\'group_list\': [], \'site_list\':[]}\n
\n
if group_list in MARKER:\n if group_list in MARKER:\n
group_list = user_assignment_dict[\'group_list\']\n group_list = user_assignment_dict[\'group_list\']\n
if site_list in MARKER:\n if site_list in MARKER:\n
...@@ -72,10 +78,16 @@ if site_list in MARKER:\n ...@@ -72,10 +78,16 @@ if site_list in MARKER:\n
membership_criterion_category_list = context.getMembershipCriterionCategoryList()\n membership_criterion_category_list = context.getMembershipCriterionCategoryList()\n
multimembership_criterion_base_category_list = context.getMultimembershipCriterionBaseCategoryList()\n multimembership_criterion_base_category_list = context.getMultimembershipCriterionBaseCategoryList()\n
\n \n
reference = title.replace(\' \', \'-\').replace(\'?\', \'\').replace(\':\', \'\').replace(\'/\', \'\').replace(\'&\', \'\').replace(\'=\', \'\')\n reference = context.Base_generateReferenceFromString(title)\n
\n
existing_document = context.getDocumentValue(reference)\n existing_document = context.getDocumentValue(reference)\n
if existing_document is not None:\n existing_web_section_list = portal.portal_catalog(id=reference, portal_type=[\'Web Site\', \'Web Section\'])\n
# if there are other document which reference duplicates just add some random part\n existing_module_list = portal.portal_catalog(id=reference, parent_uid=portal.getUid())\n
if existing_document is not None \\\n
or len(existing_web_section_list) \\\n
or len(existing_module_list):\n
# if there are other document or any tarversal objects (module, web section)\n
# which ID or reference duplicates just add some random part\n
# so we can distinguish)\n # so we can distinguish)\n
reference = \'%s-%s\' %(context.Base_generateRandomString(), reference)\n reference = \'%s-%s\' %(context.Base_generateRandomString(), reference)\n
\n \n
...@@ -112,7 +124,7 @@ discussion_post = discussion_thread.newContent(\n ...@@ -112,7 +124,7 @@ discussion_post = discussion_thread.newContent(\n
language = language)\n language = language)\n
\n \n
# depending on security model Thread and Post can be directly published or shared\n # depending on security model Thread and Post can be directly published or shared\n
portal_status_message = "New discussion created in backgroud."\n portal_status_message = "New discussion created in background."\n
discussion_thread.publish()\n discussion_thread.publish()\n
\n \n
if send_notification_text not in (\'\', None):\n if send_notification_text not in (\'\', None):\n
...@@ -153,10 +165,9 @@ if send_notification_text not in (\'\', None):\n ...@@ -153,10 +165,9 @@ if send_notification_text not in (\'\', None):\n
store_as_event=False)\n store_as_event=False)\n
\n \n
return context.Base_redirect(form_id,\n return context.Base_redirect(form_id,\n
keep_items = dict(portal_status_message=context.Base_translateString(portal_status_message)))\n keep_items = dict(portal_status_message=context.Base_translateString(portal_status_message),\n
thread_relative_url=discussion_thread.getRelativeUrl()))\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
This script gets list of Discussion Thread for a Forum using catalog. \n
Due to asynchronous nature of catalog it can use\n
passed from REQUEST not index yet threads.\n
"""\n
thread_relative_url = context.REQUEST.get(\'thread_relative_url\')\n
discussion_thread_list = [x.getObject() for x in context.getDocumentValueList(**kw)]\n
if thread_relative_url is not None:\n
thread = context.restrictedTraverse(thread_relative_url)\n
if thread is not None and thread not in discussion_thread_list:\n
discussion_thread_list = [thread] + discussion_thread_list\n
return discussion_thread_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSection_getDiscussionThreadList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -61,6 +61,10 @@ kw[\'sort_on\'] = ((\'modification_date\', \'DESC\'),)\n ...@@ -61,6 +61,10 @@ kw[\'sort_on\'] = ((\'modification_date\', \'DESC\'),)\n
kw[\'portal_type\'] = \'Discussion Post\'\n kw[\'portal_type\'] = \'Discussion Post\'\n
kw[\'parent_uid\'] = parent_uid_list\n kw[\'parent_uid\'] = parent_uid_list\n
\n \n
if len(parent_uid_list)==0:\n
# no parent discussion threads therefore no posts\n
return []\n
\n
result = [x.getObject() for x in context.portal_catalog(**kw)]\n result = [x.getObject() for x in context.portal_catalog(**kw)]\n
return result\n return result\n
</string> </value> </string> </value>
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<key> <string>group_list</string> </key> <key> <string>group_list</string> </key>
<value> <value>
<list> <list>
<string>left</string> <string>left reply-dialog</string>
<string>right</string> <string>right</string>
<string>center</string> <string>center</string>
<string>bottom</string> <string>bottom</string>
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>left</string> </key> <key> <string>left reply-dialog</string> </key>
<value> <value>
<list> <list>
<string>your_title</string> <string>your_title</string>
......
...@@ -281,7 +281,7 @@ ...@@ -281,7 +281,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>method_name</string> </key> <key> <string>method_name</string> </key>
<value> <string>getDocumentValueList</string> </value> <value> <string>WebSection_getDiscussionThreadList</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_EtagSupport__etag</string> </key> <key> <string>_EtagSupport__etag</string> </key>
<value> <string>ts38383138.94</string> </value> <value> <string>ts51500035.8</string> </value>
</item> </item>
<item> <item>
<key> <string>__name__</string> </key> <key> <string>__name__</string> </key>
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
}\n }\n
\n \n
.discussion-post-header .thumbnail{\n .discussion-post-header .thumbnail{\n
width:14%;\n /*width:14%;*/\n
margin:4px;\n margin:4px;\n
}\n }\n
\n \n
...@@ -96,7 +96,7 @@ blockquote {\n ...@@ -96,7 +96,7 @@ blockquote {\n
</item> </item>
<item> <item>
<key> <string>size</string> </key> <key> <string>size</string> </key>
<value> <int>960</int> </value> <value> <int>964</int> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
119 131
\ No newline at end of file \ No newline at end of file
...@@ -186,7 +186,7 @@ ...@@ -186,7 +186,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: map(lambda x: [x,x], here.getPortalNodeTypeList() + here.getPortalProjectTypeList() + here.getPortalTicketTypeList() + here.getPortalDeliveryTypeList())</string> </value> <value> <string>python: map(lambda x: [x,x], here.getPortalNodeTypeList() + here.getPortalProjectTypeList() + here.getPortalTicketTypeList() + here.getPortalDeliveryTypeList() + here.getPortalResourceTypeList())</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
1266 1267
\ No newline at end of file \ No newline at end of file
...@@ -62,10 +62,7 @@ if address not in MARKER and port not in MARKER:\n ...@@ -62,10 +62,7 @@ if address not in MARKER and port not in MARKER:\n
for index_uid in range(len(uid)):\n for index_uid in range(len(uid)):\n
document_relative_url = getRelativeUrl[index_uid]\n document_relative_url = getRelativeUrl[index_uid]\n
document = portal.restrictedTraverse(document_relative_url)\n document = portal.restrictedTraverse(document_relative_url)\n
# XXX: we do check if "data" methods exists on pretending to be Document portal types\n if document.Base_isConvertible():\n
# we need a way to do this by introspection\n
if ((getattr(document, "getData", None) is not None and document.getData() not in MARKER) or \\\n
(getattr(document, "getBaseData", None) is not None and document.getBaseData() not in MARKER)):\n
document.activate(priority=4, tag="conversion").Base_callPreConvert()\n document.activate(priority=4, tag="conversion").Base_callPreConvert()\n
</string> </value> </string> </value>
</item> </item>
......
import re
def Base_extractImageUrlList(self, text_content=None):
"""
Extract list of image URLS used in a Text document (i.e. Web Page)
"""
if text_content is None:
text_content = self.getTextContent()
if text_content is not None:
return re.findall('src=[\"\'](.[^\"\']+)[\"\']', text_content, re.I)
return []
...@@ -56,26 +56,25 @@ ...@@ -56,26 +56,25 @@
"""\n """\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
\n \n
portal_type = context.getPortalType()\n if not context.Base_isConvertible():\n
allowed_portal_type_list = portal.getPortalDocumentTypeList() + portal.getPortalEmbeddedDocumentTypeList()\n # no need to convert any non convertible types\n
\n
if portal_type not in allowed_portal_type_list:\n
# no need to convert any non DMS types\n
return\n return\n
\n \n
format = portal.portal_preferences.getPreferredImageFormat()\n if kw=={}:\n
quality = portal.portal_preferences.getPreferredImageQuality()\n # use default set of system preferences\n
preferred_image_size = portal.portal_preferences.getPreferredImageSize()\n format = portal.portal_preferences.getPreferredImageFormat()\n
quality = portal.portal_preferences.getPreferredImageQuality()\n
# thumbnail is required always\n
display_list = ["thumbnail"]\n
kw = dict(format=format, quality=quality, display_list = display_list)\n
\n \n
# thumbnail is required always\n
display_list = ["thumbnail"]\n
method = context.getTypeBasedMethod(\'preConvert\')\n method = context.getTypeBasedMethod(\'preConvert\')\n
return method(**dict(format=format, quality=quality, display_list = display_list))\n return method(**kw)\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>**kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -2,31 +2,21 @@ ...@@ -2,31 +2,21 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/> <global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>arguments_src</string> </key> <key> <string>_function</string> </key>
<value> <string>table_0\r\n <value> <string>Base_extractImageUrlList</string> </value>
query_table</string> </value>
</item> </item>
<item> <item>
<key> <string>connection_id</string> </key> <key> <string>_module</string> </key>
<value> <string>erp5_sql_connection</string> </value> <value> <string>DocumentConversion</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>z_related_owner_title</string> </value> <value> <string>Base_extractImageUrlList</string> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-var query_table>.owner = <dtml-var table_0>.reference\n
AND <dtml-var table_0>.portal_type = \'Person\'
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Return true or false based on if document is convertible or not.\n
"""\n
MARKER = (None, \'\',)\n
portal = context.getPortalObject()\n
\n
portal_type = context.getPortalType()\n
allowed_portal_type_list = portal.getPortalDocumentTypeList() + portal.getPortalEmbeddedDocumentTypeList()\n
\n
if portal_type not in allowed_portal_type_list:\n
return False\n
\n
# XXX: we do check if "data" methods exists on pretending to be Document portal types\n
# we need a way to do this by introspection\n
return (getattr(context, "getData", None) is not None and context.getData() not in MARKER) or \\\n
(getattr(context, "getBaseData", None) is not None and context.getBaseData() not in MARKER)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_isConvertible</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -53,6 +53,11 @@ ...@@ -53,6 +53,11 @@
<value> <string>"""\n <value> <string>"""\n
Do actual conversion of any Image type.\n Do actual conversion of any Image type.\n
"""\n """\n
if quality is None:\n
# it\'s required so fall back to system preferences as\n
# directly accessed over URL will do the same\n
quality = context.getDefaultImageQuality(format)\n
\n
# UI uses \'large\' display\n # UI uses \'large\' display\n
display_list.append(\'large\')\n display_list.append(\'large\')\n
context.Base_preConvert(format, quality, display_list)\n context.Base_preConvert(format, quality, display_list)\n
...@@ -60,7 +65,7 @@ context.Base_preConvert(format, quality, display_list)\n ...@@ -60,7 +65,7 @@ context.Base_preConvert(format, quality, display_list)\n
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>format, quality, display_list</string> </value> <value> <string>format, quality=None, display_list=[]</string> </value>
</item> </item>
<item> <item>
<key> <string>_proxy_roles</string> </key> <key> <string>_proxy_roles</string> </key>
......
...@@ -53,7 +53,12 @@ ...@@ -53,7 +53,12 @@
<value> <string>"""\n <value> <string>"""\n
Do actual conversion of OOo types.\n Do actual conversion of OOo types.\n
"""\n """\n
portal = context.getPortalObject()\n
\n
if context.hasBaseData():\n if context.hasBaseData():\n
if quality is None:\n
quality = portal.portal_preferences.getPreferredImageQuality()\n
\n
# empty documents do not need pre conversion\n # empty documents do not need pre conversion\n
context.activate(serialization_tag=\'pre_convert\').convert(**{\'format\': \'html\'})\n context.activate(serialization_tag=\'pre_convert\').convert(**{\'format\': \'html\'})\n
context.activate(serialization_tag=\'pre_convert\').Base_preConvert(format, quality, display_list)\n context.activate(serialization_tag=\'pre_convert\').Base_preConvert(format, quality, display_list)\n
...@@ -61,7 +66,7 @@ if context.hasBaseData():\n ...@@ -61,7 +66,7 @@ if context.hasBaseData():\n
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>format, quality, display_list</string> </value> <value> <string>format, quality=None, display_list=[]</string> </value>
</item> </item>
<item> <item>
<key> <string>_proxy_roles</string> </key> <key> <string>_proxy_roles</string> </key>
......
...@@ -50,7 +50,9 @@ ...@@ -50,7 +50,9 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>"""\n <value> <string encoding="cdata"><![CDATA[
"""\n
Do actual conversion of Web Page. As it involves cloudoo use serialization tag and activity.\n Do actual conversion of Web Page. As it involves cloudoo use serialization tag and activity.\n
"""\n """\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
...@@ -60,7 +62,12 @@ format_kw = {\'format\': format,\n ...@@ -60,7 +62,12 @@ format_kw = {\'format\': format,\n
for display in display_list:\n for display in display_list:\n
format_kw[\'display\'] = display\n format_kw[\'display\'] = display\n
context.activate(serialization_tag=\'pre_convert\').convert(**format_kw)\n context.activate(serialization_tag=\'pre_convert\').convert(**format_kw)\n
</string> </value> \n
# try to convert all relative referenced (i.e. by <img> tag) documents\n
context.activate().WebPage_preConvertReferencedImageList(**format_kw)\n
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Get all images inside a document and try to pre convert relative ones\n
"""\n
portal = context.getPortalObject()\n
\n
MARKER = (None, \'\',)\n
API_ARGUMENT_LIST = [\'format\', \'display\', \'display_list\', \'quality\', \'resolution\']\n
validation_state = (\'released\', \'released_alive\', \'published\', \'published_alive\',\n
\'shared\', \'shared_alive\', \'public\', \'validated\')\n
\n
def convertUrlArgumentsToDict(convert_string):\n
convert_kw = {}\n
# some editors when creating wbe page content do escape \'&\' properly\n
convert_string = convert_string.replace(\'&amp;\', \'&\')\n
\n
# convert from URL string to python arguments dict\n
for pair in convert_string.split(\'&\'):\n
arg_list = pair.split(\'=\')\n
if len(arg_list)==2:\n
convert_kw[arg_list[0]] = arg_list[1]\n
return convert_kw\n
\n
image_url_list = context.Base_extractImageUrlList()\n
for image_url in image_url_list:\n
if not image_url.startswith(\'http://\') and not image_url.startswith(\'https://\'):\n
# try to use only relative URLs\n
part_list = image_url.split(\'?\')\n
if len(part_list)==2:\n
# don\'t deal with bad URLs (having more than one \'?\') inside\n
reference = part_list[0]\n
convert_string = part_list[1]\n
\n
# check we have locally such a reference so we can convert it\n
catalog_kw = {\'portal_type\': portal.getPortalDocumentTypeList() + portal.getPortalEmbeddedDocumentTypeList(),\n
\'reference\': reference,\n
\'validation_state\': validation_state}\n
\n
document = portal.portal_catalog.getResultValue(**catalog_kw)\n
if document is not None:\n
# try to pre convert it based on extracted URL\'s arguments\n
convert_kw = convertUrlArgumentsToDict(convert_string)\n
\n
# XXX: we do check if "data" methods exists on pretending to be Document portal types\n
# we need a way to do this by introspection\n
if ((getattr(document, "getData", None) is not None and document.getData() not in MARKER) or \\\n
(getattr(document, "getBaseData", None) is not None and document.getBaseData() not in MARKER)):\n
if \'display\' in convert_kw.keys():\n
# conversion script aggregate all possible display options into a list\n
convert_kw[\'display_list\'] = [convert_kw.pop(\'display\')]\n
\n
# only certain arguments make sense due to API so leave only them\n
for key in convert_kw.keys():\n
if key not in API_ARGUMENT_LIST:\n
convert_kw.pop(key)\n
\n
# due to API we need certain arguments\n
if convert_kw.get(\'quality\') is None:\n
convert_kw[\'quality\'] = kw.get(\'quality\')\n
\n
# do real conversion\n
format = convert_kw.get(\'format\')\n
quality = convert_kw.get(\'quality\')\n
if format not in MARKER and quality not in MARKER:\n
# format is mandatory if it\'s missing then anyway URL request will fail so\n
# don\'t bother create an activity\n
document.activate(priority=4, tag="conversion").Base_callPreConvert(**convert_kw)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebPage_preConvertReferencedImageList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
18 22
\ No newline at end of file \ No newline at end of file
DocumentConversion
\ No newline at end of file
...@@ -30,7 +30,9 @@ ...@@ -30,7 +30,9 @@
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string></string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>icon</string> </key> <key> <string>icon</string> </key>
...@@ -44,7 +46,7 @@ ...@@ -44,7 +46,7 @@
<key> <string>permissions</string> </key> <key> <string>permissions</string> </key>
<value> <value>
<tuple> <tuple>
<string>View</string> <string>Manage portal</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
...@@ -186,7 +186,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n ...@@ -186,7 +186,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <unicode></unicode> </value> <value> <unicode>VCS Status</unicode> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
ERP5 Forge helps software development. It provide a bug management module, integration with SVN and an upload module, glossary module for translation project. ERP5 Forge helps software development. It provide a bug management module, integration with version control systems and a glossary module for translation project.
\ No newline at end of file \ No newline at end of file
667 670
\ No newline at end of file \ No newline at end of file
...@@ -71,7 +71,7 @@ if redirect_to_document is None:\n ...@@ -71,7 +71,7 @@ if redirect_to_document is None:\n
if user_login is None:\n if user_login is None:\n
# get current authenticated user\n # get current authenticated user\n
user_login = str(portal.portal_membership.getAuthenticatedMember())\n user_login = str(portal.portal_membership.getAuthenticatedMember())\n
\n \n
document_kw = {\'user_login\': user_login,\n document_kw = {\'user_login\': user_login,\n
\'group\': group,\n \'group\': group,\n
\'publication_section\': publication_section,\n \'publication_section\': publication_section,\n
...@@ -86,6 +86,13 @@ if classification not in MARKER:\n ...@@ -86,6 +86,13 @@ if classification not in MARKER:\n
if follow_up_list:\n if follow_up_list:\n
document_kw[\'follow_up_list\'] = follow_up_list\n document_kw[\'follow_up_list\'] = follow_up_list\n
\n \n
\n
# FIXME: this list of properties should not be hardcoded.\n
for key in (\'title\', \'short_title\', \'reference\', \'language\', \'version\', \'description\', ):\n
value = kw.get(key, None)\n
if value not in MARKER:\n
document_kw[key] = value\n
\n
if attach_document_to_context:\n if attach_document_to_context:\n
# attach document to current context using follow_up\n # attach document to current context using follow_up\n
follow_up_list = document_kw.setdefault(\'follow_up_list\', [])\n follow_up_list = document_kw.setdefault(\'follow_up_list\', [])\n
...@@ -126,20 +133,7 @@ if synchronous_metadata_discovery:\n ...@@ -126,20 +133,7 @@ if synchronous_metadata_discovery:\n
input_parameter_dict=document_kw)\n input_parameter_dict=document_kw)\n
is_existing_document_updated = (merged_document!=document)\n is_existing_document_updated = (merged_document!=document)\n
document = merged_document\n document = merged_document\n
# introspect document and find editable properties\n
# then use form or kw and try to get values in two available modes: the\n
# script coulbe be called: from ERP5 From or directly from Python script\n
document_edit_kw = {}\n
property_id_list = document.propertyIds()\n
form = context.REQUEST.form\n
for key in property_id_list:\n
value = form.get(key, kw.get(key, None))\n
if value not in MARKER:\n
document_edit_kw[key] = value\n
\n \n
# edit document \n
if document_edit_kw is not {}:\n
document.edit(**document_edit_kw)\n
document_portal_type = document.getTranslatedPortalType()\n document_portal_type = document.getTranslatedPortalType()\n
if not is_existing_document_updated:\n if not is_existing_document_updated:\n
message = translateString(\'${portal_type} created successfully.\',\n message = translateString(\'${portal_type} created successfully.\',\n
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python:here.ERP5Site_getAuthenticatedMemberPersonValue() is not None and here.ERP5Site_getAuthenticatedMemberPersonValue().getGroup() or \'\'</string> </value> <value> <string>python: context.getProperty(\'group\') or context.ERP5Site_getAuthenticatedMemberPersonValue() is not None and here.ERP5Site_getAuthenticatedMemberPersonValue().getGroup() or \'\'</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -115,16 +115,13 @@ ...@@ -115,16 +115,13 @@
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle> <pickle>
<tuple> <global name="TALESMethod" module="Products.Formulator.TALESField"/>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>here/absolute_url</string> </value> <value> <string>python: "%s/%s" % (context.absolute_url(), request.get(\'form_id\', \'\'))</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
141 145
\ No newline at end of file \ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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