Commit 938f4bc7 authored by Ivan Tyagov's avatar Ivan Tyagov

Merge branch 'master' into cache

Conflicts:
	bt5/erp5_dms_conversion_catalog/SkinTemplateItem/portal_skins/erp5_dms_conversion_catalog/WebPage_preConvertReferencedImageList.xml
	bt5/erp5_dms_conversion_catalog/bt/revision
	product/ERP5OOo/tests/testDmsWithPreConversion.py
parents 1ad62b2b 0be4533e
...@@ -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
......
...@@ -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
......
...@@ -367,6 +367,7 @@ class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin): ...@@ -367,6 +367,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):
""" """
......
...@@ -50,33 +50,37 @@ ...@@ -50,33 +50,37 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>transition = state_change[\'transition\'].id[len(\'user_\'):]\n <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 \n
def TestTitle(object):\n def removeNonAscii(s): \n
"""\n return "".join(i for i in s if ord(i)>44 and ord(i)<123)\n
This is the test for this particular action\n
"""\n
if object.getTitle() == \'truc\':\n
return 1\n
return 0\n
\n \n
object = state_change[\'object\']\n # reference can be used for permanent URL so be friendly to spaces (SEO)\n
s = s.strip()\n
s =s.replace(\' \', \'-\')\n
\n \n
if TestTitle(object):\n s = removeNonAscii(s)\n
method = getattr(context, transition)\n for item in transliterate_list:\n
method()\n s = s.replace(item, \'-\')\n
else:\n \n
kw = {\'error_message\':\'Why do you want to do this ?????\'}\n return s.strip(\'-\')\n
state_change.setWorkflowVariable(object, **kw)\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change</string> </value> <value> <string>s</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_error_message</string> </value> <value> <string>Base_generateReferenceFromString</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -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,7 +78,8 @@ if site_list in MARKER:\n ...@@ -72,7 +78,8 @@ 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 if existing_document is not None:\n
# if there are other document which reference duplicates just add some random part\n # if there are other document which reference duplicates just add some random part\n
...@@ -154,9 +161,7 @@ if send_notification_text not in (\'\', None):\n ...@@ -154,9 +161,7 @@ if send_notification_text not in (\'\', None):\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
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
...@@ -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>
......
119 122
\ 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>
......
...@@ -56,11 +56,8 @@ ...@@ -56,11 +56,8 @@
"""\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
if kw=={}:\n if kw=={}:\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>"""\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>
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
\n \n
MARKER = (None, \'\',)\n MARKER = (None, \'\',)\n
API_ARGUMENT_LIST = [\'format\', \'display\', \'quality\', \'resolution\']\n API_ARGUMENT_LIST = [\'format\', \'display\', \'display_list\', \'quality\', \'resolution\']\n
validation_state = (\'released\', \'released_alive\', \'published\', \'published_alive\',\n validation_state = (\'released\', \'released_alive\', \'published\', \'published_alive\',\n
\'shared\', \'shared_alive\', \'public\', \'validated\')\n \'shared\', \'shared_alive\', \'public\', \'validated\')\n
\n \n
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3243,6 +3243,12 @@ msgstr "関連する出荷明細書がありません" ...@@ -3243,6 +3243,12 @@ msgstr "関連する出荷明細書がありません"
msgid "No Trade Condition." msgid "No Trade Condition."
msgstr "取引条件がありません。" msgstr "取引条件がありません。"
msgid "No result !"
msgstr "見つかれませんでした!"
msgid "No result."
msgstr "見つかれませんでした。"
msgid "No such document was found." msgid "No such document was found."
msgstr "ドキュメントが見つかりませんでした。" msgstr "ドキュメントが見つかりませんでした。"
......
2012-10-16 arnaud.fontaine
* Add missing translations for 'No result.' and 'No result !'.
2010-07-09 tatuya 2010-07-09 tatuya
* Fix the translations of Internal Packing List. Because they were not consistent. * Fix the translations of Internal Packing List. Because they were not consistent.
......
39 40
\ No newline at end of file \ No newline at end of file
...@@ -65,7 +65,6 @@ class PaypalService(XMLObject): ...@@ -65,7 +65,6 @@ class PaypalService(XMLObject):
def navigate(self, REQUEST=None, **kw): def navigate(self, REQUEST=None, **kw):
"""See Payment Service Interface Documentation""" """See Payment Service Interface Documentation"""
self.Base_checkConsistency()
page_template = kw.pop("page_template") page_template = kw.pop("page_template")
paypal_dict = kw.get("paypal_dict", {}) paypal_dict = kw.get("paypal_dict", {})
temp_document = newTempDocument(self, 'id') temp_document = newTempDocument(self, 'id')
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>NVP Url</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>nvp_link_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: \'\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Email of account</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>service_email_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: \'\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
<string>my_title</string> <string>my_title</string>
<string>my_reference</string> <string>my_reference</string>
<string>my_link_url_string</string> <string>my_link_url_string</string>
<string>my_nvp_link</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -110,6 +111,7 @@ ...@@ -110,6 +111,7 @@
<string>my_service_username</string> <string>my_service_username</string>
<string>my_service_password</string> <string>my_service_password</string>
<string>my_service_signature</string> <string>my_service_signature</string>
<string>my_service_email</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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_nvp_link</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>field_id</string> </key>
<value> <string>my_link_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>NVP URL</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_service_email</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>field_id</string> </key>
<value> <string>my_string_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>Email</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
<item> <item>
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list/> <list>
<string>default</string>
</list>
</value> </value>
</item> </item>
<item> <item>
...@@ -50,6 +52,10 @@ ...@@ -50,6 +52,10 @@
<key> <string>tales</string> </key> <key> <string>tales</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -69,6 +75,10 @@ ...@@ -69,6 +75,10 @@
<key> <string>values</string> </key> <key> <string>values</string> </key>
<value> <value>
<dictionary> <dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_password</string> </value> <value> <string>my_password</string> </value>
......
3 5
\ No newline at end of file \ No newline at end of file
...@@ -62,20 +62,12 @@ if bt5 is None:\n ...@@ -62,20 +62,12 @@ if bt5 is None:\n
\n \n
active_result = ActiveResult()\n active_result = ActiveResult()\n
\n \n
template_tool.updateRepositoryBusinessTemplateList(\n bt5_list = bt5.split()\n
template_tool.getRepositoryList())\n bt5_list.extend(template_tool.getInstalledBusinessTemplateTitleList())\n
\n \n
try:\n try:\n
bt5_list = [x[1] for x in template_tool.resolveBusinessTemplateListDependency(\n message_list = template_tool.upgradeSite(bt5_list, dry_run=True)\n
bt5.split(),\n severity = len(message_list)\n
newest_only=True)]\n
\n
bt5_list.extend([x.getTitle() for x in \\\n
template_tool.getUpdatedRepositoryBusinessTemplateList()])\n
\n
bt5_list = list(set(bt5_list))\n
severity = len(bt5_list)\n
\n
except BusinessTemplateUnknownError, error:\n except BusinessTemplateUnknownError, error:\n
severity = -1\n severity = -1\n
detail = str(error)\n detail = str(error)\n
...@@ -83,13 +75,13 @@ except BusinessTemplateUnknownError, error:\n ...@@ -83,13 +75,13 @@ except BusinessTemplateUnknownError, error:\n
if severity == -1:\n if severity == -1:\n
severity = 5\n severity = 5\n
summary = "Unable to resolve bt5 dependencies"\n summary = "Unable to resolve bt5 dependencies"\n
\n
elif severity == 0:\n elif severity == 0:\n
summary = "Nothing to do."\n summary = "Nothing to do."\n
detail = ""\n detail = ""\n
else:\n else:\n
summary = "Upgrade needed"\n summary = "Upgrade needed."\n
detail = "Needed to install %s" % \', \'.join(bt5_list)\n detail = "Information: %s" % ",".join(message_list)\n
\n
\n \n
active_result.edit(\n active_result.edit(\n
summary=summary, \n summary=summary, \n
......
...@@ -56,12 +56,9 @@ bt5 = portal.getPromiseParameter(\'portal_templates\', \'expected_bt5\')\n ...@@ -56,12 +56,9 @@ bt5 = portal.getPromiseParameter(\'portal_templates\', \'expected_bt5\')\n
if bt5 is None:\n if bt5 is None:\n
return\n return\n
\n \n
bt5_list = [x[1] for x in portal.portal_templates.resolveBusinessTemplateListDependency(bt5.split(), newest_only=True)]\n bt5_list = bt5.split()\n
bt5_list.extend([x.getTitle() for x in portal.portal_templates.getUpdatedRepositoryBusinessTemplateList()])\n bt5_list.extend(portal.portal_templates.getInstalledBusinessTemplateTitleList())\n
bt5_list = list(set(bt5_list))\n portal.portal_templates.upgradeSite(bt5_list)\n
\n
portal.portal_templates.installBusinessTemplateListFromRepository(\n
bt5_list, activate=True, install_dependency=True)\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
18 19
\ No newline at end of file \ No newline at end of file
...@@ -303,6 +303,7 @@ ...@@ -303,6 +303,7 @@
<string>my_view_mode_preferred_internal_use_list</string> <string>my_view_mode_preferred_internal_use_list</string>
<string>my_view_mode_listbox_read_only_effective_date</string> <string>my_view_mode_listbox_read_only_effective_date</string>
<string>my_view_mode_listbox_read_only_expiration_date</string> <string>my_view_mode_listbox_read_only_expiration_date</string>
<string>my_view_mode_preferred_tax_use_list</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>items</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_view_mode_preferred_tax_use_list</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>items</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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>field_id</string> </key>
<value> <string>my_multi_list_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<list/>
</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>Tax Uses</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: getattr(here.portal_categories.use, preferences.getPreference(\'preferred_category_child_item_list_method_id\', \'getCategoryChildCompactLogicalPathItemList\'))(base=1, local_sort_id=(\'int_index\', \'translated_title\'), checked_permission=\'View\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
<string>my_preferred_supplier_role_list</string> <string>my_preferred_supplier_role_list</string>
<string>my_preferred_client_role_list</string> <string>my_preferred_client_role_list</string>
<string>my_preferred_trade_base_amount_list</string> <string>my_preferred_trade_base_amount_list</string>
<string>my_preferred_tax_use_list</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_tax_use_list</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>field_id</string> </key>
<value> <string>my_view_mode_preferred_tax_use_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -42,6 +42,7 @@ from Products.CMFActivity.ActiveResult import ActiveResult ...@@ -42,6 +42,7 @@ from Products.CMFActivity.ActiveResult import ActiveResult
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping from Products.ERP5Type.Globals import InitializeClass, DTMLFile, PersistentMapping
from Products.ERP5Type.DiffUtils import DiffFile from Products.ERP5Type.DiffUtils import DiffFile
from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5.Document.BusinessTemplate import BusinessTemplateMissingDependency from Products.ERP5.Document.BusinessTemplate import BusinessTemplateMissingDependency
from Acquisition import aq_base from Acquisition import aq_base
...@@ -881,62 +882,57 @@ class TemplateTool (BaseTool): ...@@ -881,62 +882,57 @@ class TemplateTool (BaseTool):
Return the list of missing dependencies for a business Return the list of missing dependencies for a business
template, given a tuple : (repository, id) template, given a tuple : (repository, id)
""" """
# We do not take into consideration the dependencies # use by using "self" on transactional_cached decorator
# for meta business templates # breaks ERP5Site creation due aq_base.
if bt[0] == 'meta': @transactional_cached(lambda bt: (bt))
return [] def _getDependency(bt):
result_list = [] # We do not take into consideration the dependencies
for repository, property_dict_list in self.repository_dict.items(): # for meta business templates
if repository == bt[0]: if bt[0] == 'meta':
for property_dict in property_dict_list: return []
if property_dict['id'] == bt[1]: result_list = []
dependency_list = property_dict['dependency_list'] for repository, property_dict_list in self.repository_dict.items():
for dependency_couple in dependency_list: if repository == bt[0]:
# dependency_couple is like "erp5_xhtml_style (>= 0.2)" for property_dict in property_dict_list:
dependency_couple_list = dependency_couple.split(' ', 1) if property_dict['id'] == bt[1]:
dependency = dependency_couple_list[0] dependency_list = [q for q in property_dict['dependency_list'] if q]
version_restriction = None for dependency_couple in dependency_list:
if len(dependency_couple_list) > 1: # dependency_couple is like "erp5_xhtml_style (>= 0.2)"
version_restriction = dependency_couple_list[1] dependency_couple_list = dependency_couple.split(' ', 1)
if version_restriction.startswith('('): dependency = dependency_couple_list[0]
# Something like "(>= 1.0rc6)". version_restriction = None
version_restriction = version_restriction[1:-1] if len(dependency_couple_list) > 1:
require_update = False version_restriction = dependency_couple_list[1]
installed_bt = self.getInstalledBusinessTemplate(dependency) if version_restriction.startswith('('):
if version_restriction is not None: # Something like "(>= 1.0rc6)".
if installed_bt is not None: version_restriction = version_restriction[1:-1]
# Check if the installed version require an update require_update = False
if not self.compareVersionStrings(installed_bt.getVersion(), version_restriction): if dependency not in result_list:
operator = version_restriction.split(' ')[0] # Get the lastest version of the dependency on the
if operator in ('<', '<<', '<='): # repository that meet the version restriction
raise BusinessTemplateMissingDependency, '%s (%s) is present but %s require: %s (%s)'%(dependency, installed_bt.getVersion(), property_dict['title'], dependency, version_restriction) provider_installed = False
else: bt_dep = None
require_update = True try:
if (require_update or installed_bt is None) \ bt_dep = self.getLastestBTOnRepos(dependency, version_restriction)
and dependency not in result_list: except BusinessTemplateUnknownError:
# Get the lastest version of the dependency on the raise BusinessTemplateMissingDependency, 'While analysing %s the following dependency could not be satisfied: %s (%s)\nReason: Business Template could not be found in the repositories'%(bt[1], dependency, version_restriction or '')
# repository that meet the version restriction except BusinessTemplateIsMeta:
provider_installed = False provider_list = self.getProviderList(dependency)
try: for provider in provider_list:
bt_dep = self.getLastestBTOnRepos(dependency, version_restriction) if self.portal_templates.getInstalledBusinessTemplate(provider) is not None:
except BusinessTemplateUnknownError: bt_dep = self.getLastestBTOnRepos(provider)
raise BusinessTemplateMissingDependency, 'The following dependency could not be satisfied: %s (%s)\nReason: Business Template could not be found in the repositories'%(dependency, version_restriction or '') break
except BusinessTemplateIsMeta: if bt_dep is None:
provider_list = self.getProviderList(dependency) bt_dep = ('meta', dependency)
for provider in provider_list:
if self.portal_templates.getInstalledBusinessTemplate(provider) is not None:
provider_installed = True
break
if not provider_installed:
bt_dep = ('meta', dependency)
if not provider_installed:
sub_dep_list = self.getDependencyList(bt_dep) sub_dep_list = self.getDependencyList(bt_dep)
for sub_dep in sub_dep_list: for sub_dep in sub_dep_list:
if sub_dep not in result_list: if sub_dep not in result_list:
result_list.append(sub_dep) result_list.append(sub_dep)
result_list.append(bt_dep) result_list.append(bt_dep)
return result_list return result_list
raise BusinessTemplateUnknownError, 'The Business Template %s could not be found on repository %s'%(bt[1], bt[0]) raise BusinessTemplateUnknownError, 'The Business Template %s could not be found on repository %s'%(bt[1], bt[0])
return _getDependency(bt)
def findProviderInBTList(self, provider_list, bt_list): def findProviderInBTList(self, provider_list, bt_list):
""" """
...@@ -1061,22 +1057,32 @@ class TemplateTool (BaseTool): ...@@ -1061,22 +1057,32 @@ class TemplateTool (BaseTool):
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'getRepositoryBusinessTemplateList' ) 'getRepositoryBusinessTemplateList' )
def getRepositoryBusinessTemplateList(self, update_only=False, def getRepositoryBusinessTemplateList(self, update_only=False,
newest_only=False, **kw): template_list=None, **kw):
"""Get the list of Business Templates in repositories. """Get the list of Business Templates in repositories.
update_only: return only bt that needs to be updated
template_list: only returns bt within the given list
""" """
version_state_title_dict = { 'new' : 'New', 'present' : 'Present', version_state_title_dict = { 'new' : 'New', 'present' : 'Present',
'old' : 'Old' } 'old' : 'Old' }
from Products.ERP5Type.Document import newTempBusinessTemplate from Products.ERP5Type.Document import newTempBusinessTemplate
template_list = [] result_list = []
template_set = None
if template_list is not None:
template_set = set(template_list)
template_item_list = [] template_item_list = []
if update_only or newest_only: # First of all, filter Business Templates in repositories.
# First of all, filter Business Templates in repositories. template_item_dict = {}
template_item_dict = {} for repository, property_dict_list in self.repository_dict.items():
for repository, property_dict_list in self.repository_dict.items(): for property_dict in property_dict_list:
for property_dict in property_dict_list: title = property_dict['title']
title = property_dict['title'] if template_set and not(title in template_set):
continue
if not update_only:
template_item_list.append((repository, property_dict))
else:
if title not in template_item_dict: if title not in template_item_dict:
# If this is the first time to see this business template, # If this is the first time to see this business template,
# insert it. # insert it.
...@@ -1095,26 +1101,22 @@ class TemplateTool (BaseTool): ...@@ -1095,26 +1101,22 @@ class TemplateTool (BaseTool):
and property_dict['revision'] \ and property_dict['revision'] \
and int(previous_property_dict['revision']) < int(property_dict['revision']): and int(previous_property_dict['revision']) < int(property_dict['revision']):
template_item_dict[title] = (repository, property_dict) template_item_dict[title] = (repository, property_dict)
if update_only: # Next, select only updated business templates.
# Next, select only updated business templates. if update_only:
for repository, property_dict in template_item_dict.values(): for repository, property_dict in template_item_dict.values():
installed_bt = \ installed_bt = \
self.getInstalledBusinessTemplate(property_dict['title'], strict=True) self.getInstalledBusinessTemplate(property_dict['title'], strict=True)
if installed_bt is not None: if installed_bt is not None:
diff_version = self.compareVersions(installed_bt.getVersion(), diff_version = self.compareVersions(installed_bt.getVersion(),
property_dict['version']) property_dict['version'])
if diff_version < 0: if diff_version < 0:
template_item_list.append((repository, property_dict)) template_item_list.append((repository, property_dict))
elif diff_version == 0 \ elif diff_version == 0 \
and installed_bt.getRevision() \ and installed_bt.getRevision() \
and property_dict['revision'] \ and property_dict['revision'] \
and int(installed_bt.getRevision()) < int(property_dict['revision']): and int(installed_bt.getRevision()) < int(property_dict['revision']):
template_item_list.append((repository, property_dict)) template_item_list.append((repository, property_dict))
else: elif template_list is not None:
template_item_list = template_item_dict.values()
else:
for repository, property_dict_list in self.repository_dict.items():
for property_dict in property_dict_list:
template_item_list.append((repository, property_dict)) template_item_list.append((repository, property_dict))
# Create temporary Business Template objects for displaying. # Create temporary Business Template objects for displaying.
...@@ -1123,14 +1125,14 @@ class TemplateTool (BaseTool): ...@@ -1123,14 +1125,14 @@ class TemplateTool (BaseTool):
id = property_dict['id'] id = property_dict['id']
filename = property_dict['id'] filename = property_dict['id']
del property_dict['id'] del property_dict['id']
version = property_dict['version'] revision = property_dict['revision']
version_state = 'new' version_state = 'new'
installed_bt = \ installed_bt = \
self.getInstalledBusinessTemplate(property_dict['title']) self.getInstalledBusinessTemplate(property_dict['title'])
if installed_bt is not None: if installed_bt is not None:
installed_version = installed_bt.getVersion() installed_version = installed_bt.getVersion()
installed_revision = installed_bt.getRevision() installed_revision = installed_bt.getRevision()
result = self.compareVersions(version, installed_version) result = self.compareVersions(installed_revision, revision)
if result == 0: if result == 0:
version_state = 'present' version_state = 'present'
elif result < 0: elif result < 0:
...@@ -1148,9 +1150,9 @@ class TemplateTool (BaseTool): ...@@ -1148,9 +1150,9 @@ class TemplateTool (BaseTool):
installed_revision = installed_revision, installed_revision = installed_revision,
repository = repository, **property_dict) repository = repository, **property_dict)
obj.setUid(uid) obj.setUid(uid)
template_list.append(obj) result_list.append(obj)
template_list.sort(key=lambda x: x.getTitle()) result_list.sort(key=lambda x: x.getTitle())
return template_list return result_list
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'getUpdatedRepositoryBusinessTemplateList' ) 'getUpdatedRepositoryBusinessTemplateList' )
...@@ -1227,16 +1229,14 @@ class TemplateTool (BaseTool): ...@@ -1227,16 +1229,14 @@ class TemplateTool (BaseTool):
install_dependency=False): install_dependency=False):
"""Deprecated. """Deprecated.
""" """
DeprecationWarning('getInstalledBusinessTemplatesList is deprecated; Use getInstalledBusinessTemplateList instead.', DeprecationWarning) DeprecationWarning('installBusinessTemplatesFromRepositories is deprecated; Use self.installBusinessTemplateListFromRepository instead.', DeprecationWarning)
return self.installBusinessTemplateListFromRepository(template_list, return self.installBusinessTemplateListFromRepository(template_list,
only_newer, update_catalog, activate, install_dependency) only_newer, update_catalog, activate, install_dependency)
security.declareProtected(Permissions.ManagePortal, security.declareProtected(Permissions.ManagePortal,
'resolveBusinessTemplateListDependency') 'resolveBusinessTemplateListDependency')
def resolveBusinessTemplateListDependency(self, template_title_list, def resolveBusinessTemplateListDependency(self, template_title_list):
newest_only=True): available_bt5_list = self.getRepositoryBusinessTemplateList()
available_bt5_list = self.getRepositoryBusinessTemplateList(
newest_only=newest_only)
template_title_list = set(template_title_list) template_title_list = set(template_title_list)
installed_bt5_title_list = self.getInstalledBusinessTemplateTitleList() installed_bt5_title_list = self.getInstalledBusinessTemplateTitleList()
...@@ -1245,37 +1245,44 @@ class TemplateTool (BaseTool): ...@@ -1245,37 +1245,44 @@ class TemplateTool (BaseTool):
for available_bt5 in available_bt5_list: for available_bt5 in available_bt5_list:
if available_bt5.title in template_title_list: if available_bt5.title in template_title_list:
template_title_list.remove(available_bt5.title) template_title_list.remove(available_bt5.title)
document = self.getInstalledBusinessTemplate(available_bt5.title, bt5 = self.decodeRepositoryBusinessTemplateUid(available_bt5.uid)
strict=True) bt5_set.add(bt5)
if not newest_only or document is None or (document is not None and \ meta_dependency_set = set()
(int(document.getRevision()) < int(available_bt5.getRevision()))): for dep_repository, dep_id in self.getDependencyList(bt5):
bt5 = self.decodeRepositoryBusinessTemplateUid(available_bt5.uid) if dep_repository != 'meta':
bt5_set.add(bt5) bt5_set.add((dep_repository, dep_id))
for dep_repository, dep_id in self.getDependencyList(bt5): else:
if dep_repository != 'meta': meta_dependency_set.add((dep_repository, dep_id))
bt5_set.add((dep_repository, dep_id)) for dep_repository, dep_id in meta_dependency_set:
else: provider_list = self.getProviderList(dep_id)
provider_list = self.getProviderList(dep_id) provider_installed = False
provider_installed = False provider_title = None
for provider in provider_list: for provider in provider_list:
if provider in [i[1].replace(".bt5", "") for i in bt5_set] or \ if provider in [i[1].replace(".bt5", "") for i in bt5_set] or \
provider in installed_bt5_title_list or \ provider in installed_bt5_title_list or \
provider in template_title_list: provider in template_title_list:
provider_installed = True provider_title = provider
for candidate in available_bt5_list:
if candidate.title == provider:
bt5_set.add(\
self.decodeRepositoryBusinessTemplateUid(
candidate.uid))
break break
break
if not provider_installed: if provider_title is None and len(provider_list) == 1:
if len(provider_list) == 1: provider_title = provider_list[0]
for candidate in available_bt5_list: LOG('resolveBT, provider_title', 0, provider_title)
if candidate.title == provider_list[0]: if provider_title:
bt5_set.add(\ for candidate in available_bt5_list:
self.decodeRepositoryBusinessTemplateUid( if candidate.title == provider_title:
candidate.uid)) bt5_set.add(\
break self.decodeRepositoryBusinessTemplateUid(
else: candidate.uid))
raise BusinessTemplateMissingDependency,\ break
"Unable to resolve dependencies for %s, options are %s" \ else:
% (dep_id, provider_list) raise BusinessTemplateMissingDependency,\
"Unable to resolve dependencies for %s, options are %s" \
% (dep_id, provider_list)
if len(template_title_list) > 0: if len(template_title_list) > 0:
raise BusinessTemplateUnknownError, 'The Business Template %s could not be found on repositories %s' % \ raise BusinessTemplateUnknownError, 'The Business Template %s could not be found on repositories %s' % \
...@@ -1294,11 +1301,15 @@ class TemplateTool (BaseTool): ...@@ -1294,11 +1301,15 @@ class TemplateTool (BaseTool):
operation_log = [] operation_log = []
resolved_template_list = self.resolveBusinessTemplateListDependency( resolved_template_list = self.resolveBusinessTemplateListDependency(
template_list, newest_only=only_newer) template_list)
if not install_dependency: if not install_dependency:
installed_bt5_set = set([x.title
for x in self.getInstalledBusinessTemplatesList()])
def checkAvailability(bt_title):
return bt_title in template_list or bt_title in installed_bt5_set
missing_dependency_list = [i[1] for i in resolved_template_list missing_dependency_list = [i[1] for i in resolved_template_list
if i[1].replace(".bt5", "") not in template_list] if not checkAvailability(i[1].replace(".bt5", ""))]
if len(missing_dependency_list) > 0: if len(missing_dependency_list) > 0:
raise BusinessTemplateMissingDependency,\ raise BusinessTemplateMissingDependency,\
"Impossible to install, please install the following dependencies before: %s" \ "Impossible to install, please install the following dependencies before: %s" \
...@@ -1471,4 +1482,68 @@ class TemplateTool (BaseTool): ...@@ -1471,4 +1482,68 @@ class TemplateTool (BaseTool):
'%s.' % (bt5_title, base_url_list)) '%s.' % (bt5_title, base_url_list))
return None return None
security.declareProtected(Permissions.ManagePortal,
'upgradeSite')
def upgradeSite(self, bt5_list, deprecated_after_script_dict=None,
deprecated_reinstall_set=None, dry_run=False,
delete_orphaned=False,
keep_bt5_id_set=None):
"""
Upgrade many business templates at a time. bt5_list should
contains only final business templates, then all dependencies
are calculated, and missing business templates will be added,
old business templates will be updated, and orphelin business
templates will be deleted
keep_bt5_id_set: business template that should not be deleted.
This is useful if we want to keep an old business
template without updating it and without removing it
deprecated_reinstall_set: this parameter needs to be removed
by setting it at business template level.
It list all business templates who needs
reinstall
"""
# make sure that we updated informations on repository
self.updateRepositoryBusinessTemplateList(self.getRepositoryList())
# do upgrade
message_list = []
deprecated_reinstall_set = deprecated_reinstall_set or set()
def append(message):
message_list.append(message)
LOG('upgradeSite', 0, message)
dependency_list = [x[1] for x in \
self.resolveBusinessTemplateListDependency(bt5_list)]
update_bt5_list = self.getRepositoryBusinessTemplateList(
template_list=dependency_list)
update_bt5_list.sort(key=lambda x: dependency_list.index(x.title))
for bt5 in update_bt5_list:
reinstall = bt5.title in deprecated_reinstall_set
if not(reinstall) and bt5.version_state == 'present':
continue
append("Update %s business template in state %s%s" % \
(bt5.title, bt5.version_state, (reinstall and ' (reinstall)') or ''))
if not(dry_run):
bt5_url = "%s/%s" % (bt5.repository, bt5.title)
self.updateBusinessTemplateFromUrl(bt5_url)
if delete_orphaned:
if keep_bt5_id_set is None:
keep_bt5_id_set = set()
to_remove_bt5_list = [x for x in self.getInstalledBusinessTemplateList()
if x.title not in dependency_list]
sorted_to_remove_bt5_id_list = self.sortDownloadedBusinessTemplateList(
[x.id for x in to_remove_bt5_list])
sorted_to_remove_bt5_id_list.reverse()
to_remove_bt5_list.sort(
key=lambda x: sorted_to_remove_bt5_id_list.index(x.id))
for bt in to_remove_bt5_list:
if bt.title in keep_bt5_id_set:
continue
append("Uninstall business template %s" % bt.title)
if not(dry_run):
# XXX Here is missing parameters to really remove stuff
bt.uninstall()
return message_list
InitializeClass(TemplateTool) InitializeClass(TemplateTool)
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
<string>my_title</string> <string>my_title</string>
<string>my_role_name_list</string> <string>my_role_name_list</string>
<string>my_condition</string> <string>my_condition</string>
<string>my_local_roles_group_id</string> <string>my_local_role_group</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -71,6 +71,7 @@ if len(uids) == 0:\n ...@@ -71,6 +71,7 @@ if len(uids) == 0:\n
id_list = []\n id_list = []\n
portal_status_message = \'\'\n portal_status_message = \'\'\n
current_uid_list=[]\n current_uid_list=[]\n
installed_business_template_title_list = context.getInstalledBusinessTemplateTitleList()\n
for uid in uids:\n for uid in uids:\n
current_uid_list.append(uid)\n current_uid_list.append(uid)\n
repository, id = context.decodeRepositoryBusinessTemplateUid(uid)\n repository, id = context.decodeRepositoryBusinessTemplateUid(uid)\n
...@@ -79,8 +80,11 @@ for uid in uids:\n ...@@ -79,8 +80,11 @@ for uid in uids:\n
# Check for missing dependencies\n # Check for missing dependencies\n
for uid in uids:\n for uid in uids:\n
repository, id = context.decodeRepositoryBusinessTemplateUid(uid)\n repository, id = context.decodeRepositoryBusinessTemplateUid(uid)\n
dependency_list = context.getDependencyList((repository, id));\n dependency_list = context.getDependencyList((repository, id))\n
for dep_repository, dep_id in dependency_list:\n for dep_repository, dep_id in dependency_list:\n
if dep_id != id and \\\n
dep_id in installed_business_template_title_list:\n
continue\n
if dep_id not in id_list:\n if dep_id not in id_list:\n
id_list.append(dep_id)\n id_list.append(dep_id)\n
if dep_repository != \'meta\':\n if dep_repository != \'meta\':\n
......
41047 41048
\ 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="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/lines</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Uses of taxes</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>preferred_tax_use_property</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>preference</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: []</string> </value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value> <string>Manage properties</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -94,15 +94,10 @@ for f in form.get_fields():\n ...@@ -94,15 +94,10 @@ for f in form.get_fields():\n
listbox = request.get(\'listbox\') # XXX: hardcoded field name\n listbox = request.get(\'listbox\') # XXX: hardcoded field name\n
if listbox is not None:\n if listbox is not None:\n
listbox_line_list = []\n listbox_line_list = []\n
listbox = getattr(request,\'listbox\',None) # XXX: hardcoded field name\n for key, value in sorted(listbox.iteritems()):\n
listbox_keys = listbox.keys()\n value[\'listbox_key\'] = key\n
listbox_keys.sort()\n listbox_line_list.append(value)\n
for key in listbox_keys:\n doaction_param_list[\'listbox\'] = tuple(listbox_line_list)\n
listbox_line = listbox[key]\n
listbox_line[\'listbox_key\'] = key\n
listbox_line_list.append(listbox[key])\n
listbox_line_list = tuple(listbox_line_list)\n
doaction_param_list[\'listbox\'] = listbox_line_list # XXX: hardcoded field name\n
\n \n
try:\n try:\n
context.portal_workflow.doActionFor(\n context.portal_workflow.doActionFor(\n
...@@ -123,10 +118,11 @@ except ValidationFailed, error_message:\n ...@@ -123,10 +118,11 @@ except ValidationFailed, error_message:\n
# that would become an error.\n # that would become an error.\n
log("Status message has been truncated")\n log("Status message has been truncated")\n
message = "%s ..." % message[:(2000 - 4)]\n message = "%s ..." % message[:(2000 - 4)]\n
return context.Base_redirect(form_id,\n else:\n
keep_items={\'portal_status_message\': message}, **kw)\n message = request.get(\'portal_status_message\')\n
\n if message is None:\n
portal_status_message = request.get(\'portal_status_message\', translateString(\'Status changed.\'))\n message = translateString(\'Status changed.\')\n
kw.clear() # useful ?\n
\n \n
# Allow to redirect to another document\n # Allow to redirect to another document\n
redirect_document_path = request.get(\'redirect_document_path\', None)\n redirect_document_path = request.get(\'redirect_document_path\', None)\n
...@@ -137,7 +133,7 @@ else:\n ...@@ -137,7 +133,7 @@ else:\n
redirect_document = context\n redirect_document = context\n
\n \n
return redirect_document.Base_redirect(form_id,\n return redirect_document.Base_redirect(form_id,\n
keep_items={\'portal_status_message\': portal_status_message})\n keep_items={\'portal_status_message\': message}, **kw)\n
]]></string> </value> ]]></string> </value>
......
...@@ -425,11 +425,15 @@ div.listbox-content-fixed-width{\n ...@@ -425,11 +425,15 @@ div.listbox-content-fixed-width{\n
}\n }\n
\n \n
table.listbox td.listbox-table-no-result-row{\n table.listbox td.listbox-table-no-result-row{\n
background-color:#DAE6F6;\n
color:#001730;\n
border: 1px solid #3D6474;\n border: 1px solid #3D6474;\n
text-align:center;\n text-align:center;\n
}\n }\n
\n \n
table.listbox tr.listbox-stat-line{\n table.listbox tr.listbox-stat-line{\n
background-color:#C1DAEB;\n
color:#001730;\n
border-top: 1px solid #3D6474;\n border-top: 1px solid #3D6474;\n
}\n }\n
\n \n
......
2012-10-16 arnaud.fontaine
* Fix background color of stat and no cell ListBox lines.
2012-08-07 Kazuhiko 2012-08-07 Kazuhiko
* update FCKeditor to 2.6.8. * update FCKeditor to 2.6.8.
......
1085 1086
\ No newline at end of file \ No newline at end of file
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2010 Nexedi SA and Contributors. # Copyright (c) 2010 Nexedi SA and Contributors.
...@@ -148,6 +149,10 @@ class TestERP5Discussion(ERP5TypeTestCase): ...@@ -148,6 +149,10 @@ class TestERP5Discussion(ERP5TypeTestCase):
self.assertSameSet([], web_section2.getDocumentValueList()) self.assertSameSet([], web_section2.getDocumentValueList())
def test_02_ReferenceGenerationFromString(self):
s = "a test by ivan !@#$%^&*()[]\\é"
self.assertEqual('a-test-by-ivan', self.portal.Base_generateReferenceFromString(s))
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestERP5Discussion)) suite.addTest(unittest.makeSuite(TestERP5Discussion))
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
Tests invoice creation from simulation. Tests invoice creation from simulation.
""" """
import sys, zipfile, xml.dom.minidom
import StringIO
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import FileUpload, DummyMailHost from Products.ERP5Type.tests.utils import FileUpload, DummyMailHost
...@@ -1574,12 +1576,15 @@ class TestInvoice(TestInvoiceMixin): ...@@ -1574,12 +1576,15 @@ class TestInvoice(TestInvoiceMixin):
self.assertEquals(DateTime(2002, 03, 04), self.assertEquals(DateTime(2002, 03, 04),
invoice_transaction_movement.getStopDate()) invoice_transaction_movement.getStopDate())
def test_Invoice_viewAsODT(self): def test_Invoice_viewAsODT(self):
resource = self.portal.getDefaultModule( resource = self.portal.getDefaultModule(
self.resource_portal_type).newContent( self.resource_portal_type).newContent(
portal_type=self.resource_portal_type, portal_type=self.resource_portal_type,
title='Resource',) title='Resource',)
resource_tax = self.portal.getDefaultModule(
self.resource_portal_type).newContent(
portal_type=self.resource_portal_type,
title='Resource Tax',)
client = self.portal.organisation_module.newContent( client = self.portal.organisation_module.newContent(
portal_type='Organisation', title='Client') portal_type='Organisation', title='Client')
vendor = self.portal.organisation_module.newContent( vendor = self.portal.organisation_module.newContent(
...@@ -1593,14 +1598,78 @@ class TestInvoice(TestInvoiceMixin): ...@@ -1593,14 +1598,78 @@ class TestInvoice(TestInvoiceMixin):
source_section_value=vendor, source_section_value=vendor,
destination_value=client, destination_value=client,
destination_section_value=client) destination_section_value=client)
line = invoice.newContent(portal_type=self.invoice_line_portal_type, product_line1 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource, resource_value=resource,
quantity=10, quantity=10,
base_contribution='tax1',
price=3) price=3)
product_line2 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource,
quantity=20,
base_contribution='tax1',
price=5)
product_line3 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource,
quantity=60,
base_contribution='tax2',
price=5)
product_line4 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource,
quantity=60,
price=3)
product_line5 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource,
quantity=7,
price=20)
tax_line1 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource_tax,
use='trade/tax',
base_contribution='tax1',
quantity=130,
price=0.2)
tax_line2 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource_tax,
use='trade/tax',
base_contribution='tax2',
quantity=300,
price=0.05)
tax_line3 = invoice.newContent(portal_type=self.invoice_line_portal_type,
resource_value=resource_tax,
use='trade/tax',
base_contribution='tax3',
quantity=20,
price=0.1)
invoice.confirm() invoice.confirm()
self.tic() self.tic()
odt = invoice.Invoice_viewAsODT() odt = invoice.Invoice_viewAsODT()
import cStringIO
output = cStringIO.StringIO()
output.write(odt)
m = OpenDocumentTextFile(output)
text_content=m.toString().encode('ascii','replace')
if text_content.find('Resource Tax') != -1 :
self.fail('fail to delete the vat line in product line')
if text_content.find('Vat Code') == -1 :
self.fail('fail to add the vat code')
if text_content.find('Amount') == -1 :
self.fail('fail to add the amount for each tax')
if text_content.find('Rate') == -1 :
self.fail('fail to add the Rate for each tax')
tax1_product_total_price=str(10*3+20*5)
if text_content.find(tax1_product_total_price) == -1 :
self.fail('fail to get the total price of products which tax1')
tax2_product_total_price=str(60*5)
if text_content.find(tax2_product_total_price) == -1 :
self.fail('fail to get the total price of products which tax2')
no_tax_product_total_price=str(60*3+7*20)
if text_content.find(no_tax_product_total_price) == -1 :
self.fail('fail to get the total price of products which have no tax')
product_total_price_no_tax=str(10*3+20*5+60*5+60*3+7*20)
if text_content.find(product_total_price_no_tax) == -1 :
self.fail('fail to get the total price of the products without tax')
product_total_price=str(10*3+20*5+60*5+60*3+7*20+130*0.2+300*0.05+20*0.1)
if text_content.find(product_total_price) == -1 :
self.fail('fail to get the total price of the products with tax')
from Products.ERP5OOo.tests.utils import Validator from Products.ERP5OOo.tests.utils import Validator
odf_validator = Validator() odf_validator = Validator()
err_list = odf_validator.validate(odt) err_list = odf_validator.validate(odt)
...@@ -3502,6 +3571,28 @@ class TestPurchaseInvoice(TestInvoice, ERP5TypeTestCase): ...@@ -3502,6 +3571,28 @@ class TestPurchaseInvoice(TestInvoice, ERP5TypeTestCase):
stepTic stepTic
""" """
class OpenDocumentTextFile :
def __init__ (self, filelikeobj) :
zip = zipfile.ZipFile(filelikeobj)
self.content = xml.dom.minidom.parseString(zip.read("content.xml"))
def toString (self) :
""" Converts the document to a string. """
buffer = u""
for val in ["text:p", "text:h", "text:list"]:
for paragraph in self.content.getElementsByTagName(val) :
buffer += self.textToString(paragraph) + "\n"
return buffer
def textToString(self, element) :
buffer = u""
for node in element.childNodes :
if node.nodeType == xml.dom.Node.TEXT_NODE :
buffer += node.nodeValue
elif node.nodeType == xml.dom.Node.ELEMENT_NODE :
buffer += self.textToString(node)
return buffer
import unittest import unittest
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -50,14 +50,18 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -50,14 +50,18 @@ class TestTemplateTool(ERP5TypeTestCase):
test_tool_id = 'test_portal_templates' test_tool_id = 'test_portal_templates'
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
return ('erp5_base', 'erp5_csv_style') return ('erp5_core_proxy_field_legacy',
'erp5_full_text_myisam_catalog',
'erp5_base',
'erp5_csv_style')
def getTitle(self): def getTitle(self):
return "Template Tool" return "Template Tool"
def afterSetUp(self): def afterSetUp(self):
self.templates_tool = self.portal.portal_templates self.templates_tool = self.portal.portal_templates
self.setupAutomaticBusinessTemplateRepository() self.setupAutomaticBusinessTemplateRepository(
searchable_business_template_list=["erp5_core", "erp5_base"])
if getattr(self.portal, self.test_tool_id, None) is not None: if getattr(self.portal, self.test_tool_id, None) is not None:
self.portal.manage_delObjects(ids=[self.test_tool_id]) self.portal.manage_delObjects(ids=[self.test_tool_id])
self.portal.newContent(portal_type='Template Tool', self.portal.newContent(portal_type='Template Tool',
...@@ -68,8 +72,7 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -68,8 +72,7 @@ class TestTemplateTool(ERP5TypeTestCase):
self.tic() self.tic()
mark_replaced_bt_list = ["erp5_odt_style", "erp5_pdm", 'erp5_accounting', mark_replaced_bt_list = ["erp5_odt_style", "erp5_pdm", 'erp5_accounting',
'erp5_workflow', 'erp5_configurator', 'erp5_configurator_ung', 'erp5_workflow', 'erp5_configurator', 'erp5_configurator_ung',
'erp5_ingestion_mysql_innodb_catalog', "erp5_configurator_standard", 'erp5_ingestion_mysql_innodb_catalog', "erp5_configurator_standard"]
'erp5_full_text_myisam_catalog']
for bt_name in mark_replaced_bt_list: for bt_name in mark_replaced_bt_list:
bt = self.templates_tool.getInstalledBusinessTemplate(bt_name) bt = self.templates_tool.getInstalledBusinessTemplate(bt_name)
if (bt is not None) and bt.getInstallationState() in ['installed', if (bt is not None) and bt.getInstallationState() in ['installed',
...@@ -408,38 +411,39 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -408,38 +411,39 @@ class TestTemplateTool(ERP5TypeTestCase):
addRepositoryEntry(title='biz', dependency_list=()), addRepositoryEntry(title='biz', dependency_list=()),
addRepositoryEntry(title='ca1', provision_list=('sql',)), addRepositoryEntry(title='ca1', provision_list=('sql',)),
addRepositoryEntry(title='ca2', provision_list=('sql',)), addRepositoryEntry(title='ca2', provision_list=('sql',)),
addRepositoryEntry(title='end', dependency_list=('baz','sql')), addRepositoryEntry(title='a', dependency_list=()),
addRepositoryEntry(title='b', dependency_list=('a'), revision='5'),
addRepositoryEntry(title='end', dependency_list=('baz','sql', 'b')),
) )
# Simulate that we have some installed bt. # Simulate that we have some installed bt.
for bt_id in ('foo', 'ca1'): for bt_id in ('foo', 'ca1', 'b'):
bt = template_tool.newContent(portal_type='Business Template', bt = template_tool.newContent(portal_type='Business Template',
title=bt_id, revision='4', id=bt_id) title=bt_id, revision='4', id=bt_id)
bt.install() bt.install()
bt5_id_list = ['baz'] bt5_id_list = ['baz']
bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list)
self.assertEquals([(repository, 'bar.bt5'), self.assertEquals([(repository, 'foo.bt5'),
(repository, 'bar.bt5'),
(repository, 'baz.bt5')], bt5_list) (repository, 'baz.bt5')], bt5_list)
bt5_id_list = ['foo'] bt5_id_list = ['foo']
bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list)
self.assertEquals([], bt5_list)
bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list,
newest_only=True)
self.assertEquals([], bt5_list)
bt5_list = template_tool.resolveBusinessTemplateListDependency( bt5_list = template_tool.resolveBusinessTemplateListDependency(
bt5_id_list, False) bt5_id_list)
self.assertEquals([(repository, 'foo.bt5')], bt5_list) self.assertEquals([(repository, 'foo.bt5')], bt5_list)
bt5_id_list = ['biz', 'end'] bt5_id_list = ['biz', 'end']
bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list) bt5_list = template_tool.resolveBusinessTemplateListDependency(bt5_id_list)
self.assertEquals([(repository, 'bar.bt5'), self.assertEquals([(repository, 'foo.bt5'),
(repository, 'a.bt5'),
(repository, 'bar.bt5'),
(repository, 'b.bt5'),
(repository, 'ca1.bt5'),
(repository, 'baz.bt5'), (repository, 'baz.bt5'),
(repository, 'biz.bt5'), (repository, 'end.bt5'),
(repository, 'end.bt5')], bt5_list) (repository, 'biz.bt5')], bt5_list)
# By removing ca1, we remove the choice for the "sql" provider. # By removing ca1, we remove the choice for the "sql" provider.
# Therefore template tool does not know any more what to take for "sql". # Therefore template tool does not know any more what to take for "sql".
...@@ -447,12 +451,12 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -447,12 +451,12 @@ class TestTemplateTool(ERP5TypeTestCase):
self.assertRaises(BusinessTemplateMissingDependency, self.assertRaises(BusinessTemplateMissingDependency,
template_tool.resolveBusinessTemplateListDependency, template_tool.resolveBusinessTemplateListDependency,
bt5_id_list, False) bt5_id_list)
bt5_id_list = ['erp5_do_not_exist'] bt5_id_list = ['erp5_do_not_exist']
self.assertRaises(BusinessTemplateUnknownError, self.assertRaises(BusinessTemplateUnknownError,
template_tool.resolveBusinessTemplateListDependency, template_tool.resolveBusinessTemplateListDependency,
bt5_id_list, False) bt5_id_list)
def test_installBusinessTemplatesFromRepository_simple(self): def test_installBusinessTemplatesFromRepository_simple(self):
""" Simple test for portal_templates.installBusinessTemplatesFromRepository """ Simple test for portal_templates.installBusinessTemplatesFromRepository
...@@ -463,7 +467,7 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -463,7 +467,7 @@ class TestTemplateTool(ERP5TypeTestCase):
self.assertEquals(bt, None) self.assertEquals(bt, None)
operation_log = \ operation_log = \
self.templates_tool.installBusinessTemplateListFromRepository([bt5_name]) self.templates_tool.installBusinessTemplateListFromRepository([bt5_name])
self.assertTrue("Installed %s with" % bt5_name in operation_log[0]) self.assertTrue("Installed %s with" % bt5_name in operation_log[-1])
bt = self.templates_tool.getInstalledBusinessTemplate(bt5_name, strict=True) bt = self.templates_tool.getInstalledBusinessTemplate(bt5_name, strict=True)
self.assertNotEquals(bt, None) self.assertNotEquals(bt, None)
self.assertEquals(bt.getTitle(), bt5_name) self.assertEquals(bt.getTitle(), bt5_name)
...@@ -477,7 +481,7 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -477,7 +481,7 @@ class TestTemplateTool(ERP5TypeTestCase):
operation_log = self.templates_tool.installBusinessTemplateListFromRepository( operation_log = self.templates_tool.installBusinessTemplateListFromRepository(
[bt5_name], only_newer=False) [bt5_name], only_newer=False)
self.assertTrue("Installed %s with" % bt5_name in operation_log[0]) self.assertTrue("Installed %s with" % bt5_name in operation_log[-1])
bt_new = self.templates_tool.getInstalledBusinessTemplate(bt5_name, bt_new = self.templates_tool.getInstalledBusinessTemplate(bt5_name,
strict=True) strict=True)
self.assertNotEquals(bt.getId(), bt_new.getId()) self.assertNotEquals(bt.getId(), bt_new.getId())
...@@ -509,29 +513,17 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -509,29 +513,17 @@ class TestTemplateTool(ERP5TypeTestCase):
bt5_name = 'erp5_odt_style' bt5_name = 'erp5_odt_style'
operation_log = template_tool.installBusinessTemplateListFromRepository([bt5_name], operation_log = template_tool.installBusinessTemplateListFromRepository([bt5_name],
only_newer=False, update_catalog=1) only_newer=False, update_catalog=1)
self.assertTrue("Installed %s with" % bt5_name in operation_log[-1])
self.assertTrue("Installed %s with" % bt5_name in operation_log[0])
bt = template_tool.getInstalledBusinessTemplate(bt5_name) bt = template_tool.getInstalledBusinessTemplate(bt5_name)
self.assertEquals(bt.getTitle(), bt5_name) self.assertEquals(bt.getTitle(), bt5_name)
self.commit() self.commit()
self.checkFolderReindexAllActivityPresense() self.checkFolderReindexAllActivityPresense()
self.tic() self.tic()
bt5_name = 'erp5_full_text_myisam_catalog'
operation_log = template_tool.installBusinessTemplateListFromRepository(
[bt5_name], only_newer=False)
self.assertTrue("Installed %s with" % bt5_name in operation_log[0])
bt = template_tool.getInstalledBusinessTemplate(bt5_name)
self.assertNotEquals(bt, None)
self.assertEquals(bt.getTitle(), bt5_name)
self.commit()
self.checkFolderReindexAllActivityPresense()
self.tic()
# Install again should not force catalog to be updated # Install again should not force catalog to be updated
operation_log = template_tool.installBusinessTemplateListFromRepository( operation_log = template_tool.installBusinessTemplateListFromRepository(
[bt5_name], only_newer=False) [bt5_name], only_newer=False)
self.assertTrue("Installed %s with" % bt5_name in operation_log[0]) self.assertTrue("Installed %s with" % bt5_name in operation_log[-1])
bt = template_tool.getInstalledBusinessTemplate(bt5_name) bt = template_tool.getInstalledBusinessTemplate(bt5_name)
self.assertNotEquals(bt, None) self.assertNotEquals(bt, None)
self.assertEquals(bt.getTitle(), bt5_name) self.assertEquals(bt.getTitle(), bt5_name)
...@@ -574,7 +566,9 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -574,7 +566,9 @@ class TestTemplateTool(ERP5TypeTestCase):
""" """
bt5_name_list = ['erp5_configurator_ung', 'erp5_configurator_standard'] bt5_name_list = ['erp5_configurator_ung', 'erp5_configurator_standard']
template_tool = self.portal.portal_templates template_tool = self.portal.portal_templates
repository = template_tool.getRepositoryList()[0] for repos in template_tool.getRepositoryList():
if "bootstrap" not in repos:
repository = repos
self.tic() self.tic()
for bt5_name in bt5_name_list: for bt5_name in bt5_name_list:
bt = template_tool.getInstalledBusinessTemplate(bt5_name) bt = template_tool.getInstalledBusinessTemplate(bt5_name)
...@@ -615,18 +609,9 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -615,18 +609,9 @@ class TestTemplateTool(ERP5TypeTestCase):
def test_sortBusinessTemplateList(self): def test_sortBusinessTemplateList(self):
"""Check sorting of a list of business template by their dependencies """Check sorting of a list of business template by their dependencies
""" """
repository = "http://www.erp5.org/dists/snapshot/bt5/"
template_tool = self.portal.portal_templates template_tool = self.portal.portal_templates
# XXX This test requires the usage of the public repository due ".bt5" usage
if repository not in template_tool.getRepositoryList():
self.portal.portal_templates.updateRepositoryBusinessTemplateList([repository])
bt5list = template_tool.resolveBusinessTemplateListDependency(('erp5_credential',)) bt5list = template_tool.resolveBusinessTemplateListDependency(('erp5_credential',))
# because erp5_base is already installed, it is not returned
# by resolveBusinessTemplateListDependency, so append it manualy
bt5list.append((repository, "erp5_base.bt5"))
# add some entropy by disorder bt5list returned by # add some entropy by disorder bt5list returned by
# resolveBusinessTemplateListDependency # resolveBusinessTemplateListDependency
position_list = range(len(bt5list)) position_list = range(len(bt5list))
...@@ -638,19 +623,27 @@ class TestTemplateTool(ERP5TypeTestCase): ...@@ -638,19 +623,27 @@ class TestTemplateTool(ERP5TypeTestCase):
ordered_list = template_tool.sortBusinessTemplateList(new_bt5_list) ordered_list = template_tool.sortBusinessTemplateList(new_bt5_list)
# group orders # group orders
first_group = range(0, 2) first_group = range(0, 6)
second_group = range(2, 4) second_group = range(6, 8)
third_group = range(4, 7) third_group = range(8, 10)
fourth_group = range(7, 8) fourth_group = range(10, 13)
expected_position_dict = dict((('erp5_ingestion_mysql_innodb_catalog.bt5', fifth_group = range(13, 14)
first_group),
('erp5_base.bt5', first_group), expected_position_dict = dict((('erp5_property_sheets', first_group),
('erp5_jquery.bt5', second_group), ('erp5_core_proxy_field_legacy', first_group),
('erp5_ingestion.bt5', second_group), ('erp5_mysql_innodb_catalog', first_group),
('erp5_xhtml_jquery_style.bt5', third_group), ('erp5_core', first_group),
('erp5_web.bt5', third_group), ('erp5_full_text_myisam_catalog', first_group),
('erp5_crm.bt5', third_group), ('erp5_xhtml_style', first_group),
('erp5_credential.bt5', fourth_group))) ('erp5_ingestion_mysql_innodb_catalog', second_group),
('erp5_base', second_group),
('erp5_jquery', third_group),
('erp5_ingestion', third_group),
('erp5_xhtml_jquery_style', fourth_group),
('erp5_web', fourth_group),
('erp5_crm', fourth_group),
('erp5_credential', fifth_group)))
for bt in ordered_list: for bt in ordered_list:
self.assertTrue(ordered_list.index(bt) in expected_position_dict[bt[1]], self.assertTrue(ordered_list.index(bt) in expected_position_dict[bt[1]],
'Expected positions for %r: %r, got %r' % (bt[1], 'Expected positions for %r: %r, got %r' % (bt[1],
......
...@@ -27,13 +27,10 @@ ...@@ -27,13 +27,10 @@
# #
############################################################################## ##############################################################################
import time
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Globals import PersistentMapping from Globals import PersistentMapping
from Acquisition import aq_base from Acquisition import aq_base
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet
from zLOG import LOG, INFO
from cStringIO import StringIO
from Products.ERP5Configurator.Tool.ConfiguratorTool import _validateFormToRequest from Products.ERP5Configurator.Tool.ConfiguratorTool import _validateFormToRequest
from Products.ERP5.Document.Item import Item from Products.ERP5.Document.Item import Item
...@@ -262,19 +259,6 @@ class BusinessConfiguration(Item): ...@@ -262,19 +259,6 @@ class BusinessConfiguration(Item):
form = getattr(self, self.getNextTransition().getTransitionFormId()) form = getattr(self, self.getNextTransition().getTransitionFormId())
return _validateFormToRequest(form, REQUEST, **kw) return _validateFormToRequest(form, REQUEST, **kw)
#############
## misc ##
#############
security.declarePrivate('_getConfigurationStack')
def _getConfigurationStack(self):
""" Return list of created by client configuration save objects
sort on id which is an integer. """
result = self.objectValues('ERP5 Configuration Save')
result = map(None, result)
result.sort(lambda x, y: cmp(x.getIntIndex(x.getIntId()),
y.getIntIndex(y.getIntId())))
return result
security.declarePrivate('_getConfSaveForStateFromWorkflowHistory') security.declarePrivate('_getConfSaveForStateFromWorkflowHistory')
def _getConfSaveForStateFromWorkflowHistory(self): def _getConfSaveForStateFromWorkflowHistory(self):
""" Get from workflow history configuration save for this state """ """ Get from workflow history configuration save for this state """
...@@ -282,8 +266,7 @@ class BusinessConfiguration(Item): ...@@ -282,8 +266,7 @@ class BusinessConfiguration(Item):
current_state = self.getCurrentStateValue() current_state = self.getCurrentStateValue()
transition = self.getNextTransition() transition = self.getNextTransition()
next_state = self.unrestrictedTraverse(transition.getDestination()) next_state = self.unrestrictedTraverse(transition.getDestination())
workflow_history = current_state.getWorkflowHistory(self) for wh in current_state.getWorkflowHistory(self):
for wh in workflow_history:
if next_state == self.unrestrictedTraverse(wh['current_state']): if next_state == self.unrestrictedTraverse(wh['current_state']):
configuration_save = self.unrestrictedTraverse(wh['configuration_save_url']) configuration_save = self.unrestrictedTraverse(wh['configuration_save_url'])
return configuration_save return configuration_save
...@@ -339,12 +322,11 @@ class BusinessConfiguration(Item): ...@@ -339,12 +322,11 @@ class BusinessConfiguration(Item):
security.declareProtected(Permissions.View, 'getGlobalConfigurationAttr') security.declareProtected(Permissions.View, 'getGlobalConfigurationAttr')
def getGlobalConfigurationAttr(self, key, default=None): def getGlobalConfigurationAttr(self, key, default=None):
""" Get global business configuration attribute. """ """ Get global business configuration attribute. """
global_configuration_attributes = getattr(self, '_global_configuration_attributes', {}) return getattr(self, '_global_configuration_attributes', {}).get(key, default)
return global_configuration_attributes.get(key, default)
############# Instance and Business Configuration ######################## ############# Instance and Business Configuration ########################
security.declareProtected(Permissions.ModifyPortalContent, 'buildConfiguration') security.declareProtected(Permissions.ModifyPortalContent, 'buildConfiguration')
def buildConfiguration(self, execute_after_setup_script=1): def buildConfiguration(self):
""" """
Build list of business templates according to already saved Build list of business templates according to already saved
Configuration Saves (i.e. user input). Configuration Saves (i.e. user input).
...@@ -355,13 +337,13 @@ class BusinessConfiguration(Item): ...@@ -355,13 +337,13 @@ class BusinessConfiguration(Item):
after_method_id=["updateBusinessTemplateFromUrl", after_method_id=["updateBusinessTemplateFromUrl",
"recursiveImmediateReindexObject", "recursiveImmediateReindexObject",
"immediateReindexObject"]) "immediateReindexObject"])
start = time.time()
LOG("CONFIGURATOR", INFO,
'Build process started for %s' % self.getRelativeUrl())
# build # build
for configuration_save in self._getConfigurationStack(): configuration_save_list = self.contentValues(portal_type='Configuration Save')
configuration_save_list.sort(lambda x, y: cmp(x.getIntIndex(x.getIntId()),
y.getIntIndex(y.getIntId())))
for configuration_save in configuration_save_list:
# XXX: check which items are configure-able # XXX: check which items are configure-able
configuration_item_list = [x for x in configuration_save.contentValues()] configuration_item_list = configuration_save.contentValues()
configuration_item_list.sort(lambda x, y: cmp(x.getIntId(), y.getIntId())) configuration_item_list.sort(lambda x, y: cmp(x.getIntId(), y.getIntId()))
for configurator_item in configuration_item_list: for configurator_item in configuration_item_list:
configurator_item.activate(**kw).build(self.getRelativeUrl()) configurator_item.activate(**kw).build(self.getRelativeUrl())
...@@ -369,16 +351,11 @@ class BusinessConfiguration(Item): ...@@ -369,16 +351,11 @@ class BusinessConfiguration(Item):
kw["tag"] = "configurator_item_%s_%s" % (configurator_item.getId(), kw["tag"] = "configurator_item_%s_%s" % (configurator_item.getId(),
configurator_item.getUid()) configurator_item.getUid())
LOG('CONFIGURATOR', INFO, kw["tag"] = "final_configuration_step_%s" % self.getId()
'Build process started for %s ended after %.02fs' % (self.getRelativeUrl(), kw["after_method_id"] = ["build", 'immediateReindexObject', \
time.time() - start)) "recursiveImmediateReindexObject"]
if execute_after_setup_script:
kw["tag"] = "final_configuration_step_%s" % self.getId()
kw["after_method_id"] = ["build", 'immediateReindexObject', \
"recursiveImmediateReindexObject"]
self.activate(**kw).ERP5Site_afterConfigurationSetup() self.activate(**kw).ERP5Site_afterConfigurationSetup()
if self.portal_workflow.isTransitionPossible(self, 'install'): if self.portal_workflow.isTransitionPossible(self, 'install'):
self.activate(after_tag=kw["tag"]).install() self.activate(after_tag=kw["tag"]).install()
...@@ -113,7 +113,8 @@ class TestLiveConfiguratorWorkflowMixin(SecurityTestCase): ...@@ -113,7 +113,8 @@ class TestLiveConfiguratorWorkflowMixin(SecurityTestCase):
self.stepCleanUpRequest() self.stepCleanUpRequest()
self.restricted_security = 0 self.restricted_security = 0
self.setupAutomaticBusinessTemplateRepository() self.setupAutomaticBusinessTemplateRepository(
searchable_business_template_list=["erp5_core", "erp5_base"])
# it is required by SecurityTestCase # it is required by SecurityTestCase
self.workflow_tool = self.portal.portal_workflow self.workflow_tool = self.portal.portal_workflow
......
...@@ -83,16 +83,13 @@ class EditorWidget(Widget.TextAreaWidget): ...@@ -83,16 +83,13 @@ class EditorWidget(Widget.TextAreaWidget):
""" """
here = REQUEST['here'] here = REQUEST['here']
text_editor = field.get_value('text_editor') text_editor = field.get_value('text_editor')
if text_editor == 'text_area': if text_editor == 'bespin':
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST)
elif text_editor == 'bespin':
# XXX The usage of bespin editor depends of erp5_bespin bt5 # XXX The usage of bespin editor depends of erp5_bespin bt5
# installed and still experimental. If erp5_bespin is not installed, it # installed and still experimental. If erp5_bespin is not installed, it
# render standard an standard editor field. # render standard an standard editor field.
bespin_support = getattr(here, 'bespin_support',None) bespin_support = getattr(here, 'bespin_support',None)
if bespin_support is None: if bespin_support is not None:
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST) return bespin_support.pt_render(
return bespin_support.pt_render(
extra_context= { extra_context= {
'field' : field, 'field' : field,
'inputvalue' : value, 'inputvalue' : value,
...@@ -100,9 +97,8 @@ class EditorWidget(Widget.TextAreaWidget): ...@@ -100,9 +97,8 @@ class EditorWidget(Widget.TextAreaWidget):
}) })
elif text_editor == "xinha": elif text_editor == "xinha":
xinha_support = getattr(here, 'xinha_support', None) xinha_support = getattr(here, 'xinha_support', None)
if xinha_support is None: if xinha_support is not None:
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST) return xinha_support.pt_render(
return xinha_support.pt_render(
extra_context= { extra_context= {
'field' : field, 'field' : field,
'field_value' : value, 'field_value' : value,
...@@ -110,27 +106,25 @@ class EditorWidget(Widget.TextAreaWidget): ...@@ -110,27 +106,25 @@ class EditorWidget(Widget.TextAreaWidget):
}) })
elif text_editor == "svg_editor": elif text_editor == "svg_editor":
svg_editor_support = getattr(here, 'svg_editor_support', None) svg_editor_support = getattr(here, 'svg_editor_support', None)
if svg_editor_support is None: if svg_editor_support is not None:
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST) return svg_editor_support.pt_render()
return svg_editor_support.pt_render()
elif text_editor == "spreadsheet_editor": elif text_editor == "spreadsheet_editor":
sheet_editor_support = getattr(here, 'sheet_editor_support', None) sheet_editor_support = getattr(here, 'sheet_editor_support', None)
if sheet_editor_support is None: if sheet_editor_support is not None:
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST) return sheet_editor_support.pt_render()
return sheet_editor_support.pt_render()
elif text_editor == 'ace': elif text_editor == 'ace':
ace_editor_support = getattr(here, 'ace_editor_support', None) ace_editor_support = getattr(here, 'ace_editor_support', None)
if ace_editor_support is None: if ace_editor_support is not None:
return Widget.TextAreaWidth.render(self, field, key, value, REQUEST) return ace_editor_support.pt_render(extra_context={'field': field,
return ace_editor_support.pt_render(extra_context={'field': field,
'content': value, 'content': value,
'id': key}) 'id': key})
else: elif text_editor != 'text_area':
return here.fckeditor_wysiwyg_support.pt_render( return here.fckeditor_wysiwyg_support.pt_render(
extra_context= { extra_context= {
'inputvalue' : value, 'inputvalue' : value,
'inputname' : key 'inputname' : key
}) })
return Widget.TextAreaWidget.render(self, field, key, value, REQUEST)
def render_view(self, field, value, REQUEST=None, render_prefix=None): def render_view(self, field, value, REQUEST=None, render_prefix=None):
""" """
......
...@@ -2746,7 +2746,7 @@ class ListBoxValidator(Validator.Validator): ...@@ -2746,7 +2746,7 @@ class ListBoxValidator(Validator.Validator):
editable_columns = field.get_value('editable_columns') editable_columns = field.get_value('editable_columns')
column_ids = [x[0] for x in columns] column_ids = [x[0] for x in columns]
editable_column_ids = [x[0] for x in editable_columns] editable_column_ids = [x[0] for x in editable_columns]
editable_field_dict = dict() editable_field_dict = {}
for sql in editable_column_ids: for sql in editable_column_ids:
alias = sql.replace('.', '_') alias = sql.replace('.', '_')
editable_field_dict[alias] = ListBoxRenderer( editable_field_dict[alias] = ListBoxRenderer(
...@@ -2754,55 +2754,52 @@ class ListBoxValidator(Validator.Validator): ...@@ -2754,55 +2754,52 @@ class ListBoxValidator(Validator.Validator):
selection_name = field.get_value('selection_name') selection_name = field.get_value('selection_name')
#LOG('ListBoxValidator', 0, 'field = %s, selection_name = %s' % (repr(field), repr(selection_name))) #LOG('ListBoxValidator', 0, 'field = %s, selection_name = %s' % (repr(field), repr(selection_name)))
params = here.portal_selections.getSelectionParamsFor( portal = here.getPortalObject()
params = portal.portal_selections.getSelectionParamsFor(
selection_name, selection_name,
REQUEST=REQUEST) REQUEST=REQUEST)
portal_url = getToolByName(here, 'portal_url') portal_url = portal.portal_url
portal = portal_url.getPortalObject()
result = {} result = {}
error_result = {} error_result = {}
MARKER = [] try:
listbox_uids = REQUEST.get('%s_uid' % field.id, MARKER) listbox_uids = REQUEST['%s_uid' % field.id]
if listbox_uids is MARKER: except KeyError:
raise KeyError, 'Field %s is not present in request object.' % (field.id, ) raise KeyError('Field %s is not present in request object.'
% field.id)
select = field.get_value('select')
if select:
selected_uid_set = set(REQUEST.get('uids', ()))
#LOG('ListBox.validate: REQUEST',0,REQUEST) #LOG('ListBox.validate: REQUEST',0,REQUEST)
errors = [] errors = []
object_list = [] object_list = None
# We have two things to do in the case of temp objects, # We have two things to do in the case of temp objects,
# the first thing is to create a list with new temp objects # the first thing is to create a list with new temp objects
# then try to validate some data, and then create again # then try to validate some data, and then create again
# the list with a listbox as parameter. Like this we # the list with a listbox as parameter. Like this we
# can use tales expression # can use tales expression
for uid in listbox_uids:
if str(uid).find('new') == 0:
list_method = field.get_value('list_method')
list_method = getattr(here, list_method.method_name)
#LOG('ListBoxValidator', 0, 'call %s' % repr(list_method))
object_list = list_method(REQUEST=REQUEST, **params)
break
listbox = {} listbox = {}
for uid in listbox_uids: for uid in listbox_uids:
if str(uid).find('new') == 0: if uid[:4] == 'new_':
o = None if object_list is None:
for object in object_list: list_method = field.get_value('list_method')
if object.getUid()==uid: list_method = getattr(here, list_method.method_name)
o = object #LOG('ListBoxValidator', 0, 'call %s' % repr(list_method))
if o is None: object_list = list_method(REQUEST=REQUEST, **params)
row_key = uid[4:]
for o in object_list:
if o.getUid() == uid:
break
else:
# First case: dialog input to create new objects # First case: dialog input to create new objects
o = newTempBase(portal, uid[4:]) # Arghhh - XXX acquisition problem - use portal root o = newTempBase(portal, row_key) # Arghhh - XXX acquisition problem - use portal root
o.uid = uid o.uid = uid
listbox[uid[4:]] = {} listbox[row_key] = row_result = {}
# We first try to set a listbox corresponding to all things # We first try to set a listbox corresponding to all things
# we can validate, so that we can use the same list # we can validate, so that we can use the same list
# as the one used for displaying the listbox # as the one used for displaying the listbox
for sql in editable_column_ids: for sql in editable_column_ids:
alias = sql.replace('.', '_') editable_field = editable_field_dict.get(sql.replace('.', '_'))
if '.' in sql:
property_id = '.'.join(sql.split('.')[1:]) # Only take trailing part
else:
property_id = alias
editable_field = editable_field_dict.get(alias)
if editable_field is not None: if editable_field is not None:
error_result_key = '%s_%s' % (editable_field.id, o.uid) error_result_key = '%s_%s' % (editable_field.id, o.uid)
key = 'field_' + error_result_key key = 'field_' + error_result_key
...@@ -2810,39 +2807,31 @@ class ListBoxValidator(Validator.Validator): ...@@ -2810,39 +2807,31 @@ class ListBoxValidator(Validator.Validator):
try: try:
value = editable_field._validate_helper(key, REQUEST) # We need cell value = editable_field._validate_helper(key, REQUEST) # We need cell
# Here we set the property # Here we set the property
listbox[uid[4:]][sql] = value row_result[sql] = value
except ValidationError, err: except ValidationError, err:
pass pass
except KeyError: except KeyError:
pass pass
# Here we generate again the object_list with listbox the listbox we # Here we generate again the object_list with listbox the listbox we
# have just created # have just created
if len(listbox)>0: if listbox:
list_method = field.get_value('list_method') list_method = field.get_value('list_method')
list_method = getattr(here, list_method.method_name) list_method = getattr(here, list_method.method_name)
REQUEST.set(field.id, listbox) REQUEST.set(field.id, listbox)
object_list = list_method(REQUEST=REQUEST, **params) object_list = list_method(REQUEST=REQUEST, **params)
for uid in listbox_uids: for uid in listbox_uids:
if str(uid).find('new') == 0: row_result = {}
if uid[:4] == 'new_':
# First case: dialog input to create new objects # First case: dialog input to create new objects
#o = newTempBase(here, uid[4:]) # Arghhh - XXX acquisition problem - use portal root row_key = uid[4:]
#o.uid = uid for o in object_list:
o = None if o.getUid() == uid:
for object in object_list: break
if object.getUid()==uid: else:
o = object o = newTempBase(portal, row_key) # Arghhh - XXX acquisition problem - use portal root
if o is None:
# First case: dialog input to create new objects
o = newTempBase(portal, uid[4:]) # Arghhh - XXX acquisition problem - use portal root
o.uid = uid o.uid = uid
result[uid[4:]] = {}
for sql in editable_column_ids: for sql in editable_column_ids:
alias = sql.replace('.', '_') editable_field = editable_field_dict.get(sql.replace('.', '_'))
if '.' in sql:
property_id = '.'.join(sql.split('.')[1:]) # Only take trailing part
else:
property_id = alias
editable_field = editable_field_dict.get(alias)
if editable_field is not None: if editable_field is not None:
REQUEST.set('cell', o) REQUEST.set('cell', o)
editable = editable_field.get_value('editable', REQUEST=REQUEST) editable = editable_field.get_value('editable', REQUEST=REQUEST)
...@@ -2851,8 +2840,8 @@ class ListBoxValidator(Validator.Validator): ...@@ -2851,8 +2840,8 @@ class ListBoxValidator(Validator.Validator):
error_result_key = '%s_%s' % (editable_field.id, o.uid) error_result_key = '%s_%s' % (editable_field.id, o.uid)
key = 'field_' + error_result_key key = 'field_' + error_result_key
try: try:
value = editable_field._validate_helper(key, REQUEST) # We need cell row_result[sql] = editable_field._validate_helper(
result[uid[4:]][sql] = value key, REQUEST) # We need cell
except ValidationError, err: except ValidationError, err:
#LOG("ListBox ValidationError",0,str(err)) #LOG("ListBox ValidationError",0,str(err))
err.field_id = error_result_key err.field_id = error_result_key
...@@ -2869,43 +2858,34 @@ class ListBoxValidator(Validator.Validator): ...@@ -2869,43 +2858,34 @@ class ListBoxValidator(Validator.Validator):
# because sometimes, we can be provided bad uids # because sometimes, we can be provided bad uids
try : try :
o = here.portal_catalog.getObject(uid) o = here.portal_catalog.getObject(uid)
except (KeyError, NotFound, ValueError): except (KeyError, NotFound, ValueError), err:
o = None
if o is None:
# It is possible that this object is not catalogged yet. So # It is possible that this object is not catalogged yet. So
# the object must be obtained from ZODB. # the object must be obtained from ZODB.
if not object_list: if object_list is None:
list_method = field.get_value('list_method') list_method = field.get_value('list_method')
list_method = getattr(here, list_method.method_name) list_method = getattr(here, list_method.method_name)
object_list = list_method(REQUEST=REQUEST, **params) object_list = list_method(REQUEST=REQUEST, **params)
for object in object_list: for o in object_list:
try: try:
if object.getUid() == int(uid): if o.getUid() == int(uid):
o = object
break break
except ValueError: except ValueError:
if str(object.getUid()) == uid: if str(o.getUid()) == uid:
o = object
break break
for sql in editable_column_ids:
alias = sql.replace('.', '_')
if '.' in sql:
property_id = '.'.join(sql.split('.')[1:]) # Only take trailing part
else: else:
property_id = alias raise err
editable_field = editable_field_dict.get(alias) row_key = o.getUrl()
for sql in editable_column_ids:
editable_field = editable_field_dict.get(sql.replace('.', '_'))
if editable_field is not None: if editable_field is not None:
REQUEST.set('cell', o) # We need cell REQUEST.set('cell', o) # We need cell
if editable_field.get_value('editable', REQUEST=REQUEST) \ if editable_field.get_value('editable', REQUEST=REQUEST) and \
and field.need_validate(REQUEST): editable_field.need_validate(REQUEST):
error_result_key = '%s_%s' % (editable_field.id, o.uid) error_result_key = '%s_%s' % (editable_field.id, o.uid)
key = 'field_' + error_result_key key = 'field_' + error_result_key
try: try:
value = editable_field._validate_helper(key, REQUEST) row_result[sql] = error_result[error_result_key] = \
error_result[error_result_key] = value editable_field._validate_helper(key, REQUEST)
if not result.has_key(o.getUrl()):
result[o.getUrl()] = {}
result[o.getUrl()][sql] = value
except ValidationError, err: except ValidationError, err:
err.field_id = error_result_key err.field_id = error_result_key
errors.append(err) errors.append(err)
...@@ -2916,6 +2896,9 @@ class ListBoxValidator(Validator.Validator): ...@@ -2916,6 +2896,9 @@ class ListBoxValidator(Validator.Validator):
#except: #except:
else: else:
LOG("ListBox WARNING",0,"Object uid %s could not be validated" % uid) LOG("ListBox WARNING",0,"Object uid %s could not be validated" % uid)
result[row_key] = row_result
if select:
row_result['listbox_selected'] = uid in selected_uid_set
if len(errors) > 0: if len(errors) > 0:
#LOG("ListBox FormValidationError",0,str(error_result)) #LOG("ListBox FormValidationError",0,str(error_result))
#LOG("ListBox FormValidationError",0,str(errors)) #LOG("ListBox FormValidationError",0,str(errors))
......
...@@ -64,6 +64,23 @@ class TestDocumentWithPreConversion(TestDocument): ...@@ -64,6 +64,23 @@ class TestDocumentWithPreConversion(TestDocument):
'Embedded-XXX?format=jpeg&display=large&quality=75'], 'Embedded-XXX?format=jpeg&display=large&quality=75'],
web_page.Base_extractImageUrlList()) web_page.Base_extractImageUrlList())
def test_Base_isConvertible(self):
"""
Test pre converion only happens on proper documents.
"""
print "da"
image = self.portal.image_module.newContent(portal_type='Image',
reference='Embedded-XXX',
version='001',
language='en')
# empty image is not convertible
self.assertEqual(False, image.Base_isConvertible())
# image with data is convertible
upload_file = makeFileUpload('cmyk_sample.jpg')
image.edit(file=upload_file)
self.tic()
self.assertEqual(True, image.Base_isConvertible())
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -400,8 +400,7 @@ def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None): ...@@ -400,8 +400,7 @@ def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
sci = StateChangeInfo( sci = StateChangeInfo(
ob, self, status, tdef, old_sdef, new_sdef, kwargs) ob, self, status, tdef, old_sdef, new_sdef, kwargs)
# put the error message in the workflow history # put the error message in the workflow history
sci.setWorkflowVariable(ob, workflow_id=self.id, sci.setWorkflowVariable(error_message=before_script_error_message)
error_message = before_script_error_message)
if validation_exc : if validation_exc :
# reraise validation failed exception # reraise validation failed exception
raise validation_exc, None, validation_exc_traceback raise validation_exc, None, validation_exc_traceback
......
...@@ -30,19 +30,14 @@ from Products.DCWorkflow.Expression import StateChangeInfo ...@@ -30,19 +30,14 @@ from Products.DCWorkflow.Expression import StateChangeInfo
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
allow_class(StateChangeInfo) allow_class(StateChangeInfo)
def setWorkflowVariable(self, object, workflow_id='edit_workflow',**kw): def setWorkflowVariable(self, **kw):
""" """
Allows to go through security checking and let a Allows to go through security checking and let a
script allows to modify a workflow variable script allows to modify a workflow variable
""" """
workflow_history = object.workflow_history history = self.object.workflow_history[self.workflow.id]
for workflow in workflow_history.keys(): history[-1].update(kw)
if len(workflow_history[workflow])!= 0 and workflow==workflow_id: history._p_changed = 1
last_status = workflow_history[workflow][-1]
for variable in kw.keys():
if last_status.has_key(variable):
last_status[variable]=kw[variable]
StateChangeInfo.setWorkflowVariable = setWorkflowVariable StateChangeInfo.setWorkflowVariable = setWorkflowVariable
...@@ -570,7 +570,7 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase): ...@@ -570,7 +570,7 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase):
public_bt5_repository_list) public_bt5_repository_list)
else: else:
self.portal.portal_templates.updateRepositoryBusinessTemplateList( self.portal.portal_templates.updateRepositoryBusinessTemplateList(
bt5_repository_path_list, None) bt5_repository_path_list, None)
elif accept_public: elif accept_public:
self.portal.portal_templates.updateRepositoryBusinessTemplateList( self.portal.portal_templates.updateRepositoryBusinessTemplateList(
public_bt5_repository_list) public_bt5_repository_list)
......
...@@ -608,7 +608,7 @@ def main(argument_list=None): ...@@ -608,7 +608,7 @@ def main(argument_list=None):
opts, args = getopt.getopt(sys.argv[1:], opts, args = getopt.getopt(sys.argv[1:],
"hpvD", ["help", "verbose", "profile", "coverage=", "portal_id=", "hpvD", ["help", "verbose", "profile", "coverage=", "portal_id=",
"data_fs_path=", "data_fs_path=",
"bt5_path", "bt5_path=",
"firefox_bin=", "firefox_bin=",
"xvfb_bin=", "xvfb_bin=",
"recreate_catalog=", "erp5_sql_connection_string=", "recreate_catalog=", "erp5_sql_connection_string=",
......
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