Commit 1c1f266e authored by Cédric de Saint Martin's avatar Cédric de Saint Martin

Merge branch 'master' into no_bridge

parents 3f49f908 986dd36f
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Software Instance</string> </value> <value> <string>Requester</string> </value>
</item> </item>
<item> <item>
<key> <string>visible</string> </key> <key> <string>visible</string> </key>
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
<key> <string>text</string> </key> <key> <string>text</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
string:${object_url}/Base_jumpToRelatedObject?base_category=predecessor&portal_type=Software+Instance string:${object_url}/Base_jumpToRelatedObject?base_category=predecessor&portal_type:list=Software+Instance&portal_type:list=Hosting+Subscription
]]></string> </value> ]]></string> </value>
</item> </item>
......
...@@ -36,3 +36,7 @@ class Person(ERP5Person): ...@@ -36,3 +36,7 @@ class Person(ERP5Person):
"""Revokes existing certificate""" """Revokes existing certificate"""
self._checkCertificateRequest() self._checkCertificateRequest()
self._revokeCertificate() self._revokeCertificate()
def getPaymentState(self):
"""Allows to catalog slap_date in payment_state column"""
return self.getSlapState()
...@@ -108,3 +108,7 @@ class SoftwareInstance(Item): ...@@ -108,3 +108,7 @@ class SoftwareInstance(Item):
if size != len(visited) + 1: if size != len(visited) + 1:
raise DisconnectedSoftwareTree raise DisconnectedSoftwareTree
return True return True
def getPaymentState(self):
"""Allows to catalog slap_date in payment_state column"""
return self.getSlapState()
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<item>SlaveInstanceContraint</item> <item>SlaveInstanceContraint</item>
<item>SoftwareInstance</item> <item>SoftwareInstance</item>
<item>TextDocument</item> <item>TextDocument</item>
<item>VariationRange</item>
</portal_type> </portal_type>
<portal_type id="Software Instance"> <portal_type id="Software Instance">
<item>Reference</item> <item>Reference</item>
......
...@@ -6,6 +6,18 @@ ...@@ -6,6 +6,18 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>constraint_property</string> </key> <key> <string>constraint_property</string> </key>
<value> <value>
...@@ -22,6 +34,18 @@ ...@@ -22,6 +34,18 @@
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>ssl_certificate_constraint</string> </value> <value> <string>ssl_certificate_constraint</string> </value>
</item> </item>
<item>
<key> <string>int_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>message_no_such_property</string> </key> <key> <string>message_no_such_property</string> </key>
<value> <string>SSL Certificate must be set</string> </value> <value> <string>SSL Certificate must be set</string> </value>
...@@ -30,6 +54,52 @@ ...@@ -30,6 +54,52 @@
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Property Existence Constraint</string> </value> <value> <string>Property Existence Constraint</string> </value>
</item> </item>
<item>
<key> <string>string_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>test_tales_expression</string> </key>
<value> <string>python: context.SoftwareInstance_getStatus() != \'Destroyed\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -6,6 +6,18 @@ ...@@ -6,6 +6,18 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>constraint_property</string> </key> <key> <string>constraint_property</string> </key>
<value> <value>
...@@ -22,6 +34,18 @@ ...@@ -22,6 +34,18 @@
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>ssl_key_constraint</string> </value> <value> <string>ssl_key_constraint</string> </value>
</item> </item>
<item>
<key> <string>int_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item> <item>
<key> <string>message_no_such_property</string> </key> <key> <string>message_no_such_property</string> </key>
<value> <string>SSL Key must be set</string> </value> <value> <string>SSL Key must be set</string> </value>
...@@ -30,6 +54,52 @@ ...@@ -30,6 +54,52 @@
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Property Existence Constraint</string> </value> <value> <string>Property Existence Constraint</string> </value>
</item> </item>
<item>
<key> <string>string_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>test_tales_expression</string> </key>
<value> <string>python: context.SoftwareInstance_getStatus() != \'Destroyed\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -6,6 +6,18 @@ ...@@ -6,6 +6,18 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>constraint_base_category</string> </key> <key> <string>constraint_base_category</string> </key>
<value> <value>
...@@ -16,7 +28,7 @@ ...@@ -16,7 +28,7 @@
</item> </item>
<item> <item>
<key> <string>constraint_portal_type</string> </key> <key> <string>constraint_portal_type</string> </key>
<value> <string>python: \'Software Instance\'</string> </value> <value> <string>python: (\'Slave Instance\', \'Software Instance\')</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -59,4 +71,34 @@ ...@@ -59,4 +71,34 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData> </ZopeData>
...@@ -286,9 +286,7 @@ ...@@ -286,9 +286,7 @@
</item> </item>
<item> <item>
<key> <string>lines</string> </key> <key> <string>lines</string> </key>
<value> <value> <string></string> </value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item> </item>
<item> <item>
<key> <string>list_action</string> </key> <key> <string>list_action</string> </key>
...@@ -416,7 +414,7 @@ ...@@ -416,7 +414,7 @@
</item> </item>
<item> <item>
<key> <string>css_class</string> </key> <key> <string>css_class</string> </key>
<value> <string>hidden_label gadget</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>default_display_style</string> </key> <key> <string>default_display_style</string> </key>
...@@ -500,7 +498,7 @@ ...@@ -500,7 +498,7 @@
<item> <item>
<key> <string>list_method</string> </key> <key> <string>list_method</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
...@@ -615,19 +613,6 @@ ...@@ -615,19 +613,6 @@
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <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: int(context.restrictedTraverse(context.REQUEST.get(\'box_relative_url\', \'\')).KnowledgeBox_getDefaultPreferencesDict().get(\'listbox_selection_list_lines\', None) or 10)</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="Method" module="Products.Formulator.MethodField"/> <global name="Method" module="Products.Formulator.MethodField"/>
</pickle> </pickle>
......
<?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># Did not import Products.ERP5Security.ERP5GroupManager\n
# because of semantic matter.\n
class ConsistencyError(Exception):\n
pass\n
\n
predecessor_software_instance = context\n
while (predecessor_software_instance is not None):\n
root_software_instance = predecessor_software_instance\n
predecessor_software_instance = predecessor_software_instance.getPredecessorRelatedValue(\n
portal_type=["Software Instance", "Slave Instance"])\n
\n
root_hosting_subscription = root_software_instance.getPredecessorRelatedValue(\n
portal_type="Hosting Subscription")\n
\n
# XXX-Antoine: As Romain wanted it, we raise an error if it\'s not attached to a\n
# root Hosting Subscription.\n
if root_hosting_subscription is None:\n
raise ConsistencyError(("Software instance %s has no hosting "\n
"subscription as root.") % context.getReference())\n
\n
return root_hosting_subscription.getUid()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_getRootHostingSubscriptionUid</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,21 +50,21 @@ ...@@ -50,21 +50,21 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>predecessor_software_instance = context\n <value> <string>movement = context\n
while (predecessor_software_instance is not None):\n \n
root_software_instance = predecessor_software_instance\n if movement.getSimulationState() in movement.getCausalityValue(portal_type=\'Business Link\').getCompletedStateList():\n
predecessor_software_instance = predecessor_software_instance.getPredecessorRelatedValue(\n return True\n
portal_type=["Software Instance", "Slave Instance"])\n \n
return root_software_instance.getUid()\n return False\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>rule</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>SoftwareInstance_getRootSoftwareInstanceUid</string> </value> <value> <string>SimulationMovement_testDeliverySimulationRule</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -65,7 +65,10 @@ if source_section == destination_section or source_section is None \\\n ...@@ -65,7 +65,10 @@ if source_section == destination_section or source_section is None \\\n
or destination_section is None:\n or destination_section is None:\n
return False\n return False\n
\n \n
return True\n if movement.getSimulationState() in movement.getCausalityValue(portal_type=\'Business Link\').getCompletedStateList():\n
return True\n
\n
return False\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
...@@ -58,7 +58,10 @@ if delivery_movement is not None and (\n ...@@ -58,7 +58,10 @@ if delivery_movement is not None and (\n
and delivery_movement.getPortalType() not in movement.getPortalTaxMovementTypeList()):\n and delivery_movement.getPortalType() not in movement.getPortalTaxMovementTypeList()):\n
return False\n return False\n
\n \n
return True\n if movement.getSimulationState() in movement.getCausalityValue(portal_type=\'Business Link\').getCompletedStateList():\n
return True\n
\n
return False\n
</string> </value> </string> </value>
</item> </item>
<item> <item>
......
...@@ -56,6 +56,13 @@ ...@@ -56,6 +56,13 @@
receivable_account_type_list = (\'asset/receivable\',)\n receivable_account_type_list = (\'asset/receivable\',)\n
payable_account_type_list = (\'liability/payable\',)\n payable_account_type_list = (\'liability/payable\',)\n
\n \n
if movement.getQuantity() == 0:\n
# do not create empty payment movements\n
return False\n
\n
if movement.getSimulationState() not in movement.getCausalityValue(portal_type=\'Business Link\').getCompletedStateList():\n
return False\n
\n
for account in (movement.getSourceValue(portal_type=\'Account\'),\n for account in (movement.getSourceValue(portal_type=\'Account\'),\n
movement.getDestinationValue(portal_type=\'Account\')):\n movement.getDestinationValue(portal_type=\'Account\')):\n
if account is not None:\n if account is not None:\n
......
...@@ -51,17 +51,18 @@ ...@@ -51,17 +51,18 @@
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>software_instance = state_change[\'object\']\n <value> <string>software_instance = state_change[\'object\']\n
portal = context.getPortalObject()\n portal = software_instance.getPortalObject()\n
\n \n
root_software_instance = software_instance\n root_hosting_subscription = portal.portal_catalog.getResultValue(uid=software_instance.SoftwareInstance_getRootHostingSubscriptionUid())\n
while (software_instance is not None):\n tag = \'%s_%s_inProgress\' % (software_instance.getUid(), root_hosting_subscription.getTitle())\n
root_software_instance = software_instance\n root_software_instance = root_hosting_subscription.HostingSubscription_requestRootSoftwareInstance(tag)\n
software_instance = software_instance.getPredecessorRelatedValue()\n
\n \n
for software_instance in context.portal_catalog(\n # Use iterative algorithm instead of recursive approach in order to avoid\n
portal_type=\'Software Instance\',\n # complexity as much as possible.\n
root_uid=root_software_instance.getUid()):\n flat_tree = [root_software_instance]\n
software_instance = software_instance.getObject()\n while flat_tree:\n
software_instance = flat_tree.pop(0)\n
flat_tree.extend(software_instance.getPredecessorValueList())\n
try:\n try:\n
software_instance.Item_getInstancePackingListLine(service_relative_url=portal.portal_preferences.getPreferredInstanceCleanupResource())\n software_instance.Item_getInstancePackingListLine(service_relative_url=portal.portal_preferences.getPreferredInstanceCleanupResource())\n
except ValueError:\n except ValueError:\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># Get the software_instance\n
software_instance = state_change[\'object\']\n
\n
# Change the title\n
software_instance.edit(title=state_change.kwargs[\'new_name\'])\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_rename</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Rename software instance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -64,6 +64,8 @@ is_slave = kwargs.get("shared", False)\n ...@@ -64,6 +64,8 @@ is_slave = kwargs.get("shared", False)\n
sla_xml = kwargs["sla_xml"]\n sla_xml = kwargs["sla_xml"]\n
state = kwargs["state"]\n state = kwargs["state"]\n
\n \n
from DateTime import DateTime\n
\n
if is_slave == True:\n if is_slave == True:\n
software_instance_portal_type = "Slave Instance"\n software_instance_portal_type = "Slave Instance"\n
else:\n else:\n
...@@ -72,20 +74,23 @@ else:\n ...@@ -72,20 +74,23 @@ else:\n
# graph allows to "simulate" tree change after requested operation\n # graph allows to "simulate" tree change after requested operation\n
graph = {}\n graph = {}\n
# Get root software instance and create initial graph\n # Get root software instance and create initial graph\n
predecessor_software_instance = software_instance\n root_hosting_subscription = software_instance.portal_catalog.getResultValue(\n
while (predecessor_software_instance is not None):\n uid=software_instance.SoftwareInstance_getRootHostingSubscriptionUid(),\n
predecessor_software_instance_pred_uid_list = predecessor_software_instance.getPredecessorUidList()\n )\n
graph[predecessor_software_instance.getUid()] = predecessor_software_instance_pred_uid_list\n \n
# as this walking is not fetching all instances fill predecessors into graph, in order to have\n predecessor_list = root_hosting_subscription.getPredecessorValueList()\n
# "nearly" complete representation\n graph[root_hosting_subscription.getUid()] = [predecessor.getUid() for predecessor in predecessor_list]\n
for uid in predecessor_software_instance_pred_uid_list:\n while True:\n
if uid not in graph:\n try:\n
graph[uid] = []\n current_software_instance = predecessor_list.pop(0)\n
root_software_instance = predecessor_software_instance\n except IndexError:\n
predecessor_software_instance = predecessor_software_instance.getPredecessorRelatedValue(\n break\n
portal_type="Software Instance")\n current_software_instance_predecessor_list = current_software_instance.getPredecessorValueList() or []\n
\n graph[current_software_instance.getUid()] = [predecessor.getUid()\n
tag = "%s_%s_inProgress" % (root_software_instance.getUid(),\n for predecessor in current_software_instance_predecessor_list]\n
predecessor_list.extend(current_software_instance_predecessor_list)\n
\n
tag = "%s_%s_inProgress" % (root_hosting_subscription.getUid(),\n
requested_partition_reference)\n requested_partition_reference)\n
\n \n
# Check if it already exists\n # Check if it already exists\n
...@@ -94,68 +99,66 @@ request_software_instance = software_instance.portal_catalog.getResultValue(\n ...@@ -94,68 +99,66 @@ request_software_instance = software_instance.portal_catalog.getResultValue(\n
# XXX: User based property is used in non manual operation\n # XXX: User based property is used in non manual operation\n
# XXX-2: Do we really need to use root_uid?\n # XXX-2: Do we really need to use root_uid?\n
title=requested_partition_reference,\n title=requested_partition_reference,\n
root_uid=root_software_instance.getUid(),\n root_uid=root_hosting_subscription.getUid(),\n
)\n )\n
\n \n
if (portal.portal_activities.countMessageWithTag(tag) > 0):\n
# The software instance is already under creation but can not be fetched from catalog\n
# As it is not possible to fetch informations, it is better to raise an error\n
raise NotImplementedError(tag)\n
\n
root_software_instance = root_hosting_subscription.HostingSubscription_requestRootSoftwareInstance(tag)\n
\n
# above query does not find root software instance, but as this case is easy\n # above query does not find root software instance, but as this case is easy\n
# to find, just check if such request does not come and raise\n # to find, just check if such request does not come and raise\n
if root_software_instance.getTitle() == requested_partition_reference:\n if root_software_instance.getTitle() == requested_partition_reference:\n
raise ValueError(\'It is disallowed to request root software instance\')\n raise ValueError(\'It is disallowed to request root software instance\')\n
\n \n
if (request_software_instance is None):\n if (request_software_instance is None):\n
if (portal.portal_activities.countMessageWithTag(tag) > 0):\n # First time that the software instance is requested\n
# The software instance is already under creation but can not be fetched from catalog\n # Create a new one\n
# As it is not possible to fetch informations, it is better to raise an error\n module = software_instance.getDefaultModule(portal_type="Software Instance")\n
raise NotImplementedError(tag)\n request_software_instance = module.newContent(\n
else:\n portal_type=software_instance_portal_type,\n
# First time that the software instance is requested\n title=requested_partition_reference,\n
# Create a new one\n source_reference=software_type,\n
module = software_instance.getDefaultModule(portal_type="Software Instance")\n text_content=instance_xml,\n
request_software_instance = module.newContent(\n sla_xml=sla_xml,\n
portal_type=software_instance_portal_type,\n activate_kw={\'tag\': tag},\n
title=requested_partition_reference,\n **portal.Base_getNewSoftwareInstanceCoordinate()\n
source_reference=software_type,\n )\n
text_content=instance_xml,\n request_software_instance.portal_workflow.doActionFor(request_software_instance, \'validate_action\')\n
sla_xml=sla_xml,\n packing_list_line = software_instance.getAggregateRelatedValue(portal_type="Sale Packing List Line")\n
activate_kw={\'tag\': tag},\n subscription = packing_list_line.getAggregateValue(portal_type="Hosting Subscription")\n
**portal.Base_getNewSoftwareInstanceCoordinate()\n software_release_document = context.portal_catalog.getResultValue(\n
)\n portal_type=\'Software Release\',\n
request_software_instance.portal_workflow.doActionFor(request_software_instance, \'validate_action\')\n url_string=software_release_url_string)\n
if state == "started":\n base_sale_packing_list = packing_list_line.getParentValue()\n
request_software_instance.startRequested()\n trade_condition = packing_list_line.getSpecialise(portal_type="Sale Trade Condition")\n
if state == "stopped":\n sale_order = portal.getDefaultModule(portal_type="Sale Order").newContent(\n
request_software_instance.stopRequested()\n portal_type="Sale Order",\n
setup_service_relative_url = portal.portal_preferences.getPreferredInstanceSetupResource()\n destination=base_sale_packing_list.getDestination(),\n
packing_list_line = software_instance.getAggregateRelatedValue(portal_type="Sale Packing List Line")\n destination_section=base_sale_packing_list.getDestinationSection(),\n
subscription = packing_list_line.getAggregateValue(portal_type="Hosting Subscription")\n destination_decision=base_sale_packing_list.getDestinationDecision(),\n
software_release_document = context.portal_catalog.getResultValue(\n start_date=DateTime(),\n
portal_type=\'Software Release\',\n received_date=DateTime(),\n
url_string=software_release_url_string)\n # XXX Hardcoded values\n
base_sale_packing_list = packing_list_line.getParentValue()\n source="organisation_module/vifib_internet",\n
trade_condition = packing_list_line.getSpecialise(portal_type="Sale Trade Condition")\n source_section="organisation_module/vifib_internet",\n
sale_order = portal.getDefaultModule(portal_type="Sale Order").newContent(\n price_currency="currency_module/EUR",\n
portal_type="Sale Order",\n activate_kw={\'tag\': tag},\n
destination=base_sale_packing_list.getDestination(),\n
destination_section=base_sale_packing_list.getDestinationSection(),\n
destination_decision=base_sale_packing_list.getDestinationDecision(),\n
start_date=DateTime(),\n
received_date=DateTime(),\n
# XXX Hardcoded values\n
source="organisation_module/vifib_internet",\n
source_section="organisation_module/vifib_internet",\n
price_currency="currency_module/EUR",\n
activate_kw={\'tag\': tag},\n
)\n )\n
\n \n
sale_order.setSpecialise(trade_condition, portal_type="Sale Trade Condition")\n setup_service_relative_url = portal.portal_preferences.getPreferredInstanceSetupResource()\n
sale_order_line = sale_order.newContent(\n sale_order.setSpecialise(trade_condition, portal_type="Sale Trade Condition")\n
portal_type="Sale Order Line",\n sale_order_line = sale_order.newContent(\n
resource=setup_service_relative_url,\n portal_type="Sale Order Line",\n
quantity=1,\n resource=setup_service_relative_url,\n
aggregate_value_list=[request_software_instance,subscription,software_release_document],\n quantity=1,\n
activate_kw={\'tag\': tag},\n aggregate_value_list=[request_software_instance,subscription,software_release_document],\n
)\n activate_kw={\'tag\': tag},\n
sale_order.order()\n )\n
sale_order.order()\n
else:\n else:\n
# Update existing software instance\n # Update existing software instance\n
# Sale Packing List interaction has to be requested automatically with an interaction workflow\n # Sale Packing List interaction has to be requested automatically with an interaction workflow\n
...@@ -168,21 +171,30 @@ else:\n ...@@ -168,21 +171,30 @@ else:\n
# Update the predecessor category of the original caller\n # Update the predecessor category of the original caller\n
predecessor_software_instance = request_software_instance.getPredecessorRelatedValue(\n predecessor_software_instance = request_software_instance.getPredecessorRelatedValue(\n
portal_type="Software Instance")\n portal_type="Software Instance")\n
\n
predecessor = None\n
if predecessor_software_instance is None:\n if predecessor_software_instance is None:\n
raise ValueError(\'Requested Software Instance %s should have a predecessor\' % request_software_instance.getRelativeUrl())\n sale_packing_list_line = context.SoftwareInstance_getInstanceSetupPackingListLine(state_change)\n
hosting_subscription = sale_packing_list_line.getAggregateValue(portal_type=\'Hosting Subscription\')\n
if request_software_instance.getPredecessorRelatedValue(portal_type="Hosting Subscription") != hosting_subscription:\n
raise ValueError(\'Requested Software Instance %s should have a predecessor from same tree\' % request_software_instance.getRelativeUrl())\n
else:\n
predecessor = hosting_subscription\n
else:\n else:\n
predecessor_uid_list = predecessor_software_instance.getPredecessorUidList()\n predecessor = predecessor_software_instance\n
predecessor_uid_list.remove(request_software_instance.getUid())\n \n
predecessor_software_instance.edit(\n predecessor_uid_list = predecessor.getPredecessorUidList()\n
predecessor_uid_list=predecessor_uid_list,\n predecessor_uid_list.remove(request_software_instance.getUid())\n
activate_kw={\'tag\': tag},)\n predecessor.edit(\n
graph[predecessor_software_instance.getUid()] = predecessor_uid_list\n predecessor_uid_list=predecessor_uid_list,\n
activate_kw={\'tag\': tag},)\n
graph[predecessor.getUid()] = predecessor_uid_list\n
\n \n
if state == \'started\':\n if state == \'started\':\n
request_software_instance.startRequested()\n request_software_instance.startRequested()\n
request_software_instance.activate(after_tag=tag).requestStartComputerPartition()\n request_software_instance.activate(after_tag=tag).requestStartComputerPartition()\n
elif state == \'stopped\':\n elif state == \'stopped\':\n
request_software_instance.stopRequested() \n request_software_instance.stopRequested()\n
request_software_instance.activate(after_tag=tag).requestStopComputerPartition()\n request_software_instance.activate(after_tag=tag).requestStopComputerPartition()\n
else:\n else:\n
raise ValueError(\'State %r is not supported\' % state)\n raise ValueError(\'State %r is not supported\' % state)\n
...@@ -195,7 +207,7 @@ if not request_software_instance.getUid() in graph:\n ...@@ -195,7 +207,7 @@ if not request_software_instance.getUid() in graph:\n
graph[software_instance.getUid()] = software_instance.getPredecessorUidList() + [request_software_instance.getUid()]\n graph[software_instance.getUid()] = software_instance.getPredecessorUidList() + [request_software_instance.getUid()]\n
\n \n
# check if all elements are still connected and if there is no cycle\n # check if all elements are still connected and if there is no cycle\n
software_instance.checkConnected(graph, root_software_instance.getUid())\n software_instance.checkConnected(graph, root_hosting_subscription.getUid())\n
software_instance.checkNotCyclic(graph)\n software_instance.checkNotCyclic(graph)\n
\n \n
software_instance.edit(\n software_instance.edit(\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>try:\n
packing_list_line = context.SoftwareInstance_getInstanceHostingPackingListLine(state_change)\n
except ValueError:\n
pass\n
else:\n
packing_list = packing_list_line.getParentValue()\n
if packing_list.getPortalObject().portal_workflow.isTransitionPossible(packing_list, \'stop\'):\n
packing_list.stop()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_requestStopIfNeeded</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -52,11 +52,15 @@ ...@@ -52,11 +52,15 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
from Products.DCWorkflow.DCWorkflow import ValidationFailed\n
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n
\n \n
software_instance = state_change[\'object\']\n software_instance = state_change[\'object\']\n
portal = software_instance.getPortalObject()\n portal = software_instance.getPortalObject()\n
\n \n
if software_instance.SoftwareInstance_getStatus() == \'Destroyed\':\n
raise ValidationFailed\n
\n
# avoid conflicting with "in progress" update tasks\n # avoid conflicting with "in progress" update tasks\n
tag_list = ["%s_destroyInProgress" % software_instance.getUid(), "%s_startInProgress" % software_instance.getUid()]\n tag_list = ["%s_destroyInProgress" % software_instance.getUid(), "%s_startInProgress" % software_instance.getUid()]\n
for tag in tag_list:\n for tag in tag_list:\n
...@@ -73,7 +77,11 @@ service_uid_state_mapping = {\n ...@@ -73,7 +77,11 @@ service_uid_state_mapping = {\n
setup_resource_uid: [\'stopped\'],\n setup_resource_uid: [\'stopped\'],\n
hosting_resource_uid: [\'started\', \'delivered\']\n hosting_resource_uid: [\'started\', \'delivered\']\n
}\n }\n
previous_packing_list_line = context.SoftwareInstance_getInstancePackingListLine(state_change)\n try:\n
previous_packing_list_line = context.SoftwareInstance_getInstancePackingListLine(state_change)\n
except ValueError:\n
# no packing list yet, no need to update\n
return\n
\n \n
if previous_packing_list_line.getResourceUid() == hosting_resource_uid:\n if previous_packing_list_line.getResourceUid() == hosting_resource_uid:\n
if previous_packing_list_line.getSimulationState() not in service_uid_state_mapping[hosting_resource_uid]:\n if previous_packing_list_line.getSimulationState() not in service_uid_state_mapping[hosting_resource_uid]:\n
......
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
<tuple> <tuple>
<string>destroy_computer_partition</string> <string>destroy_computer_partition</string>
<string>destroy_requested</string> <string>destroy_requested</string>
<string>lock</string>
<string>rename</string>
<string>report_computer_partition_bang</string> <string>report_computer_partition_bang</string>
<string>report_computer_partition_error</string> <string>report_computer_partition_error</string>
<string>request_computer_partition</string>
<string>request_destroy_computer_partition</string> <string>request_destroy_computer_partition</string>
<string>request_destroy_computer_partition_action</string> <string>request_destroy_computer_partition_action</string>
<string>request_software_instance</string> <string>request_software_instance</string>
......
...@@ -24,9 +24,9 @@ ...@@ -24,9 +24,9 @@
<tuple> <tuple>
<string>destroy_computer_partition</string> <string>destroy_computer_partition</string>
<string>destroy_requested</string> <string>destroy_requested</string>
<string>lock</string>
<string>report_computer_partition_bang</string> <string>report_computer_partition_bang</string>
<string>report_computer_partition_error</string> <string>report_computer_partition_error</string>
<string>request_computer_partition</string>
<string>request_destroy_computer_partition</string> <string>request_destroy_computer_partition</string>
<string>request_destroy_computer_partition_action</string> <string>request_destroy_computer_partition_action</string>
<string>request_software_instance</string> <string>request_software_instance</string>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StateDefinition" module="Products.DCWorkflow.States"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>locked</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>transitions</string> </key>
<value>
<tuple>
<string>destroy_computer_partition</string>
<string>destroy_requested</string>
<string>request_destroy_computer_partition</string>
<string>request_destroy_computer_partition_action</string>
<string>stop_computer_partition</string>
<string>unlock</string>
</tuple>
</value>
</item>
<item>
<key> <string>type_list</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
<tuple> <tuple>
<string>destroy_computer_partition</string> <string>destroy_computer_partition</string>
<string>destroy_requested</string> <string>destroy_requested</string>
<string>lock</string>
<string>rename</string>
<string>report_computer_partition_bang</string> <string>report_computer_partition_bang</string>
<string>report_computer_partition_error</string> <string>report_computer_partition_error</string>
<string>request_computer_partition</string>
<string>request_destroy_computer_partition</string> <string>request_destroy_computer_partition</string>
<string>request_destroy_computer_partition_action</string> <string>request_destroy_computer_partition_action</string>
<string>request_software_instance</string> <string>request_software_instance</string>
......
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
<tuple> <tuple>
<string>destroy_computer_partition</string> <string>destroy_computer_partition</string>
<string>destroy_requested</string> <string>destroy_requested</string>
<string>lock</string>
<string>rename</string>
<string>report_computer_partition_bang</string> <string>report_computer_partition_bang</string>
<string>report_computer_partition_error</string> <string>report_computer_partition_error</string>
<string>request_computer_partition</string>
<string>request_destroy_computer_partition</string> <string>request_destroy_computer_partition</string>
<string>request_destroy_computer_partition_action</string> <string>request_destroy_computer_partition_action</string>
<string>request_software_instance</string> <string>request_software_instance</string>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>lock</string> </value>
</item>
<item>
<key> <string>new_state_id</string> </key>
<value> <string>locked</string> </value>
</item>
<item>
<key> <string>script_name</string> </key>
<value> <string>SoftwareInstance_requestStopIfNeeded</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string>SoftwareInstance_rename</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>rename</string> </value>
</item>
<item>
<key> <string>new_state_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Rename Software Instance</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>unlock</string> </value>
</item>
<item>
<key> <string>new_state_id</string> </key>
<value> <string>draft</string> </value>
</item>
<item>
<key> <string>script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
352 370
\ No newline at end of file \ No newline at end of file
...@@ -3,6 +3,7 @@ Slave Instance | Reference ...@@ -3,6 +3,7 @@ Slave Instance | Reference
Slave Instance | SlaveInstanceContraint Slave Instance | SlaveInstanceContraint
Slave Instance | SoftwareInstance Slave Instance | SoftwareInstance
Slave Instance | TextDocument Slave Instance | TextDocument
Slave Instance | VariationRange
Software Instance | Reference Software Instance | Reference
Software Instance | SoftwareInstance Software Instance | SoftwareInstance
Software Instance | SoftwareInstanceConstraint Software Instance | SoftwareInstanceConstraint
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/asset/cash/bank</string> <string>account_type/asset/cash/bank</string>
<string>financial_section/asset/current_assets/cash</string> <string>financial_section/asset/current_assets/cash</string>
<string>gap/fr/pcg/5/51/512</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -310,6 +311,51 @@ ...@@ -310,6 +311,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072164.63</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/equity</string> <string>account_type/equity</string>
<string>financial_section/equity/share_capital</string> <string>financial_section/equity/share_capital</string>
<string>gap/fr/pcg/1/10/101</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -310,6 +311,51 @@ ...@@ -310,6 +311,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072157.04</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/liability/payable/collected_vat</string> <string>account_type/liability/payable/collected_vat</string>
<string>financial_section/liability/current/other</string> <string>financial_section/liability/current/other</string>
<string>gap/fr/pcg/4/44/445/4457/44571</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -310,6 +311,51 @@ ...@@ -310,6 +311,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072148.22</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/asset</string> <string>account_type/asset</string>
<string>financial_section/asset/non_current/fixed_assets</string> <string>financial_section/asset/non_current/fixed_assets</string>
<string>gap/fr/pcg/2/21</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -310,6 +311,51 @@ ...@@ -310,6 +311,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072132.24</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/asset</string> <string>account_type/asset</string>
<string>financial_section/asset/current_assets/stock</string> <string>financial_section/asset/current_assets/stock</string>
<string>gap/fr/pcg/3</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -355,6 +356,51 @@ ...@@ -355,6 +356,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072119.36</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/liability/payable</string> <string>account_type/liability/payable</string>
<string>financial_section/liability/current/payable</string> <string>financial_section/liability/current/payable</string>
<string>gap/fr/pcg/4/40/401</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -355,6 +356,51 @@ ...@@ -355,6 +356,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072105.29</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/equity</string> <string>account_type/equity</string>
<string>financial_section/equity/net_profit</string> <string>financial_section/equity/net_profit</string>
<string>gap/fr/pcg/1/12</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -400,6 +401,51 @@ ...@@ -400,6 +401,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072093.86</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/expense</string> <string>account_type/expense</string>
<string>financial_section/expense/op_expense/cogs</string> <string>financial_section/expense/op_expense/cogs</string>
<string>gap/fr/pcg/6</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -355,6 +356,51 @@ ...@@ -355,6 +356,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072085.3</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/asset/receivable</string> <string>account_type/asset/receivable</string>
<string>financial_section/asset/current_assets/receivables</string> <string>financial_section/asset/current_assets/receivables</string>
<string>gap/fr/pcg/4/41/411</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -400,6 +401,51 @@ ...@@ -400,6 +401,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072074.09</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/asset/receivable/refundable_vat</string> <string>account_type/asset/receivable/refundable_vat</string>
<string>financial_section/asset/current_assets/receivables</string> <string>financial_section/asset/current_assets/receivables</string>
<string>gap/fr/pcg/4/44/445/4456/44566</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -490,6 +491,51 @@ ...@@ -490,6 +491,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072058.6</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
<tuple> <tuple>
<string>account_type/income</string> <string>account_type/income</string>
<string>financial_section/income/revenue</string> <string>financial_section/income/revenue</string>
<string>gap/fr/pcg/7</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -355,6 +356,51 @@ ...@@ -355,6 +356,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.52330.26845</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="4.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327072021.77</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
...@@ -194,7 +194,9 @@ ...@@ -194,7 +194,9 @@
<item> <item>
<key> <string>test_method_id</string> </key> <key> <string>test_method_id</string> </key>
<value> <value>
<tuple/> <tuple>
<string>SimulationMovement_testDeliverySimulationRule</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -583,6 +585,51 @@ ...@@ -583,6 +585,51 @@
</value> </value>
</item> </item>
</dictionary> </dictionary>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58652.61044.15803</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass> <reference id="8.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327588714.75</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list> </list>
</tuple> </tuple>
</pickle> </pickle>
......
82 84
\ No newline at end of file \ No newline at end of file
...@@ -630,20 +630,16 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi ...@@ -630,20 +630,16 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi
<value> <int>1</int> </value> <value> <int>1</int> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>format</string> </key>
<value> <string>hosting</string> </value> <value> <string>text/html</string> </value>
</item> </item>
<item> <item>
<key> <string>last_id</string> </key> <key> <string>id</string> </key>
<value> <string>5</string> </value> <value> <string>hosting</string> </value>
</item> </item>
<item> <item>
<key> <string>layout_additional_css</string> </key> <key> <string>layout_additional_css</string> </key>
<value> <value> <string>/vifib_hosting_style/hosting-design.css</string> </value>
<tuple>
<string>/vifib_hosting_style/hosting-design.css</string>
</tuple>
</value>
</item> </item>
<item> <item>
<key> <string>layout_additional_js</string> </key> <key> <string>layout_additional_js</string> </key>
...@@ -781,6 +777,12 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi ...@@ -781,6 +777,12 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi
<key> <string>visible</string> </key> <key> <string>visible</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAk=</string> </persistent>
</value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
...@@ -852,4 +854,85 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi ...@@ -852,4 +854,85 @@ Vifib Cloud is a distributed cloud around the world.<br />Just fill the email fi
<none/> <none/>
</pickle> </pickle>
</record> </record>
<record id="9" aka="AAAAAAAAAAk=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAo=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="10" aka="AAAAAAAAAAo=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superluke</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>915.58653.2524.62566</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1327055846.43</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData> </ZopeData>
81 82
\ No newline at end of file \ No newline at end of file
<local_roles_item>
<local_roles>
<role id='ERP5TypeTestCase'>
<item>Owner</item>
</role>
<role id='test_computer'>
<item>Assignor</item>
</role>
</local_roles>
</local_roles_item>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Email" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>coordinate_text</string> </key>
<value> <string>test_hr_admin@example.org</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_email</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Email</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Sale Trade Condition" module="erp5.portal_type"/> <global name="Career" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -12,22 +12,7 @@ ...@@ -12,22 +12,7 @@
<tuple> <tuple>
<string>Assignee</string> <string>Assignee</string>
<string>Assignor</string> <string>Assignor</string>
<string>Associate</string>
<string>Auditor</string> <string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string> <string>Manager</string>
<string>Owner</string> <string>Owner</string>
</tuple> </tuple>
...@@ -39,8 +24,6 @@ ...@@ -39,8 +24,6 @@
<tuple> <tuple>
<string>Assignee</string> <string>Assignee</string>
<string>Assignor</string> <string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string> <string>Manager</string>
<string>Owner</string> <string>Owner</string>
</tuple> </tuple>
...@@ -52,9 +35,7 @@ ...@@ -52,9 +35,7 @@
<tuple> <tuple>
<string>Assignee</string> <string>Assignee</string>
<string>Assignor</string> <string>Assignor</string>
<string>Associate</string>
<string>Auditor</string> <string>Auditor</string>
<string>Author</string>
<string>Manager</string> <string>Manager</string>
<string>Owner</string> <string>Owner</string>
</tuple> </tuple>
...@@ -64,22 +45,17 @@ ...@@ -64,22 +45,17 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>specialise/sale_trade_condition_module/vifib_trade_condition</string> <string>role/client</string>
<string>destination_section/organisation_module/vifib_client_A</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>10</string> </value> <value> <string>default_career</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Sale Trade Condition</string> </value> <value> <string>Career</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>ViFiB Custom Conditions</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Email" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>coordinate_text</string> </key>
<value> <string>test_updated_vifib_user@example.org</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_email</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Email</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Email" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>coordinate_text</string> </key>
<value> <string>test_vifib_member@example.org</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_email</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Email</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
<portal_type id="Purchase Packing List Line"> <portal_type id="Purchase Packing List Line">
<item>VifibPurchasePackingListLineConstraint</item> <item>VifibPurchasePackingListLineConstraint</item>
</portal_type> </portal_type>
<portal_type id="Sale Order">
<item>VifibSaleOrderCosntraint</item>
</portal_type>
<portal_type id="Software Product"> <portal_type id="Software Product">
<item>VifibSoftwareProductConstraint</item> <item>VifibSoftwareProductConstraint</item>
</portal_type> </portal_type>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByPerson</property> <property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByPerson</property>
<multi_property id='base_category'>destination_section</multi_property> <multi_property id='base_category'>destination_section</multi_property>
</role> </role>
<role id='Auditor'> <role id='Assignor'>
<property id='title'>Related Software Instance Group</property> <property id='title'>Related Software Instance Group</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromSelf</property> <property id='base_category_script'>ERP5Type_getSecurityCategoryFromSelf</property>
<multi_property id='base_category'>aggregate</multi_property> <multi_property id='base_category'>aggregate</multi_property>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
</role> </role>
<role id='Assignee'> <role id='Assignee'>
<property id='title'>Customer of the Instance</property> <property id='title'>Customer of the Instance</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByPerson</property> <property id='base_category_script'>SoftwareType_getSecurityCategoryFromAggregateMovementItemByPerson</property>
<multi_property id='base_category'>destination_section</multi_property> <multi_property id='base_category'>destination_section</multi_property>
</role> </role>
<role id='Assignee'> <role id='Assignee'>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
</role> </role>
<role id='Assignor'> <role id='Assignor'>
<property id='title'>Slave Instance related by Hosting Subscription</property> <property id='title'>Slave Instance related by Hosting Subscription</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByHostingSubscription</property> <property id='base_category_script'>SoftwareType_getSecurityCategoryFromAggregateMovementItemByHostingSubscription</property>
<multi_property id='base_category'>aggregate</multi_property> <multi_property id='base_category'>aggregate</multi_property>
</role> </role>
<role id='Assignor'> <role id='Assignor'>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
</role> </role>
<role id='Assignee'> <role id='Assignee'>
<property id='title'>Customer of the Instance</property> <property id='title'>Customer of the Instance</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByPerson</property> <property id='base_category_script'>SoftwareType_getSecurityCategoryFromAggregateMovementItemByPerson</property>
<multi_property id='base_category'>destination_section</multi_property> <multi_property id='base_category'>destination_section</multi_property>
</role> </role>
<role id='Assignee'> <role id='Assignee'>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
</role> </role>
<role id='Assignor'> <role id='Assignor'>
<property id='title'>Software Instance related by Hosting Subscription</property> <property id='title'>Software Instance related by Hosting Subscription</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromAggregateMovementItemByHostingSubscription</property> <property id='base_category_script'>SoftwareType_getSecurityCategoryFromAggregateMovementItemByHostingSubscription</property>
<multi_property id='base_category'>aggregate</multi_property> <multi_property id='base_category'>aggregate</multi_property>
</role> </role>
</type_roles> </type_roles>
\ No newline at end of file
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
</item> </item>
<item> <item>
<key> <string>test_tales_expression</string> </key> <key> <string>test_tales_expression</string> </key>
<value> <string>python: object.getAggregateValue(portal_type=\'Software Release\') is not None</string> </value> <value> <string>python: object.getAggregateValue(portal_type=\'Software Release\') is not None and object.getSimulationState() not in (\'stopped\', \'delivered\')</string> </value>
</item> </item>
<item> <item>
<key> <string>workflow_state_list</string> </key> <key> <string>workflow_state_list</string> </key>
......
...@@ -2,56 +2,10 @@ ...@@ -2,56 +2,10 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Computer" module="erp5.portal_type"/> <global name="Property Sheet" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item> <item>
<key> <string>_count</string> </key> <key> <string>_count</string> </key>
<value> <value>
...@@ -70,10 +24,6 @@ ...@@ -70,10 +24,6 @@
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>test_computer</string> </value>
</item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <value>
...@@ -82,15 +32,11 @@ ...@@ -82,15 +32,11 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_computer</string> </value> <value> <string>VifibSaleOrderCosntraint</string> </value>
</item>
<item>
<key> <string>last_id</string> </key>
<value> <string>1</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Computer</string> </value> <value> <string>Property Sheet</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Content Existence Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Sale Order Line\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>lines_constraint</string> </value>
</item>
<item>
<key> <string>message_no_subobject</string> </key>
<value> <string>Purchase Packing List Line is not defined</string> </value>
</item>
<item>
<key> <string>message_no_subobject_portal_type</string> </key>
<value> <string>Purchase Packing List Line is not defined</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Content Existence Constraint</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Open Sale Order Line" module="erp5.portal_type"/> <global name="String Attribute Match Constraint" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -13,104 +13,61 @@ ...@@ -13,104 +13,61 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>_range_criterion</string> </key> <key> <string>_local_properties</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>base_price</string> </key>
<value> <float>40.0</float> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>resource/service_module/vm_monthly_hosting</string> <dictionary>
<string>aggregate/subscription_item_module/2</string> <item>
<string>aggregate/subscription_item_module/3</string> <key> <string>id</string> </key>
<string>aggregate/subscription_item_module/4</string> <value> <string>message_property_not_set</string> </value>
<string>aggregate/subscription_item_module/5</string> </item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>comment</string> </key> <key> <string>_range_criterion</string> </key>
<value> <value>
<none/> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>constraint_property</string> </key>
<value> <string>1</string> </value>
</item>
<item>
<key> <string>mapped_value_property_list</string> </key>
<value> <value>
<tuple> <tuple>
<string>base_price</string> <string>reference</string>
<string>additional_price</string>
<string>discount_ratio</string>
<string>exclusive_discount_ratio</string>
<string>surcharge_ratio</string>
<string>variable_additional_price</string>
<string>non_discountable_additional_price</string>
<string>priced_quantity</string>
<string>base_unit_price</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>description</string> </key>
<value> <string>Open Sale Order Line</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>price</string> </key> <key> <string>id</string> </key>
<value> <float>0.0</float> </value> <value> <string>reference_not_empty_constraint</string> </value>
</item> </item>
<item> <item>
<key> <string>priced_quantity</string> </key> <key> <string>message_attribute_match</string> </key>
<value> <float>20.0</float> </value> <value> <string>Reference must be defined</string> </value>
</item> </item>
<item> <item>
<key> <string>quantity</string> </key> <key> <string>message_no_such_property</string> </key>
<value> <float>50.0</float> </value> <value> <string>Reference must be defined</string> </value>
</item> </item>
<item> <item>
<key> <string>start_date_range_max</string> </key> <key> <string>message_property_not_set</string> </key>
<value> <value> <string>Reference must be defined</string> </value>
<object>
<klass>
<global id="1.1" name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1277935200.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item> </item>
<item> <item>
<key> <string>start_date_range_min</string> </key> <key> <string>portal_type</string> </key>
<value> <value> <string>String Attribute Match Constraint</string> </value>
<object>
<klass> <reference id="1.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1272664800.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
...@@ -139,41 +96,7 @@ ...@@ -139,41 +96,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>start_date</string> </key>
<value>
<tuple>
<object>
<klass>
<global id="3.1" name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1272664800.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
<object>
<klass> <reference id="3.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1277935200.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</tuple>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -2,24 +2,33 @@ ...@@ -2,24 +2,33 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Purchase Packing List Line" module="erp5.portal_type"/> <global name="Category Membership Arity Constraint" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>categories</string> </key> <key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>constraint_base_category</string> </key>
<value> <value>
<tuple> <tuple>
<string>resource/service_module/vifib_software_setup</string> <string>specialise</string>
<string>quantity_unit/unit/piece</string>
<string>aggregate/software_release_module/test_software_release</string>
<string>aggregate/computer_module/test_computer</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>constraint_portal_type</string> </key>
<value> <string>1</string> </value> <value> <string>python: (\'Sale Trade Condition\',)</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
...@@ -29,21 +38,23 @@ ...@@ -29,21 +38,23 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>1</string> </value> <value> <string>sale_order_specialise_sale_trade_condition_constraint_constraint</string> </value>
</item> </item>
<item> <item>
<key> <string>index</string> </key> <key> <string>max_arity</string> </key>
<value> <value> <int>1</int> </value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item> </item>
<item> <item>
<key> <string>int_index</string> </key> <key> <string>min_arity</string> </key>
<value> <int>1</int> </value> <value> <int>1</int> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Purchase Packing List Line</string> </value> <value> <string>Category Membership Arity Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
...@@ -57,14 +68,7 @@ ...@@ -57,14 +68,7 @@
<item> <item>
<key> <string>data</string> </key> <key> <string>data</string> </key>
<value> <value>
<dictionary> <dictionary/>
<item>
<key> <string>movement</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -2,68 +2,47 @@ ...@@ -2,68 +2,47 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Computer Partition" module="erp5.portal_type"/> <global name="Property Existence Constraint" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>_Access_contents_information_Permission</string> </key> <key> <string>_identity_criterion</string> </key>
<value> <value>
<tuple> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>_Add_portal_content_Permission</string> </key> <key> <string>_local_properties</string> </key>
<value> <value>
<tuple> <tuple>
<string>Assignee</string> <dictionary>
<string>Assignor</string> <item>
<string>Associate</string> <key> <string>id</string> </key>
<string>Author</string> <value> <string>message_property_not_set</string> </value>
<string>Manager</string> </item>
<string>Owner</string> <item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>_Modify_portal_content_Permission</string> </key> <key> <string>_range_criterion</string> </key>
<value> <value>
<tuple> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>_View_Permission</string> </key> <key> <string>constraint_property</string> </key>
<value> <value>
<tuple> <tuple>
<string>Assignee</string> <string>start_date</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>test_computer_partition</string> </value>
</item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <value>
...@@ -72,21 +51,49 @@ ...@@ -72,21 +51,49 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_computer_partition</string> </value> <value> <string>start_date_existence_constraint</string> </value>
</item>
<item>
<key> <string>message_no_such_property</string> </key>
<value> <string>Property start_date must be defined</string> </value>
</item>
<item>
<key> <string>message_property_not_set</string> </key>
<value> <string>Property start_date must be defined</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Computer Partition</string> </value> <value> <string>Property Existence Constraint</string> </value>
</item> </item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item> <item>
<key> <string>quantity</string> </key> <key> <string>data</string> </key>
<value> <value>
<none/> <dictionary/>
</value> </value>
</item> </item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item> <item>
<key> <string>title</string> </key> <key> <string>data</string> </key>
<value> <string>1</string> </value> <value>
<dictionary/>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?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># XXX For now, this script requires proxy manager\n
\n
# base_category_list : list of category values we need to retrieve\n
# user_name : string obtained from getSecurityManager().getUser().getUserName() [NuxUserGroup]\n
# or from getSecurityManager().getUser().getId() [PluggableAuthService with ERP5GroupManager]\n
# object : object which we want to assign roles to.\n
# portal_type : portal type of object\n
\n
# must always return a list of dicts\n
\n
category_list = []\n
\n
if obj is None:\n
return []\n
\n
item_portal_type = "Hosting Subscription"\n
movement_portal_type = "Sale Order Line"\n
\n
portal = obj.getPortalObject()\n
\n
movement = portal.portal_catalog.getResultValue(\n
portal_type=movement_portal_type,\n
strict_aggregate_uid=obj.getUid(),\n
simulation_state=(\'confirmed\', \'ordered\'),\n
)\n
\n
if movement is not None:\n
item = movement.getAggregateValue(portal_type=item_portal_type)\n
if item is not None:\n
category_list.append({"aggregate": [item.getRelativeUrl()]})\n
\n
return category_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>base_category_list, user_name, obj, portal_type</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareType_getSecurityCategoryFromAggregateMovementItemByHostingSubscription</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
# XXX For now, this script requires proxy manager\n
\n
# base_category_list : list of category values we need to retrieve\n
# user_name : string obtained from getSecurityManager().getUser().getUserName() [NuxUserGroup]\n
# or from getSecurityManager().getUser().getId() [PluggableAuthService with ERP5GroupManager]\n
# object : object which we want to assign roles to.\n
# portal_type : portal type of object\n
\n
# must always return a list of dicts\n
\n
category_list = []\n
\n
if obj is None:\n
return []\n
\n
movement_portal_type = "Sale Order Line"\n
\n
portal = obj.getPortalObject()\n
\n
security_dict = {}\n
\n
parent_url_list = []\n
for movement in portal.portal_catalog(\n
portal_type=movement_portal_type,\n
strict_aggregate_uid=obj.getUid(),\n
simulation_state=(\'ordered\', \'confirmed\'),\n
):\n
item = movement.getDestinationSectionValue(portal_type="Person")\n
if item is not None:\n
parent_url_list.append(item.getRelativeUrl())\n
\n
if len(parent_url_list) > 0:\n
parent_url_list.sort()\n
category_list.append({"destination_section": parent_url_list})\n
return category_list\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>base_category_list, user_name, obj, portal_type</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareType_getSecurityCategoryFromAggregateMovementItemByPerson</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -78,15 +78,17 @@ class TestVifibModuleSecurity(testVifibMixin): ...@@ -78,15 +78,17 @@ class TestVifibModuleSecurity(testVifibMixin):
""" """
portal = self.getPortal() portal = self.getPortal()
self.login(user_name='test_vifib_member') self.login(user_name='test_vifib_member')
error_list = []
for module_id in portal.objectIds(spec=('ERP5 Folder',)): for module_id in portal.objectIds(spec=('ERP5 Folder',)):
if module_id in self.used_module_id_list: if module_id in self.used_module_id_list:
try: try:
portal.restrictedTraverse(module_id) portal.restrictedTraverse(module_id)
except Unauthorized: except Unauthorized:
raise AssertionError, "User can not access '%s'" % module_id error_list.append("User can not access '%s'" % module_id)
else: else:
try: try:
self.assertRaises(Unauthorized, portal.restrictedTraverse, module_id) self.assertRaises(Unauthorized, portal.restrictedTraverse, module_id)
except AssertionError: except AssertionError:
raise AssertionError, "User can access '%s'" % module_id error_list.append("User can access '%s'" % module_id)
self.assertEqual([], error_list, '\n'.join(error_list))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>SaleOrder_updateAggregateLocalRoles</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleOrder_order</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>order</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<list>
<string>Sale Order</string>
</list>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
This script updates all local roles on the object. It requires Assignor\n This script updates all local roles on the object. It requires Assignor\n
proxy role since it may be called by owner in draft state.\n proxy role since it may be called by owner in draft state.\n
"""\n """\n
portal_type_list = ["Software Instance", "Slave Instance", "Hosting Subscription", "Computer Partition"]\n portal_type_list = ["Hosting Subscription", "Computer Partition", "Software Instance", "Slave Instance"]\n
for movement in state_change[\'object\'].getMovementList():\n for movement in state_change[\'object\'].getMovementList():\n
tag = "softinssec_%s" % movement.getUid()\n tag = "softinssec_%s" % movement.getUid()\n
movement.activate(activity=\'SQLQueue\', tag=tag, after_path_and_method_id=(movement.getPath(),\n movement.activate(activity=\'SQLQueue\', tag=tag, after_path_and_method_id=(movement.getPath(),\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
This script updates all local roles on the object. It requires Assignor\n
proxy role since it may be called by owner in draft state.\n
"""\n
portal_type_list = ["Slave Instance", "Software Instance", "Hosting Subscription"]\n
for movement in state_change[\'object\'].getMovementList():\n
tag = "softinssec_%s" % movement.getUid()\n
movement.activate(activity=\'SQLQueue\', tag=tag, after_path_and_method_id=(movement.getPath(),\n
(\'immediateReindexObject\', \'recursiveImmediateReindexObject\'))).serialize()\n
movement.activate(activity=\'SQLQueue\', tag=tag, after_path_and_method_id=(movement.getParentValue().getPath(),\n
(\'immediateReindexObject\', \'recursiveImmediateReindexObject\'))).serialize()\n
for software_instance in movement.getAggregateValueList(portal_type=portal_type_list):\n
software_instance.activate(after_tag=tag).updateLocalRolesOnSecurityGroups()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleOrder_updateAggregateLocalRoles</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
327 335
\ No newline at end of file \ No newline at end of file
...@@ -17,7 +17,6 @@ business_process_module/vifib_sale_business_process ...@@ -17,7 +17,6 @@ business_process_module/vifib_sale_business_process
campaign_module campaign_module
component_module component_module
computer_module computer_module
computer_module/test_computer
credential_update_module credential_update_module
currency_module currency_module
currency_module/EUR currency_module/EUR
......
...@@ -17,7 +17,6 @@ business_process_module/vifib_sale_business_process ...@@ -17,7 +17,6 @@ business_process_module/vifib_sale_business_process
campaign_module campaign_module
component_module component_module
computer_module computer_module
computer_module/test_computer
credential_update_module credential_update_module
currency_module currency_module
currency_module/EUR currency_module/EUR
......
...@@ -3,6 +3,7 @@ person_module/test_hr_admin/** ...@@ -3,6 +3,7 @@ person_module/test_hr_admin/**
person_module/test_sale_agent person_module/test_sale_agent
person_module/test_sale_agent/** person_module/test_sale_agent/**
person_module/test_updated_vifib_user person_module/test_updated_vifib_user
person_module/test_updated_vifib_user/**
person_module/test_vifib_admin person_module/test_vifib_admin
person_module/test_vifib_admin/** person_module/test_vifib_admin/**
person_module/test_vifib_customer person_module/test_vifib_customer
......
...@@ -6,5 +6,6 @@ Internal Packing List | VifibInternalPackingListConstraint ...@@ -6,5 +6,6 @@ Internal Packing List | VifibInternalPackingListConstraint
Person | VifibPersonConstraint Person | VifibPersonConstraint
Purchase Packing List Line | VifibPurchasePackingListLineConstraint Purchase Packing List Line | VifibPurchasePackingListLineConstraint
Purchase Packing List | VifibPurchasePackingListConstraint Purchase Packing List | VifibPurchasePackingListConstraint
Sale Order | VifibSaleOrderCosntraint
Software Product | VifibSoftwareProductConstraint Software Product | VifibSoftwareProductConstraint
Software Release | VifibSoftwareReleaseConstraint Software Release | VifibSoftwareReleaseConstraint
\ No newline at end of file
...@@ -7,4 +7,5 @@ VifibInternalPackingListConstraint ...@@ -7,4 +7,5 @@ VifibInternalPackingListConstraint
VifibInternalPackingListLineConstraint VifibInternalPackingListLineConstraint
VifibPurchasePackingListLineConstraint VifibPurchasePackingListLineConstraint
VifibPurchasePackingListConstraint VifibPurchasePackingListConstraint
VifibSoftwareReleaseConstraint VifibSoftwareReleaseConstraint
\ No newline at end of file VifibSaleOrderCosntraint
\ No newline at end of file
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<item> <item>
<key> <string>arguments_src</string> </key> <key> <string>arguments_src</string> </key>
<value> <string>uid\r\n <value> <string>uid\r\n
SoftwareInstance_getRootSoftwareInstanceUid</string> </value> SoftwareInstance_getRootHostingSubscriptionUid</string> </value>
</item> </item>
<item> <item>
<key> <string>cache_time_</string> </key> <key> <string>cache_time_</string> </key>
...@@ -69,7 +69,7 @@ WHERE\n ...@@ -69,7 +69,7 @@ WHERE\n
<dtml-in prefix="loop" expr="_.range(_.len(uid))">\n <dtml-in prefix="loop" expr="_.range(_.len(uid))">\n
<dtml-call expr="row_list.append([\n <dtml-call expr="row_list.append([\n
uid[loop_item],\n uid[loop_item],\n
SoftwareInstance_getRootSoftwareInstanceUid[loop_item]])">\n SoftwareInstance_getRootHostingSubscriptionUid[loop_item]])">\n
</dtml-in>\n </dtml-in>\n
\n \n
<dtml-if "row_list">\n <dtml-if "row_list">\n
......
32 33
\ 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="Open Sale Order" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>modification_date</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>date</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>creation_date</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>date</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>price_currency</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAY=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source_section/organisation_module/vifib_internet</string>
<string>source/organisation_module/2</string>
<string>destination_section/organisation_module/vifib_client_A</string>
<string>destination/organisation_module/4</string>
<string>specialise/sale_trade_condition_module/vifib_trade_condition</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string>TioLive rents VMS for its clients</string> </value>
</item>
<item>
<key> <string>creation_date</string> </key>
<value>
<object>
<klass>
<global id="1.1" name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1272146400.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>1</string> </value>
</item>
<item>
<key> <string>last_id</string> </key>
<value> <string>1</string> </value>
</item>
<item>
<key> <string>modification_date</string> </key>
<value>
<object>
<klass> <reference id="1.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1273096800.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Open Sale Order</string> </value>
</item>
<item>
<key> <string>price_currency</string> </key>
<value> <string>currency_module/1</string> </value>
</item>
<item>
<key> <string>start_date_range_max</string> </key>
<value>
<object>
<klass> <reference id="1.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1304200800.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>start_date_range_min</string> </key>
<value>
<object>
<klass> <reference id="1.1"/> </klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1272664800.0</float>
<string>GMT+2</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>TioLive VM Order</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="6" aka="AAAAAAAAAAY=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<base_category_list> <base_category_list>
<portal_type id="Hosting Subscription">
<item>predecessor</item>
</portal_type>
<portal_type id="Hosting Subscription Module"> <portal_type id="Hosting Subscription Module">
<item>business_application</item> <item>business_application</item>
</portal_type> </portal_type>
......
<property_sheet_list> <property_sheet_list>
<portal_type id="Hosting Subscription"> <portal_type id="Hosting Subscription">
<item>HostingSubscription</item>
<item>SoftwareInstance</item>
<item>TextDocument</item>
<item>VariationRange</item> <item>VariationRange</item>
</portal_type> </portal_type>
</property_sheet_list> </property_sheet_list>
\ No newline at end of file
...@@ -2,61 +2,10 @@ ...@@ -2,61 +2,10 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Purchase Packing List" module="erp5.portal_type"/> <global name="Property Sheet" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item> <item>
<key> <string>_count</string> </key> <key> <string>_count</string> </key>
<value> <value>
...@@ -75,16 +24,6 @@ ...@@ -75,16 +24,6 @@
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>PPL-793</string> </value>
</item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <value>
...@@ -93,19 +32,11 @@ ...@@ -93,19 +32,11 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test_purchase_packing_list</string> </value> <value> <string>HostingSubscription</string> </value>
</item>
<item>
<key> <string>last_id</string> </key>
<value> <string>1</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Purchase Packing List</string> </value> <value> <string>Property Sheet</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>test_purchase_packing_list</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?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/boolean</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>root_slave_property</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>
<none/>
</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>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>root_software_release_url_property</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</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>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>root_state_property</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -95,6 +95,10 @@ ...@@ -95,6 +95,10 @@
<list> <list>
<string>my_title</string> <string>my_title</string>
<string>my_reference</string> <string>my_reference</string>
<string>my_predecessor_title_list</string>
<string>my_source_reference</string>
<string>my_text_content</string>
<string>my_sla_xml</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>editable</string>
<string>portal_type</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_predecessor_title_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>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_multi_relation_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Software Instance</string>
<string>Slave Instance</string>
</tuple>
</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>Predecessors</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>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_sla_xml</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>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_area_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>Root SLA XML</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_source_reference</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_read_only_reference</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>Root Software Type</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>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_text_content</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>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_area_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>Root XML</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -21,15 +21,15 @@ ...@@ -21,15 +21,15 @@
<item> <item>
<key> <string>activate_script_name</string> </key> <key> <string>activate_script_name</string> </key>
<value> <value>
<list> <tuple/>
<string>Delivery_assertCustomTradeConditionAndOpenOrder</string>
</list>
</value> </value>
</item> </item>
<item> <item>
<key> <string>after_script_name</string> </key> <key> <string>after_script_name</string> </key>
<value> <value>
<tuple/> <list>
<string>Delivery_assertCustomTradeConditionAndOpenOrder</string>
</list>
</value> </value>
</item> </item>
<item> <item>
...@@ -80,6 +80,10 @@ ...@@ -80,6 +80,10 @@
<tuple/> <tuple/>
</value> </value>
</item> </item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
order = state_change[\'object\']\n order = state_change[\'object\']\n
portal = order.getPortalObject()\n portal = order.getPortalObject()\n
\n \n
vifib_trade_condition = \'sale_trade_condition_module/vifib_trade_condition\'\n
### STEP 1: does this order have a client-specific Trade Condition\n ### STEP 1: does this order have a client-specific Trade Condition\n
trade_condition = order.getSpecialiseValue(portal_type="Sale Trade Condition")\n trade_condition = order.getSpecialiseValue(portal_type="Sale Trade Condition")\n
custom_trade_condition = None\n custom_trade_condition = None\n
...@@ -65,21 +66,25 @@ if trade_condition is not None:\n ...@@ -65,21 +66,25 @@ if trade_condition is not None:\n
if custom_trade_condition is None:\n if custom_trade_condition is None:\n
# If no trade condition or generic trade condition\n # If no trade condition or generic trade condition\n
# try to find existing trade condition\n # try to find existing trade condition\n
trade_condition_list = portal.sale_trade_condition_module.searchFolder(destination_section_uid=order.getDestinationSectionUid(),\n trade_condition_list = portal.portal_catalog(\n
validation_state="validated")\n destination_section_relative_url=order.getDestinationSection(),\n
validation_state="validated",\n
specialise_relative_url=vifib_trade_condition,\n
portal_type=\'Sale Trade Condition\')\n
if len(trade_condition_list):\n if len(trade_condition_list):\n
custom_trade_condition = trade_condition_list[0].getObject()\n custom_trade_condition = trade_condition_list[0].getObject()\n
\n \n
if custom_trade_condition is None:\n if custom_trade_condition is None:\n
# nothing found then create a new custom trade condition\n # nothing found then create a new custom trade condition\n
if trade_condition is None:\n custom_trade_condition = portal.sale_trade_condition_module.newContent(specialise=vifib_trade_condition,\n
trade_condition = \'sale_trade_condition_module/vifib_trade_condition\'\n destination_section=order.getDestinationSection(),\n
custom_trade_condition = portal.sale_trade_condition_module.newContent(specialise_value=trade_condition,\n title="ViFiB Custom Conditions",\n
destination_section_uid=order.getDestinationSectionUid(),\n portal_type=\'Sale Trade Condition\')\n
title="ViFiB Custom Conditions")\n
\n \n
if order.getSpecialise() != custom_trade_condition.getRelativeUrl():\n if custom_trade_condition is None:\n
order.setSpecialiseValue(custom_trade_condition, portal_type="Sale Trade Condition")\n raise ValueError(\'It was impossible to generate custom trade condition.\')\n
if order.getSpecialise(portal_type="Sale Trade Condition") != custom_trade_condition.getRelativeUrl():\n
order.setSpecialiseValue(custom_trade_condition)\n
\n \n
if portal.portal_workflow.isTransitionPossible(custom_trade_condition, \'validate\'):\n if portal.portal_workflow.isTransitionPossible(custom_trade_condition, \'validate\'):\n
custom_trade_condition.validate()\n custom_trade_condition.validate()\n
......
141 149
\ No newline at end of file \ No newline at end of file
computer_module/test_computer
computer_module/test_computer/**
open_sale_order_module/1
open_sale_order_module/1/**
organisation_module/vifib_client_A organisation_module/vifib_client_A
organisation_module/vifib_client_A/** organisation_module/vifib_client_A/**
organisation_module/vifib_internet organisation_module/vifib_internet
organisation_module/vifib_internet/1 organisation_module/vifib_internet/1
organisation_module/vifib_internet/bank_account organisation_module/vifib_internet/bank_account
purchase_packing_list_module/test_purchase_packing_list
purchase_packing_list_module/test_purchase_packing_list/**
purchase_trade_condition_module/vifib_purchase_trade_condition purchase_trade_condition_module/vifib_purchase_trade_condition
purchase_trade_condition_module/vifib_purchase_trade_condition/** purchase_trade_condition_module/vifib_purchase_trade_condition/**
sale_trade_condition_module/10
sale_trade_condition_module/10/**
sale_trade_condition_module/vifib_trade_condition sale_trade_condition_module/vifib_trade_condition
sale_trade_condition_module/vifib_trade_condition/** sale_trade_condition_module/vifib_trade_condition/**
software_product_module/test_software_product software_product_module/test_software_product
......
Hosting Subscription Module | business_application Hosting Subscription Module | business_application
\ No newline at end of file Hosting Subscription | predecessor
\ No newline at end of file
Hosting Subscription | HostingSubscription
Hosting Subscription | SoftwareInstance
Hosting Subscription | TextDocument
Hosting Subscription | VariationRange Hosting Subscription | VariationRange
\ No newline at end of file
HostingSubscription
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_lockSoftwareInstance</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_lock_software_instance</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>946684800.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Locks unlocked Software/Slave instances owned by locked person</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_managePersonLock</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_manage_person_lock</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>946684800.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Manages person locks</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_unlockSoftwareInstance</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_unlock_software_instance</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>946684800.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Unlocks locked Software/Slave instances owned by unlocked person</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_updateOpenSaleOrderLine</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>vifib_update_open_sale_order_line</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>946684800.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Open Sale Order Line update</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/float</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Maximum accepted balance.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>preferred_maximum_balance_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>preference</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: 0.0</string> </value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value> <string>Manage properties</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/int</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Maximum accepted days of having any balance.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>preferred_maximum_due_day_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>preference</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: 0</string> </value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value> <string>Manage properties</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>portal_catalog = context.getPortalObject().portal_catalog\n
\n
portal_catalog.searchAndActivate(\n
method_id=\'SoftwareInstance_lockForLockedPerson\',\n
portal_type=(\'Software Instance\', \'Slave Instance\'),\n
payment_state=\'!= locked\',\n
activate_kw={\'tag\': tag}\n
)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_lockSoftwareInstance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>portal_catalog = context.getPortalObject().portal_catalog\n
from DateTime import DateTime\n
method_kw = {}\n
method_kw.update(\n
maximum_balance=context.portal_preferences.getPreferredMaximumBalance(),\n
maximum_due_date=(DateTime() - context.portal_preferences.getPreferredMaximumDueDay()).Date(),\n
simulation_state=context.getPortalCurrentInventoryStateList() + context.getPortalTransitInventoryStateList(),\n
ongoing_simulation_state=context.getPortalFutureInventoryStateList() + context.getPortalReservedInventoryStateList(),\n
section_uid=context.restrictedTraverse(\'organisation_module/vifib_internet\').getUid(), \n
)\n
portal_catalog.searchAndActivate(\n
method_id=\'Person_manageLockByBalance\',\n
portal_type=\'Person\',\n
activate_kw={\'tag\': tag},\n
method_kw=method_kw\n
)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_managePersonLock</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>portal_catalog = context.getPortalObject().portal_catalog\n
\n
portal_catalog.searchAndActivate(\n
method_id=\'SoftwareInstance_unlockForUnlockedPerson\',\n
portal_type=(\'Software Instance\', \'Slave Instance\'),\n
payment_state=\'locked\',\n
activate_kw={\'tag\': tag}\n
)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_unlockSoftwareInstance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>stop_date = None\n
if params is not None:\n
stop_date = params.get(\'stop_date\')\n
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate, addToDate\n
\n
if stop_date is None:\n
# generate expected next month\n
stop_date = addToDate(getClosestDate(target_date=DateTime(), precision=\'month\', before=1), month=2)\n
\n
context.portal_catalog.searchAndActivate(\n
method_id=\'OpenSaleOrderLine_updateStopDate\',\n
activate_kw={\'tag\':tag},\n
method_kw={\'stop_date\': stop_date},\n
portal_type=\'Open Sale Order Line\')\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_updateOpenSaleOrderLine</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate, addToDate\n
\n
portal = context.getPortalObject()\n
cleanup_resource = portal.portal_preferences.getPreferredInstanceCleanupResource()\n
\n
# copy and paste from\n
# portal_workflow/person_slap_interface_workflow/scripts/Person_requestSoftwareInstance\n
if (portal.portal_activities.countMessageWithTag(tag) > 0):\n
# The software instance is already under creation but can not be fetched from catalog\n
# As it is not possible to fetch informations, it is better to raise an error\n
raise NotImplementedError(tag)\n
hosting_subscription = context\n
\n
sale_order_portal_type = "Sale Order"\n
sale_order_line_portal_type = "Sale Order Line"\n
hosting_subscription_portal_type = "Hosting Subscription"\n
if hosting_subscription.isRootSlave():\n
software_instance_portal_type = "Slave Instance"\n
else:\n
software_instance_portal_type = "Software Instance"\n
\n
# Mostly copy and paste from\n
# portal_workflow/person_slap_interface_workflow/scripts/Person_requestSoftwareInstance\n
request_software_instance = hosting_subscription.portal_catalog.getResultValue(\n
portal_type=software_instance_portal_type,\n
title=hosting_subscription.getTitle(),\n
root_uid=hosting_subscription.getUid(),\n
)\n
\n
if person is None:\n
open_sale_order_line = hosting_subscription.portal_catalog.getResultValue(\n
portal_type=\'Open Sale Order Line\', strict_aggregate_uid=hosting_subscription.getUid())\n
open_sale_order = open_sale_order_line.getParentValue()\n
person_relative_url = open_sale_order.getDestinationSection()\n
else:\n
person_relative_url = person.getRelativeUrl()\n
\n
new_one = False\n
if (request_software_instance is None):\n
new_one = True\n
setup_service_relative_url = portal.portal_preferences.getPreferredInstanceSetupResource()\n
request_software_instance = portal.getDefaultModule(portal_type=software_instance_portal_type).newContent(\n
portal_type=software_instance_portal_type,\n
source_reference=hosting_subscription.getSourceReference(),\n
title=hosting_subscription.getTitle(),\n
text_content=hosting_subscription.getTextContent(),\n
sla_xml=hosting_subscription.getSlaXml(),\n
activate_kw={\'tag\': tag},\n
**portal.Base_getNewSoftwareInstanceCoordinate()\n
)\n
request_software_instance.portal_workflow.doActionFor(request_software_instance,\n
\'validate_action\')\n
\n
software_release_document = context.portal_catalog.getResultValue(\n
portal_type=\'Software Release\',\n
url_string=hosting_subscription.getRootSoftwareReleaseUrl())\n
\n
sale_order = portal.getDefaultModule(portal_type=sale_order_portal_type).newContent(\n
portal_type=sale_order_portal_type,\n
destination=person_relative_url,\n
destination_section=person_relative_url,\n
destination_decision=person_relative_url,\n
start_date=DateTime(),\n
received_date=DateTime(),\n
# XXX Hardcoded values\n
source="organisation_module/vifib_internet",\n
source_section="organisation_module/vifib_internet",\n
quantity_unit="unit/piece",\n
price_currency="currency_module/EUR",\n
activate_kw={\'tag\': tag},\n
)\n
sale_order_line = sale_order.newContent(\n
portal_type=sale_order_line_portal_type,\n
resource=setup_service_relative_url,\n
quantity=1,\n
price=0,\n
aggregate_value_list=[request_software_instance,\n
hosting_subscription,\n
software_release_document\n
],\n
activate_kw={\'tag\': tag},\n
)\n
#portal.portal_workflow.doActionFor(sale_order, "order_action")\n
# XXX: Do not verify security\n
sale_order.order()\n
\n
if person is not None:\n
# Update Open Order\n
# does this order have a client-specific Open Order\n
open_order = portal.portal_catalog.getResultValue(\n
default_destination_section_uid=person.getUid(),\n
portal_type="Open Sale Order",\n
validation_state="validated")\n
if open_order is None:\n
person_slap_interface_state = person.getSlapState()\n
if person_slap_interface_state == \'open_order_created\':\n
open_order_url = context.portal_workflow.getInfoFor(\n
ob=person, name=\'open_order_url\',\n
wf_id=\'person_slap_interface_workflow\')\n
open_order = portal.restrictedTraverse(open_order_url)\n
else:\n
raise ValueError(\'Person has no open order created\')\n
\n
now = DateTime()\n
start_date = getClosestDate(target_date=now, precision=\'day\', before=1)\n
# 12 months of subscription by default\n
stop_date = addToDate(getClosestDate(target_date=now, precision=\'month\', before=1), month=2)\n
\n
subscription_service_relative_url = portal.portal_preferences.getPreferredInstanceSubscriptionResource()\n
open_order.newContent(\n
portal_type="Open Sale Order Line",\n
title=hosting_subscription.getTitle(),\n
aggregate_value=hosting_subscription,\n
start_date=start_date,\n
stop_date=stop_date,\n
quantity=1,\n
quantity_unit="unit/piece",\n
price=1,\n
price_currency="currency_module/EUR",\n
specialise=sale_order.getSpecialise(portal_type="Sale Trade Condition"),\n
# XXX Hardcoded values\\n\n
resource=subscription_service_relative_url,\n
destination=person_relative_url,\n
destination_section=person_relative_url,\n
source="organisation_module/vifib_internet",\n
source_section="organisation_module/vifib_internet",\n
activate_kw={\'tag\': tag},\n
)\n
\n
hosting_subscription_predecessor_list = hosting_subscription.getPredecessorList()\n
hosting_subscription_predecessor_list.append(request_software_instance.getRelativeUrl())\n
hosting_subscription.edit(predecessor_list=hosting_subscription_predecessor_list)\n
\n
# Find Computer partition\n
# XXX Link subscript to open order\n
else:\n
# Update existing software instance\n
request_software_instance.edit(\n
text_content=hosting_subscription.getTextContent(),\n
source_reference=hosting_subscription.getSourceReference(),\n
sla_xml=hosting_subscription.getSlaXml(),\n
activate_kw={\'tag\': tag},\n
)\n
for predecessor_related in request_software_instance.getPredecessorRelatedValueList():\n
predecessor_list = predecessor_related.getPredecessorList()\n
predecessor_list.remove(request_software_instance.getRelativeUrl())\n
predecessor_related.setPredecessorList(predecessor_list)\n
\n
hosting_subscription_predecessor_list = hosting_subscription.getPredecessorList()\n
hosting_subscription_predecessor_list.append(request_software_instance.getRelativeUrl())\n
hosting_subscription.setPredecessorList(hosting_subscription_predecessor_list)\n
\n
if hosting_subscription.getRootState() == \'started\':\n
request_software_instance.startRequested()\n
if not new_one:\n
request_software_instance.activate(after_tag=tag).requestStartComputerPartition()\n
elif hosting_subscription.getRootState() == \'stopped\':\n
request_software_instance.stopRequested()\n
if not new_one:\n
request_software_instance.activate(after_tag=tag).requestStopComputerPartition()\n
\n
return request_software_instance\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, person=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_requestRootSoftwareInstance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
if context.getStopDate() < stop_date:\n
context.setStopDate(stop_date)\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>stop_date</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OpenSaleOrderLine_updateStopDate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
locked = context.getSlapState() == \'locked\'\n
customer_uid = context.getUid()\n
balance = context.portal_simulation.getInventoryAssetPrice(\n
node_category=\'account_type/asset/receivable\',\n
simulation_state=simulation_state,\n
section_uid=section_uid,\n
mirror_section_uid=customer_uid)\n
\n
if maximum_balance > balance:\n
# customer reached his balance, shall be locked\n
if not locked:\n
context.lock()\n
return\n
\n
# check ongoing payments and check that date if is acceptable, if not lock\n
if context.portal_catalog.countResults(\n
portal_type=\'Payment Transaction\',\n
simulation_state=ongoing_simulation_state,\n
**{\n
\'delivery.destination_section_uid\': customer_uid,\n
\'delivery.start_date\': \'<= %s\' % maximum_due_date\n
})[0][0] > 0:\n
# there are ongoing old payments, shall be locked\n
if not locked:\n
context.lock()\n
else:\n
# there are no ongoing payments and balance is acceptable\n
if locked:\n
context.unlock()\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>maximum_balance, maximum_due_date, simulation_state, section_uid, ongoing_simulation_state</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_manageLockByBalance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>software_instance = context\n
if software_instance.getSlapState() == \'locked\':\n
return\n
if software_instance.SoftwareInstance_getStatus() == \'destroyed\':\n
return\n
\n
try:\n
packing_list_line = software_instance.Item_getInstancePackingListLine()\n
except ValueError:\n
return\n
person = packing_list_line.getDestinationValue()\n
\n
if person.getSlapState() == \'locked\':\n
software_instance.lock()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_lockForLockedPerson</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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>software_instance = context\n
if software_instance.getSlapState() != \'locked\':\n
return\n
if software_instance.SoftwareInstance_getStatus() == \'destroyed\':\n
return\n
\n
try:\n
packing_list_line = software_instance.Item_getInstancePackingListLine()\n
except ValueError:\n
return\n
person = packing_list_line.getDestinationValue()\n
\n
if person.getSlapState() != \'locked\':\n
software_instance.unlock()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_unlockForUnlockedPerson</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -100,6 +100,8 @@ ...@@ -100,6 +100,8 @@
<string>my_preferred_instance_update_resource</string> <string>my_preferred_instance_update_resource</string>
<string>my_preferred_instance_subscription_resource</string> <string>my_preferred_instance_subscription_resource</string>
<string>my_preferred_payzen_integration_site</string> <string>my_preferred_payzen_integration_site</string>
<string>my_preferred_maximum_balance</string>
<string>my_preferred_maximum_due_day</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_preferred_maximum_balance</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_float_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>Preferred Maximum Balance</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_preferred_maximum_due_day</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_integer_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>Preferred Maximum Due Day</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
</item> </item>
<item> <item>
<key> <string>initial_state</string> </key> <key> <string>initial_state</string> </key>
<value> <string>draft</string> </value> <value> <string>locked</string> </value>
</item> </item>
<item> <item>
<key> <string>manager_bypass</string> </key> <key> <string>manager_bypass</string> </key>
......
...@@ -52,8 +52,6 @@ ...@@ -52,8 +52,6 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
from Products.ERP5Type.DateUtils import getClosestDate, addToDate\n
person = state_change[\'object\']\n person = state_change[\'object\']\n
portal = person.getPortalObject()\n portal = person.getPortalObject()\n
# Get required arguments\n # Get required arguments\n
...@@ -66,8 +64,6 @@ sla_xml = kwargs.get("sla_xml") or ""\n ...@@ -66,8 +64,6 @@ sla_xml = kwargs.get("sla_xml") or ""\n
is_slave = kwargs.get("shared", False)\n is_slave = kwargs.get("shared", False)\n
state = kwargs.get(\'state\') or \'started\'\n state = kwargs.get(\'state\') or \'started\'\n
\n \n
sale_order_portal_type = "Sale Order"\n
sale_order_line_portal_type = "Sale Order Line"\n
hosting_subscription_portal_type = "Hosting Subscription"\n hosting_subscription_portal_type = "Hosting Subscription"\n
\n \n
if is_slave == True:\n if is_slave == True:\n
...@@ -80,142 +76,60 @@ tag = "%s_%s_inProgress" % (person.getUid(), \n ...@@ -80,142 +76,60 @@ tag = "%s_%s_inProgress" % (person.getUid(), \n
\n \n
# Check if it already exists\n # Check if it already exists\n
cleanup_resource = portal.portal_preferences.getPreferredInstanceCleanupResource()\n cleanup_resource = portal.portal_preferences.getPreferredInstanceCleanupResource()\n
request_software_instance = None\n request_hosting_subscription = None\n
for si in portal.portal_catalog(\n for hs in portal.portal_catalog(\n
portal_type=software_instance_portal_type,\n portal_type=hosting_subscription_portal_type,\n
title=software_title,\n title=software_title,\n
):\n ):\n
si = hs.portal_catalog.getResultValue(title=software_title,\n
root_uid=hs.getUid())\n
try:\n try:\n
cleanup_delivery_line = si.Item_getInstancePackingListLine(cleanup_resource)\n cleanup_delivery_line = si.Item_getInstancePackingListLine(cleanup_resource)\n
except ValueError:\n except ValueError:\n
request_software_instance = si\n request_hosting_subscription = hs\n
break\n break\n
else:\n else:\n
if cleanup_delivery_line.getSimulationState() != \'delivered\':\n if cleanup_delivery_line.getSimulationState() != \'delivered\':\n
request_software_instance = si\n request_hosting_subscription = hs\n
break\n break\n
\n \n
if (request_software_instance is None):\n if (portal.portal_activities.countMessageWithTag(tag) > 0):\n
# The software instance is already under creation but can not be fetched from catalog\n
# As it is not possible to fetch informations, it is better to raise an error\n
raise NotImplementedError(tag)\n
\n
if (request_hosting_subscription is None):\n
hosting_subscription_reference = "HOSTSUBS-%s" % context.getPortalObject().portal_ids\\\n hosting_subscription_reference = "HOSTSUBS-%s" % context.getPortalObject().portal_ids\\\n
.generateNewId(id_group=\'slap_hosting_subscription_reference\', id_generator=\'uid\')\n .generateNewId(id_group=\'slap_hosting_subscription_reference\', id_generator=\'uid\')\n
if (portal.portal_activities.countMessageWithTag(tag) > 0):\n request_hosting_subscription = portal.getDefaultModule(portal_type=hosting_subscription_portal_type).newContent(\n
# The software instance is already under creation but can not be fetched from catalog\n portal_type=hosting_subscription_portal_type,\n
# As it is not possible to fetch informations, it is better to raise an error\n reference=hosting_subscription_reference,\n
raise NotImplementedError(tag)\n title=software_title,\n
else:\n source_reference=software_type,\n
\n text_content=instance_xml,\n
setup_service_relative_url = portal.portal_preferences.getPreferredInstanceSetupResource()\n sla_xml=sla_xml,\n
software_instance = portal.getDefaultModule(portal_type=software_instance_portal_type).newContent(\n root_software_release_url=software_release_url_string,\n
portal_type=software_instance_portal_type,\n root_slave=is_slave,\n
source_reference=software_type,\n root_state=state,\n
title=software_title,\n periodicity_hour_list=[0],\n
text_content=instance_xml,\n periodicity_minute_list=[0],\n
sla_xml=sla_xml,\n periodicity_month_day=[1],\n
activate_kw={\'tag\': tag},\n activate_kw={\'tag\': tag},\n
**portal.Base_getNewSoftwareInstanceCoordinate()\n )\n
)\n request_hosting_subscription.portal_workflow.doActionFor(request_hosting_subscription,\n
software_instance.portal_workflow.doActionFor(software_instance, \'validate_action\')\n \'validate_action\')\n
subscription = portal.getDefaultModule(portal_type=hosting_subscription_portal_type).newContent(\n
portal_type=hosting_subscription_portal_type,\n
reference=hosting_subscription_reference,\n
title=software_title,\n
periodicity_hour_list=[0],\n
periodicity_minute_list=[0],\n
periodicity_month_day=[1],\n
activate_kw={\'tag\': tag},\n
)\n
subscription.portal_workflow.doActionFor(subscription, \'validate_action\')\n
if state == \'started\':\n
software_instance.startRequested()\n
elif state == \'stopped\':\n
software_instance.stopRequested()\n
\n
software_release_document = context.portal_catalog.getResultValue(\n
portal_type=\'Software Release\',\n
url_string=software_release_url_string)\n
\n
sale_order = portal.getDefaultModule(portal_type=sale_order_portal_type).newContent(\n
portal_type=sale_order_portal_type,\n
destination_value=person,\n
destination_section_value=person,\n
destination_decision_value=person,\n
start_date=DateTime(),\n
received_date=DateTime(),\n
# XXX Hardcoded values\n
source="organisation_module/vifib_internet",\n
source_section="organisation_module/vifib_internet",\n
quantity_unit="unit/piece",\n
price_currency="currency_module/EUR",\n
activate_kw={\'tag\': tag},\n
)\n
sale_order_line = sale_order.newContent(\n
portal_type=sale_order_line_portal_type,\n
resource=setup_service_relative_url,\n
quantity=1,\n
price=0,\n
aggregate_value_list=[software_instance, subscription, software_release_document],\n
activate_kw={\'tag\': tag},\n
)\n
portal.portal_workflow.doActionFor(sale_order, "order_action")\n
\n
# Update Open Order\n
# does this order have a client-specific Open Order\n
open_order = portal.portal_catalog.getResultValue(\n
default_destination_section_uid=person.getUid(),\n
portal_type="Open Sale Order",\n
validation_state="validated")\n
if open_order is None:\n
person_slap_interface_state = person.getSlapState()\n
if person_slap_interface_state == \'open_order_created\':\n
open_order_url = context.portal_workflow.getInfoFor(\n
ob=person, name=\'open_order_url\',\n
wf_id=\'person_slap_interface_workflow\')\n
open_order = portal.restrictedTraverse(open_order_url)\n
else:\n
raise ValueError(\'Person has no open order created\')\n
\n
now = DateTime()\n
start_date = getClosestDate(target_date=now, precision=\'day\', before=1)\n
# 12 months of subscription by default\n
stop_date = addToDate(getClosestDate(target_date=now, precision=\'month\', before=1), year=1)\n
\n
subscription_service_relative_url = portal.portal_preferences.getPreferredInstanceSubscriptionResource()\n
open_order.newContent(\n
portal_type="Open Sale Order Line",\n
title=software_title,\n
aggregate_value=subscription,\n
start_date=start_date,\n
stop_date=stop_date,\n
quantity=1,\n
quantity_unit="unit/piece",\n
price=1,\n
price_currency="currency_module/EUR",\n
specialise=sale_order.getSpecialise(portal_type="Sale Trade Condition"),\n
# XXX Hardcoded values\\n\n
resource=subscription_service_relative_url,\n
destination_value=person,\n
destination_section_value=person,\n
source="organisation_module/vifib_internet",\n
source_section="organisation_module/vifib_internet",\n
activate_kw={\'tag\': tag},\n
)\n
\n
# Find Computer partition\n
# XXX Link subscript to open order\n
else:\n else:\n
# Update existing software instance\n request_hosting_subscription.edit(\n
request_software_instance.edit(\n
text_content=instance_xml,\n text_content=instance_xml,\n
source_reference=software_type,\n source_reference=software_type,\n
sla_xml=sla_xml,\n sla_xml=sla_xml,\n
root_software_release_url=software_release_url_string,\n
root_slave=is_slave,\n
root_state=state,\n
activate_kw={\'tag\': tag},\n activate_kw={\'tag\': tag},\n
)\n )\n
if state == \'started\':\n \n
request_software_instance.startRequested()\n request_hosting_subscription.HostingSubscription_requestRootSoftwareInstance(tag, person=person)\n
request_software_instance.activate(after_tag=tag).requestStartComputerPartition()\n
elif state == \'stopped\':\n
request_software_instance.stopRequested()\n
request_software_instance.activate(after_tag=tag).requestStopComputerPartition()\n
]]></string> </value> ]]></string> </value>
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
<value> <value>
<tuple> <tuple>
<string>create_open_order</string> <string>create_open_order</string>
<string>lock</string>
<string>request_software_instance</string> <string>request_software_instance</string>
</tuple> </tuple>
</value> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StateDefinition" module="Products.DCWorkflow.States"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>locked</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>transitions</string> </key>
<value>
<tuple>
<string>unlock</string>
</tuple>
</value>
</item>
<item>
<key> <string>type_list</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
<key> <string>transitions</string> </key> <key> <string>transitions</string> </key>
<value> <value>
<tuple> <tuple>
<string>lock</string>
<string>request_software_instance</string> <string>request_software_instance</string>
</tuple> </tuple>
</value> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>lock</string> </value>
</item>
<item>
<key> <string>new_state_id</string> </key>
<value> <string>locked</string> </value>
</item>
<item>
<key> <string>script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>unlock</string> </value>
</item>
<item>
<key> <string>new_state_id</string> </key>
<value> <string>draft</string> </value>
</item>
<item>
<key> <string>script_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
506 524
\ No newline at end of file \ No newline at end of file
portal_alarms/confirm_ordered_sale_order portal_alarms/confirm_ordered_sale_order
portal_alarms/stop_planned_sale_invoice_transaction portal_alarms/stop_planned_sale_invoice_transaction
portal_alarms/vifib_check_consistency portal_alarms/vifib_check_consistency
portal_alarms/vifib_trigger_build portal_alarms/vifib_lock_software_instance
\ No newline at end of file portal_alarms/vifib_manage_person_lock
portal_alarms/vifib_trigger_build
portal_alarms/vifib_unlock_software_instance
portal_alarms/vifib_update_open_sale_order_line
\ No newline at end of file
...@@ -245,6 +245,17 @@ class SlapTool(BaseTool): ...@@ -245,6 +245,17 @@ class SlapTool(BaseTool):
return self._softwareInstanceError(computer_id, computer_partition_id, return self._softwareInstanceError(computer_id, computer_partition_id,
error_log) error_log)
security.declareProtected(Permissions.AccessContentsInformation,
'softwareInstanceRename')
def softwareInstanceRename(self, new_name, computer_id,
computer_partition_id, slave_reference=None):
"""
Change the title of a Software Instance using Workflow.
"""
return self._softwareInstanceRename(new_name, computer_id,
computer_partition_id,
slave_reference)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'softwareInstanceBang') 'softwareInstanceBang')
def softwareInstanceBang(self, computer_id, def softwareInstanceBang(self, computer_id,
...@@ -632,6 +643,15 @@ class SlapTool(BaseTool): ...@@ -632,6 +643,15 @@ class SlapTool(BaseTool):
computer_partition_id).reportComputerPartitionError( computer_partition_id).reportComputerPartitionError(
comment=error_log) comment=error_log)
@convertToREST
def _softwareInstanceRename(self, new_name, computer_id,
computer_partition_id, slave_reference):
software_instance = self._getSoftwareInstanceForComputerPartition(
computer_id, computer_partition_id,
slave_reference)
return software_instance.rename(new_name=new_name,
comment="Rename %s into %s" % (software_instance.title, new_name))
@convertToREST @convertToREST
def _softwareInstanceBang(self, computer_id, def _softwareInstanceBang(self, computer_id,
computer_partition_id, message): computer_partition_id, message):
......
...@@ -91,6 +91,8 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -91,6 +91,8 @@ class testVifibMixin(ERP5TypeTestCase):
'erp5_system_event', 'erp5_system_event',
'erp5_secure_payment', 'erp5_secure_payment',
'erp5_payzen_secure_payment', 'erp5_payzen_secure_payment',
'erp5_ui_test_core',
'erp5_ui_test',
'vifib_mysql_innodb_catalog', 'vifib_mysql_innodb_catalog',
'vifib_core', 'vifib_core',
'vifib_base', 'vifib_base',
...@@ -159,6 +161,14 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -159,6 +161,14 @@ class testVifibMixin(ERP5TypeTestCase):
Create ERP5 user. Create ERP5 user.
This has to be called only once. This has to be called only once.
""" """
# setup new active process for this test, in order have
# consistency report local for one test
sm = getSecurityManager()
self.login()
try:
self.portal.portal_alarms.vifib_check_consistency.newActiveProcess()
finally:
setSecurityManager(sm)
self.setupPortalCertificateAuthority() self.setupPortalCertificateAuthority()
import random import random
self.portal.portal_caches.erp5_site_global_id = '%s' % random.random() self.portal.portal_caches.erp5_site_global_id = '%s' % random.random()
...@@ -201,6 +211,8 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -201,6 +211,8 @@ class testVifibMixin(ERP5TypeTestCase):
person = person.getObject() person = person.getObject()
if isTransitionPossible(person, 'validate'): if isTransitionPossible(person, 'validate'):
person.validate() person.validate()
if isTransitionPossible(person, 'unlock'):
person.unlock()
for assignment in person.contentValues(portal_type='Assignment'): for assignment in person.contentValues(portal_type='Assignment'):
if isTransitionPossible(assignment, 'open'): if isTransitionPossible(assignment, 'open'):
assignment.open() assignment.open()
...@@ -340,6 +352,18 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -340,6 +352,18 @@ class testVifibMixin(ERP5TypeTestCase):
finally: finally:
setSecurityManager(sm) setSecurityManager(sm)
def checkDivergency(self):
# there shall be no divergency
current_skin = self.app.REQUEST.get('portal_skin', 'View')
try:
# Note: Worklists are cached, so in order to have next correct result
# clear cache
self.clearCache()
self.changeSkin('RSS')
self.assertFalse('to Solve' in self.portal.ERP5Site_viewWorklist())
finally:
self.changeSkin(current_skin)
def stepCheckSiteConsistency(self, **kw): def stepCheckSiteConsistency(self, **kw):
self.portal.portal_alarms.vifib_check_consistency.activeSense() self.portal.portal_alarms.vifib_check_consistency.activeSense()
transaction.commit() transaction.commit()
...@@ -347,6 +371,7 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -347,6 +371,7 @@ class testVifibMixin(ERP5TypeTestCase):
self.assertEqual([], self.portal.portal_alarms.vifib_check_consistency\ self.assertEqual([], self.portal.portal_alarms.vifib_check_consistency\
.Alarm_getConsistencyCheckReportLineList()) .Alarm_getConsistencyCheckReportLineList())
self.assertFalse(self.portal.portal_alarms.vifib_check_consistency.sense()) self.assertFalse(self.portal.portal_alarms.vifib_check_consistency.sense())
self.checkDivergency()
def stepTic(self, **kw): def stepTic(self, **kw):
def build(): def build():
...@@ -374,13 +399,4 @@ class testVifibMixin(ERP5TypeTestCase): ...@@ -374,13 +399,4 @@ class testVifibMixin(ERP5TypeTestCase):
# tic after build # tic after build
super(testVifibMixin, self).stepTic(**kw) super(testVifibMixin, self).stepTic(**kw)
# there shall be no divergency self.checkDivergency()
current_skin = self.app.REQUEST.get('portal_skin', 'View')
try:
# Note: Worklists are cached, so in order to have next correct result
# clear cache
self.clearCache()
self.changeSkin('RSS')
self.assertFalse('to Solve' in self.portal.ERP5Site_viewWorklist())
finally:
self.changeSkin(current_skin)
...@@ -48,7 +48,6 @@ class testVifibSecurityMixin(SecurityTestCase, testVifibMixin): ...@@ -48,7 +48,6 @@ class testVifibSecurityMixin(SecurityTestCase, testVifibMixin):
Mixin class for security unit test of Vifib. Mixin class for security unit test of Vifib.
""" """
run_all_test = 1 run_all_test = 1
login = PortalTestCase.login
def createManagerAndLogin(self): def createManagerAndLogin(self):
""" """
......
...@@ -17,8 +17,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -17,8 +17,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
causality_relative_url=hosting_subscription.getRelativeUrl(), causality_relative_url=hosting_subscription.getRelativeUrl(),
sort_on=(('delivery.start_date', 'desc'),) sort_on=(('delivery.start_date', 'desc'),)
) )
# is whole year covered? # are next two months covered?
self.assertEqual(12, len(delivery_list)) self.assertEqual(2, len(delivery_list))
# generate the expected time frames # generate the expected time frames
now = DateTime() now = DateTime()
...@@ -123,7 +123,7 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -123,7 +123,7 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
self.assertEqual('planned', setup_invoice_line_list[0]\ self.assertEqual('planned', setup_invoice_line_list[0]\
.getSimulationState()) .getSimulationState())
# there are 12 confirmed subscription, so no invoice # there are 2 confirmed subscription, so no invoice
subscription_delivery_line_list = catalog( subscription_delivery_line_list = catalog(
portal_type='Sale Packing List Line', portal_type='Sale Packing List Line',
aggregate_relative_url=hosting_subscription_url, aggregate_relative_url=hosting_subscription_url,
...@@ -131,8 +131,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -131,8 +131,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
sort_on=(('movement.start_date', 'desc'),) sort_on=(('movement.start_date', 'desc'),)
) )
self.assertEqual(12, len(subscription_delivery_line_list)) self.assertEqual(2, len(subscription_delivery_line_list))
self.assertEqual(['confirmed'] * 12, [q.getSimulationState() for \ self.assertEqual(['confirmed'] * 2, [q.getSimulationState() for \
q in subscription_delivery_line_list]) q in subscription_delivery_line_list])
subscription_invoice_line_list = catalog(portal_type='Invoice Line', subscription_invoice_line_list = catalog(portal_type='Invoice Line',
...@@ -212,14 +212,14 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -212,14 +212,14 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
self.assertEqual('planned', setup_invoice_line_list[0]\ self.assertEqual('planned', setup_invoice_line_list[0]\
.getSimulationState()) .getSimulationState())
# there are 11 confirmed and 1 stopped subscription, so 1 invoice line # there are 1 confirmed and 1 stopped subscription, so 1 invoice line
subscription_delivery_line_list = catalog( subscription_delivery_line_list = catalog(
portal_type='Sale Packing List Line', portal_type='Sale Packing List Line',
aggregate_relative_url=hosting_subscription_url, aggregate_relative_url=hosting_subscription_url,
resource_relative_url=sequence['subscription_resource']) resource_relative_url=sequence['subscription_resource'])
self.assertEqual(12, len(subscription_delivery_line_list)) self.assertEqual(2, len(subscription_delivery_line_list))
self.assertEqual((['confirmed'] * 11) + ['stopped'], self.assertEqual(['confirmed'] + ['stopped'],
sorted([q.getSimulationState() for \ sorted([q.getSimulationState() for \
q in subscription_delivery_line_list])) q in subscription_delivery_line_list]))
...@@ -308,8 +308,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -308,8 +308,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
aggregate_relative_url=hosting_subscription_url, aggregate_relative_url=hosting_subscription_url,
resource_relative_url=sequence['subscription_resource']) resource_relative_url=sequence['subscription_resource'])
self.assertEqual(12, len(subscription_delivery_line_list)) self.assertEqual(2, len(subscription_delivery_line_list))
self.assertEqual((['confirmed'] * 10) + (['stopped'] * 2), self.assertEqual(['stopped'] * 2,
sorted([q.getSimulationState() for \ sorted([q.getSimulationState() for \
q in subscription_delivery_line_list])) q in subscription_delivery_line_list]))
...@@ -416,8 +416,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -416,8 +416,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
aggregate_relative_url=hosting_subscription_url, aggregate_relative_url=hosting_subscription_url,
resource_relative_url=sequence['subscription_resource']) resource_relative_url=sequence['subscription_resource'])
self.assertEqual(12, len(subscription_delivery_line_list)) self.assertEqual(2, len(subscription_delivery_line_list))
self.assertEqual((['confirmed'] * 10) + (['stopped'] * 2), self.assertEqual(['stopped'] * 2,
sorted([q.getSimulationState() for \ sorted([q.getSimulationState() for \
q in subscription_delivery_line_list])) q in subscription_delivery_line_list]))
...@@ -532,8 +532,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -532,8 +532,8 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
aggregate_relative_url=hosting_subscription_url, aggregate_relative_url=hosting_subscription_url,
resource_relative_url=sequence['subscription_resource']) resource_relative_url=sequence['subscription_resource'])
self.assertEqual(12, len(subscription_delivery_line_list)) self.assertEqual(2, len(subscription_delivery_line_list))
self.assertEqual((['confirmed'] * 10) + (['stopped'] * 2), self.assertEqual(['stopped'] * 2,
sorted([q.getSimulationState() for \ sorted([q.getSimulationState() for \
q in subscription_delivery_line_list])) q in subscription_delivery_line_list]))
...@@ -590,7 +590,12 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin): ...@@ -590,7 +590,12 @@ class TestVifibInstanceHostingRelatedDocument(TestVifibSlapWebServiceMixin):
invoice.setStartDate(getClosestDate(target_date=DateTime())-1) invoice.setStartDate(getClosestDate(target_date=DateTime())-1)
def stepTriggerStopInvoiceAlarm(self, sequence, **kw): def stepTriggerStopInvoiceAlarm(self, sequence, **kw):
self.portal.portal_alarms.stop_planned_sale_invoice_transaction.activeSense() sm = getSecurityManager()
self.login()
try:
self.portal.portal_alarms.stop_planned_sale_invoice_transaction.activeSense()
finally:
setSecurityManager(sm)
def test_OpenOrder_sale_packing_list(self): def test_OpenOrder_sale_packing_list(self):
""" """
......
...@@ -52,7 +52,7 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -52,7 +52,7 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
None, hosting_subscription.getPeriodicityWeekFrequency()) None, hosting_subscription.getPeriodicityWeekFrequency())
# check start date and stop date of the subscription item, # check start date and stop date of the subscription item,
# currently there are 12 months # currently there are 2 months
now = DateTime() now = DateTime()
start_date = \ start_date = \
getClosestDate(target_date=now, precision='day', before=1) getClosestDate(target_date=now, precision='day', before=1)
...@@ -69,7 +69,7 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -69,7 +69,7 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
self.assertEquals( self.assertEquals(
0.0, open_order_line.getStartDate().second()) 0.0, open_order_line.getStartDate().second())
stop_date = addToDate( stop_date = addToDate(
getClosestDate(target_date=now, precision='month', before=1), year=1) getClosestDate(target_date=now, precision='month', before=1), month=2)
self.assertEquals( self.assertEquals(
stop_date.year(), open_order_line.getStopDate().year()) stop_date.year(), open_order_line.getStopDate().year())
self.assertEquals( self.assertEquals(
...@@ -94,8 +94,8 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -94,8 +94,8 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
parent_uid=applied_rule.getUid(), parent_uid=applied_rule.getUid(),
sort_on=(('movement.start_date', 'desc'),) sort_on=(('movement.start_date', 'desc'),)
) )
# Check that simulation is created by the periodicity for one year # Check that simulation is created by the periodicity for two months
self.assertEquals(12, self.assertEquals(2,
len(simulation_movement_list)) len(simulation_movement_list))
# Check the list of expected simulation # Check the list of expected simulation
...@@ -143,261 +143,55 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -143,261 +143,55 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
self.assertEqual(expected_start_date, simulation_movement.getStartDate()) self.assertEqual(expected_start_date, simulation_movement.getStartDate())
self.assertEqual(expected_stop_date, simulation_movement.getStopDate()) self.assertEqual(expected_stop_date, simulation_movement.getStopDate())
# not delivered yet # delivered already
self.assertEqual(None, simulation_movement.getDelivery()) self.assertNotEqual(None, simulation_movement.getDelivery())
self.assertEqual('Sale Packing List Line',
simulation_movement.getDeliveryValue().getPortalType())
# packing list shall be buildable # packing list shall be buildable
self.assertTrue(simulation_movement.isBuildable()) self.assertFalse(simulation_movement.isBuildable())
# fetch invoice level simulation # no invoice movements on this level
applied_rule_invoice_list = \ applied_rule_invoice_list = \
simulation_movement.contentValues(portal_type="Applied Rule") simulation_movement.contentValues(portal_type="Applied Rule")
self.assertEquals(1, len(applied_rule_invoice_list)) # check next simulation movement
applied_rule_invoice = \ idx += 1
applied_rule_invoice_list[0].getObject()
self.assertNotEquals(None, applied_rule_invoice)
simulation_movement_invoice_list = \
applied_rule_invoice.contentValues(portal_type="Simulation Movement")
self.assertEquals(1, len(simulation_movement_invoice_list))
simulation_movement_invoice = \
simulation_movement_invoice_list[0].getObject()
self.assertNotEquals(None, simulation_movement_invoice)
# not delivered yet
self.assertEqual(None, simulation_movement_invoice.getDelivery())
# invoice shall be not yet buildable
self.assertFalse(False, simulation_movement_invoice.isBuildable())
# check property of invoice simulation
self.assertEquals(1.0,
simulation_movement_invoice.getQuantity())
self.assertEquals("unit/piece",
simulation_movement_invoice.getQuantityUnit())
self.assertEquals(1.0,
simulation_movement_invoice.getPrice())
self.assertEquals("currency_module/EUR",
simulation_movement_invoice.getPriceCurrency())
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_invoice.getSource())
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_invoice.getSourceSection())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_invoice.getDestination())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_invoice.getDestinationSection())
self.assertEquals(open_order_line.getSpecialise(),
simulation_movement_invoice.getSpecialise())
self.assertEquals("service_module/vifib_instance_subscription",
simulation_movement_invoice.getResource())
self.assertEquals("vifib/invoicing",
simulation_movement_invoice.getTradePhase())
self.assertEquals(expected_start_date,
simulation_movement_invoice.getStartDate())
self.assertEquals(expected_stop_date,
simulation_movement_invoice.getStopDate())
self.assertEquals(None,
simulation_movement_invoice.getAggregate(
portal_type="Computer Partition"))
self.assertEquals(None,
simulation_movement_invoice.getAggregate(
portal_type="Software Instance"))
self.assertEquals(hosting_subscription.getRelativeUrl(),
simulation_movement_invoice.getAggregate(
portal_type="Hosting Subscription"))
self.assertEquals(None,
simulation_movement_invoice.getAggregate(
portal_type="Software Release"))
# fetch invoice transaction level simulation, there are 2:
# credit and debit, and resource should be currency
applied_rule_invoice_transaction_list = \
simulation_movement_invoice.contentValues(portal_type="Applied Rule")
self.assertEquals(1, len(applied_rule_invoice_transaction_list))
applied_rule_invoice_transaction = \
applied_rule_invoice_transaction_list[0].getObject()
self.assertNotEquals(None, applied_rule_invoice_transaction)
simulation_movement_invoice_transaction_list = \
applied_rule_invoice_transaction.contentValues(
portal_type="Simulation Movement")
self.assertEquals(2, len(simulation_movement_invoice_transaction_list))
simulation_movement_invoice_transaction_credit = None
simulation_movement_invoice_transaction_debit = None
for simulation_movement_invoice_transaction in \
simulation_movement_invoice_transaction_list:
# not delivered nor buildable
self.assertEqual(None, simulation_movement_invoice_transaction\
.getDelivery())
self.assertFalse(simulation_movement_invoice_transaction.isBuildable())
if "business_process_module/vifib_sale_business_process/account_credit_path" \
in simulation_movement_invoice_transaction.getCausalityList():
simulation_movement_invoice_transaction_credit = \
simulation_movement_invoice_transaction.getObject()
if "business_process_module/vifib_sale_business_process/account_debit_path" \
in simulation_movement_invoice_transaction.getCausalityList():
simulation_movement_invoice_transaction_debit = \
simulation_movement_invoice_transaction.getObject()
self.assertNotEquals(None, simulation_movement_invoice_transaction_credit)
# not delivered nor buildable
self.assertEqual(None, simulation_movement_invoice_transaction_credit\
.getDelivery())
self.assertFalse(simulation_movement_invoice_transaction_credit\
.isBuildable())
self.assertNotEquals(None, simulation_movement_invoice_transaction_debit)
# not delivered nor buildable
self.assertEqual(None, simulation_movement_invoice_transaction_debit\
.getDelivery())
self.assertFalse(simulation_movement_invoice_transaction_debit\
.isBuildable())
# check property of invoice transaction simulation
self.assertEquals(-1.0,
simulation_movement_invoice_transaction_credit.getQuantity())
self.assertEquals("unit/piece",
simulation_movement_invoice_transaction_credit.getQuantityUnit())
self.assertEquals(1.0,
simulation_movement_invoice_transaction_credit.getPrice())
self.assertEquals(None,
simulation_movement_invoice_transaction_credit.getPriceCurrency())
self.assertEquals("account_module/sales",
simulation_movement_invoice_transaction_credit.getSource())
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_invoice_transaction_credit.getSourceSection())
self.assertEquals("account_module/purchase",
simulation_movement_invoice_transaction_credit.getDestination())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_invoice_transaction_credit.getDestinationSection())
self.assertEquals("currency_module/EUR",
simulation_movement_invoice_transaction_credit.getResource())
self.assertEquals(open_order_line.getSpecialise(),
simulation_movement_invoice_transaction_credit.getSpecialise())
self.assertEquals("vifib/accounting",
simulation_movement_invoice_transaction_credit.getTradePhase())
self.assertEquals(expected_start_date,
simulation_movement_invoice_transaction_credit.getStartDate())
self.assertEquals(expected_stop_date,
simulation_movement_invoice_transaction_credit.getStopDate())
self.assertEquals(1.0,
simulation_movement_invoice_transaction_debit.getQuantity())
self.assertEquals("unit/piece",
simulation_movement_invoice_transaction_debit.getQuantityUnit())
self.assertEquals(1.0,
simulation_movement_invoice_transaction_debit.getPrice())
self.assertEquals(None,
simulation_movement_invoice_transaction_debit.getPriceCurrency())
self.assertEquals("account_module/receivable",
simulation_movement_invoice_transaction_debit.getSource())
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_invoice_transaction_debit.getSourceSection())
self.assertEquals("account_module/payable",
simulation_movement_invoice_transaction_debit.getDestination())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_invoice_transaction_debit.getDestinationSection())
self.assertEquals("currency_module/EUR",
simulation_movement_invoice_transaction_debit.getResource())
self.assertEquals(open_order_line.getSpecialise(),
simulation_movement_invoice_transaction_debit.getSpecialise())
self.assertEquals("vifib/accounting",
simulation_movement_invoice_transaction_debit.getTradePhase())
self.assertEquals(expected_start_date,
simulation_movement_invoice_transaction_debit.getStartDate())
self.assertEquals(expected_stop_date,
simulation_movement_invoice_transaction_debit.getStopDate())
# credit simulation movement has no content
self.assertEquals([],
simulation_movement_invoice_transaction_credit.contentValues(
portal_type="Applied Rule"))
# fetch payment level simulation
applied_rule_credit_payment_list = \
simulation_movement_invoice_transaction_debit.contentValues(
portal_type="Applied Rule")
self.assertEquals(1, len(applied_rule_credit_payment_list))
applied_rule_credit_payment = \
applied_rule_credit_payment_list[0].getObject()
self.assertNotEquals(None, applied_rule_credit_payment)
simulation_movement_credit_payment_list = \
applied_rule_credit_payment.contentValues(
portal_type="Simulation Movement")
self.assertEquals(2, len(simulation_movement_credit_payment_list))
simulation_movement_credit_payment_credit = None
simulation_movement_credit_payment_debit = None
for simulation_movement_credit_payment in \
simulation_movement_credit_payment_list:
if "business_process_module/vifib_sale_business_process/payment_credit_path" \
in simulation_movement_credit_payment.getCausalityList():
simulation_movement_credit_payment_credit = \
simulation_movement_credit_payment.getObject()
if "business_process_module/vifib_sale_business_process/payment_debit_path" \
in simulation_movement_credit_payment.getCausalityList():
simulation_movement_credit_payment_debit = \
simulation_movement_credit_payment.getObject()
self.assertNotEquals(None, simulation_movement_credit_payment_credit)
# not delivered nor buildable
self.assertEqual(None, simulation_movement_credit_payment_credit\
.getDelivery())
self.assertFalse(simulation_movement_credit_payment_credit\
.isBuildable())
self.assertNotEquals(None, simulation_movement_credit_payment_debit)
# not delivered nor buildable
self.assertEqual(None, simulation_movement_credit_payment_debit\
.getDelivery())
self.assertFalse(simulation_movement_credit_payment_debit\
.isBuildable())
# check payment level of simulation def stepIncreaseOpenOrderCoverage(self, sequence, **kw):
self.assertEquals(-1.0, person = self.portal.person_module['test_vifib_customer']
simulation_movement_credit_payment_credit.getQuantity()) open_order = \
self.assertEquals("unit/piece", person.getDestinationDecisionRelatedValue(portal_type="Open Sale Order")
simulation_movement_credit_payment_credit.getQuantityUnit()) open_order_line_list = \
self.assertEquals(1.0, open_order.contentValues(portal_type="Open Sale Order Line")
simulation_movement_credit_payment_credit.getPrice()) self.assertEquals(1, len(open_order_line_list))
self.assertEquals("currency_module/EUR", open_order_line = open_order_line_list[0]
simulation_movement_credit_payment_credit.getResource()) self.portal.portal_alarms.vifib_update_open_sale_order_line.activeSense(
self.assertEquals("account_module/receivable", params={'stop_date': addToDate(getClosestDate(target_date=DateTime(),
simulation_movement_credit_payment_credit.getSource()) precision='month', before=1), month=3)})
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_credit_payment_credit.getSourceSection())
self.assertEquals("account_module/payable",
simulation_movement_credit_payment_credit.getDestination())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_credit_payment_credit.getDestinationSection())
self.assertEquals(open_order_line.getSpecialise(),
simulation_movement_credit_payment_credit.getSpecialise())
self.assertEquals("vifib/payment",
simulation_movement_credit_payment_credit.getTradePhase())
self.assertEquals(expected_start_date,
simulation_movement_credit_payment_credit.getStartDate())
self.assertEquals(expected_stop_date,
simulation_movement_credit_payment_credit.getStopDate())
self.assertEquals(1.0,
simulation_movement_credit_payment_debit.getQuantity())
self.assertEquals("unit/piece",
simulation_movement_credit_payment_debit.getQuantityUnit())
self.assertEquals(1.0,
simulation_movement_credit_payment_debit.getPrice())
self.assertEquals("currency_module/EUR",
simulation_movement_credit_payment_debit.getResource())
self.assertEquals("account_module/bank",
simulation_movement_credit_payment_debit.getSource())
self.assertEquals("organisation_module/vifib_internet",
simulation_movement_credit_payment_debit.getSourceSection())
self.assertEquals("account_module/bank",
simulation_movement_credit_payment_debit.getDestination())
self.assertEquals("person_module/test_vifib_customer",
simulation_movement_credit_payment_debit.getDestinationSection())
self.assertEquals(open_order_line.getSpecialise(),
simulation_movement_credit_payment_debit.getSpecialise())
self.assertEquals("vifib/payment",
simulation_movement_credit_payment_debit.getTradePhase())
self.assertEquals(expected_start_date,
simulation_movement_credit_payment_debit.getStartDate())
self.assertEquals(expected_stop_date,
simulation_movement_credit_payment_debit.getStopDate())
# check next simulation movement def stepCheckThreeTopLevelSimulationMovement(self, sequence, **kw):
idx += 1 person = self.portal.person_module['test_vifib_customer']
open_order = \
person.getDestinationDecisionRelatedValue(portal_type="Open Sale Order")
open_order_line_list = \
open_order.contentValues(portal_type="Open Sale Order Line")
self.assertEquals(1, len(open_order_line_list))
open_order_line = open_order_line_list[0]
hosting_subscription = \
open_order_line.getAggregateValue(portal_type="Hosting Subscription")
applied_rule = \
hosting_subscription.getCausalityRelatedValue(portal_type="Applied Rule")
self.assertEquals(
"portal_rules/default_subscription_item_rule",
applied_rule.getSpecialise())
simulation_movement_list = self.portal.portal_catalog(
portal_type='Simulation Movement',
parent_uid=applied_rule.getUid(),
sort_on=(('movement.start_date', 'desc'),)
)
# Check that simulation is created by the periodicity for two months
self.assertEquals(3,
len(simulation_movement_list))
def test_OpenOrder_request_changeSoftwareType(self): def test_OpenOrder_request_changeSoftwareType(self):
""" """
...@@ -412,7 +206,13 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -412,7 +206,13 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
CheckSimulationMovement CheckSimulationMovement
Tic Tic
SlapLogout SlapLogout
""" + """
LoginERP5TypeTestCase
IncreaseOpenOrderCoverage
Tic
CheckThreeTopLevelSimulationMovement
Logout
LoginTestVifibCustomer LoginTestVifibCustomer
RequestSoftwareInstanceStart RequestSoftwareInstanceStart
Tic Tic
...@@ -420,13 +220,13 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin): ...@@ -420,13 +220,13 @@ class TestVifibOpenOrderSimulation(TestVifibSlapWebServiceMixin):
LoginDefaultUser LoginDefaultUser
CheckComputerPartitionInstanceHostingSalePackingListConfirmed CheckComputerPartitionInstanceHostingSalePackingListConfirmed
Logout Logout
SlapLoginCurrentComputer \ SlapLoginCurrentComputer
SoftwareInstanceStarted \ SoftwareInstanceStarted
Tic \ Tic
SlapLogout \ SlapLogout
\
LoginDefaultUser \ LoginDefaultUser
CheckComputerPartitionInstanceHostingSalePackingListStarted \ CheckComputerPartitionInstanceHostingSalePackingListStarted
Logout Logout
LoginERP5TypeTestCase LoginERP5TypeTestCase
......
...@@ -178,6 +178,8 @@ erp5_system_event ...@@ -178,6 +178,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -273,6 +275,8 @@ erp5_system_event ...@@ -273,6 +275,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -368,6 +372,8 @@ erp5_system_event ...@@ -368,6 +372,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -405,6 +411,7 @@ vifib_simulation ...@@ -405,6 +411,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_knowledge_pad erp5_knowledge_pad
erp5_simulation erp5_simulation
erp5_dms_base erp5_dms_base
...@@ -456,6 +463,8 @@ erp5_system_event ...@@ -456,6 +463,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -492,6 +501,7 @@ vifib_simulation ...@@ -492,6 +501,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_knowledge_pad erp5_knowledge_pad
erp5_simulation erp5_simulation
erp5_dms_base erp5_dms_base
...@@ -543,6 +553,8 @@ erp5_system_event ...@@ -543,6 +553,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -634,6 +646,8 @@ erp5_system_event ...@@ -634,6 +646,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -671,6 +685,7 @@ vifib_simulation ...@@ -671,6 +685,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_km erp5_km
erp5_km_theme erp5_km_theme
erp5_knowledge_pad erp5_knowledge_pad
...@@ -725,6 +740,8 @@ erp5_system_event ...@@ -725,6 +740,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -762,6 +779,7 @@ vifib_simulation ...@@ -762,6 +779,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_commerce_multiflex_layout erp5_commerce_multiflex_layout
erp5_knowledge_pad erp5_knowledge_pad
erp5_simulation erp5_simulation
...@@ -813,6 +831,8 @@ erp5_system_event ...@@ -813,6 +831,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -849,6 +869,7 @@ vifib_simulation ...@@ -849,6 +869,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_web_download_theme erp5_web_download_theme
erp5_knowledge_pad erp5_knowledge_pad
erp5_simulation erp5_simulation
...@@ -900,6 +921,8 @@ erp5_system_event ...@@ -900,6 +921,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
...@@ -935,6 +958,7 @@ vifib_simulation ...@@ -935,6 +958,7 @@ vifib_simulation
vifib_slap vifib_slap
vifib_software_pdm vifib_software_pdm
vifib_test vifib_test
vifib_web_ui_test
erp5_rss_style erp5_rss_style
erp5_knowledge_pad erp5_knowledge_pad
erp5_simulation erp5_simulation
...@@ -986,6 +1010,8 @@ erp5_system_event ...@@ -986,6 +1010,8 @@ erp5_system_event
erp5_tax_resource erp5_tax_resource
erp5_toolbox erp5_toolbox
erp5_trade erp5_trade
erp5_ui_test
erp5_ui_test_core
erp5_vcs erp5_vcs
erp5_web erp5_web
erp5_web_crm erp5_web_crm
......
from Products.ERP5Type.tests.backportUnittest import skip
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
import unittest import unittest
from Products.ERP5Type.tests.backportUnittest import expectedFailure
from slapos import slap from slapos import slap
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
from random import random from random import random
...@@ -299,8 +299,7 @@ class TestVifibSlapBang(TestVifibSlapWebServiceMixin): ...@@ -299,8 +299,7 @@ class TestVifibSlapBang(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# Computer owner cannot do bang yet @skip('Computer owner cannot do bang yet')
@expectedFailure
def test_admin_bang_computer_complex_tree(self): def test_admin_bang_computer_complex_tree(self):
"""Checks that bangs works on complex tree """Checks that bangs works on complex tree
...@@ -718,6 +717,346 @@ class TestVifibSlapBang(TestVifibSlapWebServiceMixin): ...@@ -718,6 +717,346 @@ class TestVifibSlapBang(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
def stepCheckTreeLooksLikeRenameComplexTree(self, sequence, **kw):
hosting_subscription_uid = sequence['hosting_subscription_uid']
hosting_subscription = self.portal.portal_catalog.getResultValue(
uid=hosting_subscription_uid
)
root_software_instance = hosting_subscription.portal_catalog.getResultValue(
title=hosting_subscription.getTitle(), portal_type="Software Instance",
root_uid=hosting_subscription_uid)
self.failIfEqual(root_software_instance, None)
children_titles = set([si.getTitle()
for si in root_software_instance.getPredecessorValueList()])
self.failUnless(set(['children_a', 'children_b']) <= children_titles)
children_b_child = hosting_subscription.portal_catalog.getResultValue(
title='children_b_child',
root_uid=hosting_subscription.getUid(),
)
self.failIfEqual(children_b_child, None)
@skip('Ignored for now')
def test_ComputerPartition_rename_root_and_bang(self):
r"""
Request Master: __________
/ \
| HS: Master |
\__________/
_____|____
/ \
| SI: Master |
\__________/
Rename Software Instance Master into MasterDead:
__________
/ \
| HS: Master |
\__________/
_______|______
/ \
| SI: MasterDead |
\______________/
Banging the tree should result:
_____________________________
/ \
| HS: Master |
\______________________________/
____/_____ _______\______
/ \ / \
| SI: Master | | SI: MasterDead |
\__________/ \______________/
"""
self.computer_partition_amount = 2
sequence_list = SequenceList()
sequence_string = self.prepare_install_requested_computer_partition_sequence_string + """
SetRootSoftwareInstanceCurrentInstance
Tic
LoginDefaultUser
RenameCurrentSoftwareInstanceDead
Tic
Logout
SlapLoginCurrentSoftwareInstance
Bang
ConfirmOrderedSaleOrderActiveSense
SlapLogout
Tic
LoginTestVifibCustomer
CheckTreeHasARootSoftwareInstance
Logout
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
@skip('Ignored for now')
def test_ComputerPartition_rename_root_complex_tree(self):
r"""
Request Master which is a software realease having a complex tree :
___________________________
/ \
| HS: Master |
\____________________________/
_____________|_____________
/ \
| SI: Master |
\____________________________/
_____/_____ _____\_____
/ \ / \
| SI: Child A | | SI: Child B |
\___________/ \___________/
______|______
/ \
| SI: GrandChild |
\______________/
Rename Software Instance Master :
___________________________
/ \
| SI: Master |
\____________________________/
_____________|_____________
/ \
| SI: MasterDead |
\____________________________/
_____/_____ _____\_____
/ \ / \
| SI: Child A | | SI: Child B |
\___________/ \___________/
______|______
/ \
| SI: GrandChild |
\______________/
Run bang() on the tree. We expect to have a new root as :
_______________________________________________
/ \
| HS: Master |
\_______________________________________________/
_____________|______________ _______|______
/ \ / \
| SI: Master | | SI: MasterDead |
\____________________________/ \______________/
_____/_____ _____\_____
/ \ / \
| SI: Child A | | SI: Child B |
\___________/ \___________/
______|______
/ \
| SI: GrandChild |
\______________/
"""
self.computer_partition_amount = 5
sequence_list = SequenceList()
sequence_string = self.prepare_children_a_children_b_sequence_string + """
LoginDefaultUser
SetSoftwareInstanceChildrenB
SelectRequestedReferenceChildrenBChild
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
Tic
CheckRaisesNotFoundComputerPartitionParameterDict
Tic
RequestComputerPartition
Tic
SlapLogout
LoginDefaultUser
SlapLoginTestVifibCustomer
SetSoftwareInstanceRoot
RenameCurrentSoftwareInstanceDead
Tic
Bang
ConfirmOrderedSaleOrderActiveSense
Tic
Logout
SlapLogout
LoginDefaultUser
SetSoftwareInstanceGetRootOfTheTree
SetRootSoftwareInstanceCurrentInstance
SelectRequestedReferenceChildrenA
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
Tic
SlapLogout
LoginDefaultUser
SelectRequestedReferenceChildrenB
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SetSoftwareInstanceChildrenB
SelectRequestedReferenceChildrenBChild
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SlapLoginCurrentComputer
CheckTreeHasARootSoftwareInstance
CheckTreeLooksLikeRenameComplexTree
SlapLogout
Logout
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_ComputerPartition_rename_child_complex_tree(self):
r"""
Request A which is a software realease having a complex tree :
___________________________
/ \
| HS: Master |
\____________________________/
_____________|_____________
/ \
| SI: Master |
\____________________________/
_____/_____ _____\_____
/ \ / \
| SI: Child A | | SI: Child B |
\___________/ \___________/
______|______
/ \
| SI: GrandChild |
\______________/
Rename child C into E :
(Rename reattach to root as Luke wanted it)
________________________________
/ \
| HS: Master |
\________________________________/
________________|_______________
/ \
| SI: Master |
\________________________________/
_____/_____ _________\______
/ \ / \
| SI: Child A | | SI: Child B Dead |
\___________/ \________________/
______|______
/ \
| SI: GrandChild |
\______________/
Bang the tree. We espect to have a new C replacing it,
as : _________________________________________________
/ \
| HS: Master |
\_________________________________________________/
_____________|___________________________________
/ \
| SI: Master |
\_________________________________________________/
_____/_____ _____\_____ _______|________
/ \ / \ / \
| SI: Child A | | SI: Child B | | SI: Child B Dead |
\___________/ \___________/ \________________/
______|______
/ \
| SI: GrandChild |
\______________/
"""
self.computer_partition_amount = 5
sequence_list = SequenceList()
sequence_string = self.prepare_children_a_children_b_sequence_string + """
LoginDefaultUser
SetSoftwareInstanceChildrenB
SelectRequestedReferenceChildrenBChild
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
Tic
CheckRaisesNotFoundComputerPartitionParameterDict
Tic
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SlapLoginTestVifibCustomer
SetSoftwareInstanceChildrenB
RenameCurrentSoftwareInstanceDead
Tic
Bang
ConfirmOrderedSaleOrderActiveSense
Tic
Logout
SlapLogout
LoginDefaultUser
SetSoftwareInstanceGetRootOfTheTree
SetRootSoftwareInstanceCurrentInstance
SelectRequestedReferenceChildrenA
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SelectRequestedReferenceChildrenB
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SetSoftwareInstanceChildrenB
SelectRequestedReferenceChildrenBChild
SelectEmptyRequestedParameterDict
Logout
SlapLoginCurrentSoftwareInstance
RequestComputerPartition
ConfirmOrderedSaleOrderActiveSense
Tic
SlapLogout
LoginDefaultUser
SlapLoginCurrentComputer
CheckTreeHasARootSoftwareInstance
CheckTreeLooksLikeRenameComplexTree
SlapLogout
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestVifibSlapBang)) suite.addTest(unittest.makeSuite(TestVifibSlapBang))
......
...@@ -2,6 +2,7 @@ from Products.ERP5Type.tests.Sequence import SequenceList ...@@ -2,6 +2,7 @@ from Products.ERP5Type.tests.Sequence import SequenceList
import unittest import unittest
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
import random import random
import transaction
class TestVifibSlapBug(TestVifibSlapWebServiceMixin): class TestVifibSlapBug(TestVifibSlapWebServiceMixin):
def test_bug_Person_request_more_then_one_instance(self): def test_bug_Person_request_more_then_one_instance(self):
...@@ -702,6 +703,7 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin): ...@@ -702,6 +703,7 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin):
sla_xml=self.minimal_correct_xml, sla_xml=self.minimal_correct_xml,
state='started' state='started'
) )
transaction.abort()
def test_bug_orhpaned_software_instance(self): def test_bug_orhpaned_software_instance(self):
"""Check that no orphaned Software Instances would be created """Check that no orphaned Software Instances would be created
...@@ -866,6 +868,7 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin): ...@@ -866,6 +868,7 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin):
sla_xml=self.minimal_correct_xml, sla_xml=self.minimal_correct_xml,
state='started' state='started'
) )
transaction.abort()
def test_bug_cyclic_software_instance(self): def test_bug_cyclic_software_instance(self):
"""Check that no cyclic Software Instance trees would be created """Check that no cyclic Software Instance trees would be created
...@@ -1520,6 +1523,84 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin): ...@@ -1520,6 +1523,84 @@ class TestVifibSlapBug(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
def test_bug_person_request_ComputerPartition_own_computer(self):
"""Checks that Person using Slap interface is able to request Computer
Partition"""
self.computer_partition_amount = 1
sequence_list = SequenceList()
sequence_string = self.prepare_published_software_release + \
"""
Logout
RequestCredentialFromWebSite
Tic
LoginDefaultUser
SubmitCredentialRequest
Tic
AcceptSubmittedCredentialsActiveSense
Tic
Logout
LoginWebUser
CustomerRegisterNewComputer
Tic
SetComputerCoordinatesFromComputerTitle
ComputerSetAllocationScopeOpenPersonal
Logout
SlapLoginCurrentComputer
FormatComputer
Tic
SlapLogout
LoginWebUser
RequestSoftwareInstallation
Tic
Logout
SlapLoginCurrentComputer
ComputerSoftwareReleaseAvailable
Tic
SlapLogout
SetRandomRequestedReference
SlapLoginWebUser
PersonRequestSlapSoftwareInstancePrepare
Tic
SlapLogout
LoginDefaultUser
ConfirmOrderedSaleOrderActiveSense
Tic
Logout
SlapLoginWebUser
PersonRequestSlapSoftwareInstance
Tic
SlapLogout
LoginDefaultUser
SetCurrentPersonSlapRequestedSoftwareInstance
CheckPersonRequestedSoftwareInstanceAndRelatedComputerPartition
Logout
SlapLoginCurrentSoftwareInstance
CheckRequestedComputerPartitionCleanParameterList
SlapLogout
LoginWebUser
CheckViewCurrentSoftwareInstance
CheckWriteCurrentSoftwareInstance
Tic
Logout
LoginERP5TypeTestCase
CheckSiteConsistency
Logout
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestVifibSlapBug)) suite.addTest(unittest.makeSuite(TestVifibSlapBug))
......
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
import transaction import transaction
import unittest import unittest
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
...@@ -50,9 +50,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin ...@@ -50,9 +50,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
self.computer_partition_amount = 2 self.computer_partition_amount = 2
self.test_Computer_getComputerPartitionList_emptyPartition() self.test_Computer_getComputerPartitionList_emptyPartition()
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getComputerPartitionList_unknowComputerUid(self): def test_Computer_getComputerPartitionList_unknowComputerUid(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
...@@ -66,9 +65,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin ...@@ -66,9 +65,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getComputerPartitionList_draftComputer(self): def test_Computer_getComputerPartitionList_draftComputer(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
...@@ -109,9 +107,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin ...@@ -109,9 +107,8 @@ class TestVifibSlapComputerGetComputerPartitionList(TestVifibSlapWebServiceMixin
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getComputerPartitionList_TwoValidatedComputer(self): def test_Computer_getComputerPartitionList_TwoValidatedComputer(self):
# XXX: It shall be part of VifibMachineAuthentication test suite # XXX: It shall be part of VifibMachineAuthentication test suite
sequence_list = SequenceList() sequence_list = SequenceList()
......
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
import transaction import transaction
import unittest import unittest
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
...@@ -9,9 +9,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin): ...@@ -9,9 +9,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin):
# Computer.getSoftwareReleaseList # Computer.getSoftwareReleaseList
######################################## ########################################
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getSoftwareReleaseList_unknowComputerUid(self): def test_Computer_getSoftwareReleaseList_unknowComputerUid(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
...@@ -27,9 +26,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin): ...@@ -27,9 +26,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getSoftwareReleaseList_draftComputer(self): def test_Computer_getSoftwareReleaseList_draftComputer(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
...@@ -88,9 +86,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin): ...@@ -88,9 +86,8 @@ class TestVifibSlapComputerGetSoftwareReleaseList(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_Computer_getSoftwareReleaseList_TwoValidatedComputer(self): def test_Computer_getSoftwareReleaseList_TwoValidatedComputer(self):
# XXX: It shall be part of VifibMachineAuthentication test suite # XXX: It shall be part of VifibMachineAuthentication test suite
sequence_list = SequenceList() sequence_list = SequenceList()
......
from Products.ERP5Type.tests.Sequence import SequenceList
import unittest
from testVifibSlapWebService import TestVifibSlapWebServiceMixin
from Products.DCWorkflow.DCWorkflow import ValidationFailed
from random import random
from slapos import slap
class TestVifibSlapComputerPartitionLock(TestVifibSlapWebServiceMixin):
def test_lock_building(self):
"""Check locking building computer partition
It shall render it as stopped and disallow any operation.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_stopping(self):
"""Check locking stopping computer partition
It shall render it as stopped and disallow any operation.
Stopping shall be possible.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_stopped(self):
"""Check locking stopped computer partition
It shall render it as stopped and disallow any operation.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_starting(self):
"""Check locking starting computer partition
It shall render it as stopped and disallow any operation.
Stopping shall be possible.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_started(self):
"""Check locking started computer partition
It shall render it as stopped and disallow starting.
Stopping shall be possible.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_destroying(self):
"""Check locking destroying computer partition
It shall render it as destroyed.
Destruction shall be possible.
"""
raise NotImplementedError
def test_lock_destroyed(self):
"""Check locking destroyed computer partition
It shall not render it at all.
"""
raise NotImplementedError
def test_lock_update(self):
"""Check locking update computer partition
It shall render as stopped.
Destruction shall be possible.
"""
raise NotImplementedError
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestVifibSlapComputerPartitionLock))
return suite
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
import urllib import urllib
import urlparse import urlparse
import httplib import httplib
...@@ -353,10 +353,9 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin): ...@@ -353,10 +353,9 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# XXX: This test fails because test_vifib_customer security is cached @skip('This test fails because test_vifib_customer security is cached '
# and this user is not in SOFTINST-x group. We do not want to clear 'and this user is not in SOFTINST-x group. We do not want to clear '
# cache in tests. 'cache in tests.')
@expectedFailure
def test_ComputerPartition_request_instantiateStop(self): def test_ComputerPartition_request_instantiateStop(self):
""" """
Check that after computer partition is requested it is possible to Check that after computer partition is requested it is possible to
...@@ -715,8 +714,7 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin): ...@@ -715,8 +714,7 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# Marked as expectedFailure as implementation is not ready yet @skip('Implementation is not ready yet')
@expectedFailure
def test_ComputerPartition_request_twiceDifferentParentWithoutTic(self): def test_ComputerPartition_request_twiceDifferentParentWithoutTic(self):
""" """
Checks that requesting twice with same arguments from different Computer Checks that requesting twice with same arguments from different Computer
...@@ -837,8 +835,7 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin): ...@@ -837,8 +835,7 @@ class TestVifibSlapComputerPartitionRequest(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# Marked as expectedFailure as implementation is not ready yet @skip('Implementation is not ready yet.')
@expectedFailure
def test_ComputerPartition_request_differentSourceDifferentResultWithoutTic( def test_ComputerPartition_request_differentSourceDifferentResultWithoutTic(
self): self):
""" """
......
...@@ -571,9 +571,9 @@ class TestVifibSlapComputerPartitionUpdate(TestVifibSlapWebServiceMixin): ...@@ -571,9 +571,9 @@ class TestVifibSlapComputerPartitionUpdate(TestVifibSlapWebServiceMixin):
slap_computer_partition.request(**kw) slap_computer_partition.request(**kw)
def stepCheckActivityRequestInProgress(self, sequence, **kw): def stepCheckActivityRequestInProgress(self, sequence, **kw):
software_instance_uid = sequence['software_instance_uid'] hosting_subscription_uid = sequence['hosting_subscription_uid']
requested_partition_reference = sequence.get('software_type', 'requested_reference') requested_partition_reference = sequence.get('software_type', 'requested_reference')
tag = "%s_%s_inProgress" % (software_instance_uid, tag = "%s_%s_inProgress" % (hosting_subscription_uid,
requested_partition_reference) requested_partition_reference)
self.assertNotEqual(0, self.portal.portal_activities. self.assertNotEqual(0, self.portal.portal_activities.
......
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
import unittest import unittest
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
...@@ -8,9 +8,8 @@ class TestVifibSlapRegisterComputerPartition(TestVifibSlapWebServiceMixin): ...@@ -8,9 +8,8 @@ class TestVifibSlapRegisterComputerPartition(TestVifibSlapWebServiceMixin):
# slap.registerComputerPartition # slap.registerComputerPartition
######################################## ########################################
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_slap_registerComputerPartition_unknowComputerUid(self): def test_slap_registerComputerPartition_unknowComputerUid(self):
""" """
Check the slap.registerComputerPartition without any Computer document Check the slap.registerComputerPartition without any Computer document
...@@ -30,9 +29,8 @@ class TestVifibSlapRegisterComputerPartition(TestVifibSlapWebServiceMixin): ...@@ -30,9 +29,8 @@ class TestVifibSlapRegisterComputerPartition(TestVifibSlapWebServiceMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# ERP5/Zope does not follow REST API beacuse it is not possible to configure @skip('ERP5/Zope does not follow REST API beacuse it is not possible to '
# Cookie Crumbler to ignore portal_slap 'configure Cookie Crumbler to ignore portal_slap')
@expectedFailure
def test_slap_registerComputerPartition_draftComputer(self): def test_slap_registerComputerPartition_draftComputer(self):
""" """
Check the slap.registerComputerPartition fails Check the slap.registerComputerPartition fails
......
...@@ -873,6 +873,10 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -873,6 +873,10 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
global REMOTE_USER global REMOTE_USER
REMOTE_USER = 'test_vifib_customer' REMOTE_USER = 'test_vifib_customer'
def stepSlapLoginWebUser(self, sequence, **kw):
global REMOTE_USER
REMOTE_USER = sequence['web_user']
######################################## ########################################
# Typical sequences for scenarios # Typical sequences for scenarios
######################################## ########################################
...@@ -1798,18 +1802,15 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -1798,18 +1802,15 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
second = slap_computer_partition.request(software_release, second = slap_computer_partition.request(software_release,
software_type, software_type + str(2)) software_type, software_type + str(2))
self.stepLoginDefaultUser() self.stepLoginDefaultUser()
transaction.commit() self.stepTic()
self.tic()
self.stepConfirmOrderedSaleOrderActiveSense() self.stepConfirmOrderedSaleOrderActiveSense()
transaction.commit() self.stepTic()
self.tic()
self.stepLogout() self.stepLogout()
first = slap_computer_partition.request(software_release, first = slap_computer_partition.request(software_release,
software_type, software_type + str(1)) software_type, software_type + str(1))
second = slap_computer_partition.request(software_release, second = slap_computer_partition.request(software_release,
software_type, software_type + str(2)) software_type, software_type + str(2))
transaction.commit() self.stepTic()
self.tic()
self.assertNotEqual(first.getId(), second.getId()) self.assertNotEqual(first.getId(), second.getId())
def stepRequestComputerPartition(self, sequence, **kw): def stepRequestComputerPartition(self, sequence, **kw):
...@@ -1837,12 +1838,13 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -1837,12 +1838,13 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
def _stepSetSoftwareInstanceChildren(self, sequence, source_reference): def _stepSetSoftwareInstanceChildren(self, sequence, source_reference):
software_instance_uid = sequence['root_software_instance_uid'] software_instance_uid = sequence['root_software_instance_uid']
hosting_subscription_uid = sequence['hosting_subscription_uid']
software_instance = self.portal.portal_catalog.getResultValue( software_instance = self.portal.portal_catalog.getResultValue(
uid=software_instance_uid) uid=software_instance_uid)
children_software_instance = \ children_software_instance = \
software_instance.portal_catalog.getResultValue( software_instance.portal_catalog.getResultValue(
portal_type="Software Instance", source_reference=source_reference, portal_type="Software Instance", source_reference=source_reference,
root_uid=software_instance_uid) root_uid=hosting_subscription_uid)
self.assertNotEqual(None, children_software_instance) self.assertNotEqual(None, children_software_instance)
self.assertNotEqual(software_instance.getRelativeUrl(), self.assertNotEqual(software_instance.getRelativeUrl(),
children_software_instance.getRelativeUrl()) children_software_instance.getRelativeUrl())
...@@ -1864,6 +1866,18 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -1864,6 +1866,18 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
self.assertNotEqual(None, software_instance_uid) self.assertNotEqual(None, software_instance_uid)
sequence.edit(root_software_instance_uid=software_instance_uid) sequence.edit(root_software_instance_uid=software_instance_uid)
def stepSetSoftwareInstanceRoot(self, sequence, **kw):
root_software_instance_uid = sequence['root_software_instance_uid']
self.failIfEqual(None, root_software_instance_uid)
root_software_instance = self.portal.portal_catalog.getResultValue(
uid=root_software_instance_uid,
)
self.failIfEqual(None, root_software_instance)
computer_partition_reference = self._softwareInstance_getComputerPartition(
root_software_instance).getReference()
sequence.edit(software_instance_uid=root_software_instance_uid,
computer_partition_reference=computer_partition_reference)
def stepRequestComputerPartitionDifferentReferenceSameTransaction(self, def stepRequestComputerPartitionDifferentReferenceSameTransaction(self,
sequence, **kw): sequence, **kw):
software_release_uri = sequence['software_release_uri'] software_release_uri = sequence['software_release_uri']
...@@ -2017,6 +2031,8 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -2017,6 +2031,8 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
finally: finally:
Base.serialize = Base.serialize_call Base.serialize = Base.serialize_call
transaction.abort()
def _getComputerPartitionByReference(self, sequence): def _getComputerPartitionByReference(self, sequence):
computer_partition_list = self.portal.portal_catalog( computer_partition_list = self.portal.portal_catalog(
portal_type=self.computer_partition_portal_type, portal_type=self.computer_partition_portal_type,
...@@ -3896,6 +3912,73 @@ class TestVifibSlapWebServiceMixin(testVifibMixin): ...@@ -3896,6 +3912,73 @@ class TestVifibSlapWebServiceMixin(testVifibMixin):
def stepSetRandomRequestedReference(self, sequence, **kw): def stepSetRandomRequestedReference(self, sequence, **kw):
sequence['requested_reference'] = self.id() + str(random()) sequence['requested_reference'] = self.id() + str(random())
def stepRenameCurrentSoftwareInstanceDead(self, sequence, **kw):
hosting_subscription = self.portal.portal_catalog.getResultValue(
uid=sequence['hosting_subscription_uid'],
)
software_instance = self.portal.portal_catalog.getResultValue(
uid=sequence['software_instance_uid']
)
software_instance.rename(new_name='%sDead' % software_instance.getTitle())
def stepCheckTreeHasARootSoftwareInstance(self, sequence, **kw):
hosting_subscription_uid = sequence['hosting_subscription_uid']
hosting_subscription = self.portal.portal_catalog.getResultValue(
uid=hosting_subscription_uid,
)
root_software_instance = self.portal.portal_catalog.getResultValue(
root_uid=hosting_subscription_uid,
title=hosting_subscription.getTitle(),
)
self.failIfEqual(root_software_instance, None,
"No root software instance")
def stepSetSoftwareInstanceGetRootOfTheTree(self, sequence, **kw):
hosting_subscription_uid = sequence['hosting_subscription_uid']
hosting_subscription = self.portal.portal_catalog.getResultValue(
uid=hosting_subscription_uid,
)
root_software_instance = self.portal.portal_catalog.getResultValue(
root_uid=hosting_subscription_uid,
title=hosting_subscription.getTitle(),
)
self.failIfEqual(root_software_instance, None,
"No root software instance")
computer_partition_reference = self._softwareInstance_getComputerPartition(
root_software_instance).getReference()
sequence.edit(software_instance_uid=root_software_instance.getUid(),
computer_partition_reference=computer_partition_reference)
def stepRequestCredentialFromWebSite(self, sequence, **kw):
sequence['web_user_email'] = '%s@example.com' % random()
sequence['web_user'] = '%s.%s' % (self.id(), random())
self.portal.ERP5Site_newCredentialRequest(\
first_name='Homer',
last_name='Simpson',
reference=sequence['web_user'],
password='secret',
default_email_text=sequence['web_user_email'],
)
def stepSubmitCredentialRequest(self, sequence, **kw):
"""Simulates click of user in email confirmation about account"""
credential_request = self.portal.portal_catalog.getResultValue(
portal_type='Credential Request',
reference=sequence['web_user']
)
credential_request.submit()
def stepAcceptSubmittedCredentialsActiveSense(self, **kw):
self.portal.portal_alarms.accept_submitted_credentials.activeSense()
def stepLoginWebUser(self, sequence, **kw):
self.login(sequence['web_user'])
class TestVifibSlapWebService(TestVifibSlapWebServiceMixin): class TestVifibSlapWebService(TestVifibSlapWebServiceMixin):
######################################## ########################################
# slap.initializeConnection # slap.initializeConnection
...@@ -4138,31 +4221,6 @@ class TestVifibSlapWebService(TestVifibSlapWebServiceMixin): ...@@ -4138,31 +4221,6 @@ class TestVifibSlapWebService(TestVifibSlapWebServiceMixin):
# Other tests # Other tests
######################################## ########################################
def stepRequestCredentialFromWebSite(self, sequence, **kw):
sequence['web_user_email'] = '%s@example.com' % random()
sequence['web_user'] = '%s.%s' % (self.id(), random())
self.portal.ERP5Site_newCredentialRequest(\
first_name='Homer',
last_name='Simpson',
reference=sequence['web_user'],
password='secret',
default_email_text=sequence['web_user_email'],
)
def stepSubmitCredentialRequest(self, sequence, **kw):
"""Simulates click of user in email confirmation about account"""
credential_request = self.portal.portal_catalog.getResultValue(
portal_type='Credential Request',
reference=sequence['web_user']
)
credential_request.submit()
def stepAcceptSubmittedCredentialsActiveSense(self, **kw):
self.portal.portal_alarms.accept_submitted_credentials.activeSense()
def stepLoginWebUser(self, sequence, **kw):
self.login(sequence['web_user'])
def test_person_from_credential_request_software_instance(self): def test_person_from_credential_request_software_instance(self):
"""Checks that person created from web can use the system""" """Checks that person created from web can use the system"""
sequence_list = SequenceList() sequence_list = SequenceList()
...@@ -4258,6 +4316,7 @@ class TestVifibSlapWebService(TestVifibSlapWebServiceMixin): ...@@ -4258,6 +4316,7 @@ class TestVifibSlapWebService(TestVifibSlapWebServiceMixin):
""" """
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
# class IComputerPartition # class IComputerPartition
# def started(): # def started():
# def stopped(): # def stopped():
......
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
import unittest import unittest
from VifibMixin import testVifibMixin from VifibMixin import testVifibMixin
...@@ -65,8 +65,7 @@ class TestVifibSoftwareInstance(testVifibMixin): ...@@ -65,8 +65,7 @@ class TestVifibSoftwareInstance(testVifibMixin):
self.assertRaises(DisconnectedSoftwareTree, self.checkConnected, graph, self.assertRaises(DisconnectedSoftwareTree, self.checkConnected, graph,
root) root)
# For now limitation of implementation gives false positive @skip('For now limitation of implementation gives false positive')
@expectedFailure
def test_si_tree_cyclic_connected(self): def test_si_tree_cyclic_connected(self):
"""Cyclic is connected """Cyclic is connected
......
...@@ -32,6 +32,7 @@ from lxml import etree ...@@ -32,6 +32,7 @@ from lxml import etree
from slapos import slap from slapos import slap
from testVifibSlapWebService import TestVifibSlapWebServiceMixin from testVifibSlapWebService import TestVifibSlapWebServiceMixin
from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.tests.backportUnittest import skip
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
...@@ -312,6 +313,7 @@ class TestVifibUsageReport(TestVifibUsageReportMixin): ...@@ -312,6 +313,7 @@ class TestVifibUsageReport(TestVifibUsageReportMixin):
def getTitle(self): def getTitle(self):
return "testVifibUsageReport" return "testVifibUsageReport"
@skip('Ignored for now.')
def test_usageReportWithSinglePartition(self): def test_usageReportWithSinglePartition(self):
""" """
Checks if useComputer method of SlapTool is properly called one time. Checks if useComputer method of SlapTool is properly called one time.
...@@ -343,6 +345,7 @@ class TestVifibUsageReport(TestVifibUsageReportMixin): ...@@ -343,6 +345,7 @@ class TestVifibUsageReport(TestVifibUsageReportMixin):
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
@skip('Ignored for now.')
def test_usageReportWithTwoPartitions(self): def test_usageReportWithTwoPartitions(self):
""" """
Checks if useComputer method of SlapTool is properly called two times. Checks if useComputer method of SlapTool is properly called two times.
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
############################################################################## ##############################################################################
import unittest import unittest
from VifibMixin import testVifibMixin from VifibMixin import testVifibMixin
from Products.ERP5Type.tests.backportUnittest import expectedFailure from Products.ERP5Type.tests.backportUnittest import skip
class TestVifibXHTML(testVifibMixin): class TestVifibXHTML(testVifibMixin):
run_all_test = 1 run_all_test = 1
...@@ -112,7 +112,7 @@ class TestVifibXHTML(testVifibMixin): ...@@ -112,7 +112,7 @@ class TestVifibXHTML(testVifibMixin):
error_list.append(form_path) error_list.append(form_path)
self.assertEquals(error_list, []) self.assertEquals(error_list, [])
@expectedFailure @skip('Skipped.')
def test_configurationOfFieldLibrary(self): def test_configurationOfFieldLibrary(self):
self.login() self.login()
error_list = [] error_list = []
......
...@@ -70,25 +70,43 @@ class OS(object): ...@@ -70,25 +70,43 @@ class OS(object):
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self._os, name) return getattr(self._os, name)
class SlapError(Exception): class UsageError(Exception):
pass
class NoAddressOnBridge(Exception):
""" """
Slap error Exception raised if there's not address on the bridge to construct IPv6
address with.
Attributes:
brige: String, the name of the bridge.
""" """
def __init__(self, message):
self.msg = message
class UsageError(SlapError): def __init__(self, bridge):
pass super(NoAddressOnBridge, self).__init__(
'No IPv6 found on bridge %s to construct IPv6 with.' % (bridge, )
)
class ExecError(SlapError): class AddressGenerationError(Exception):
pass """
Exception raised if the generation of an IPv6 based on the prefix obtained
from the bridge failed.
Attributes:
addr: String, the invalid address the exception is raised for.
"""
def __init__(self, addr):
super(AddressGenerationError, self).__init__(
'Generated IPv6 %s seems not to be a valid IP.' % addr
)
def callAndRead(argument_list, raise_on_error=True): def callAndRead(argument_list, raise_on_error=True):
popen = subprocess.Popen(argument_list, stdout=subprocess.PIPE, popen = subprocess.Popen(argument_list, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
result = popen.communicate()[0] result = popen.communicate()[0]
if raise_on_error and popen.returncode != 0: if raise_on_error and popen.returncode != 0:
raise ValueError('Issue during invoking %r, result was:\n%s' % (argument_list, result)) raise ValueError('Issue during invoking %r, result was:\n%s' % (
argument_list, result))
return popen.returncode, result return popen.returncode, result
def isGlobalScopeAddress(a): def isGlobalScopeAddress(a):
...@@ -124,54 +142,27 @@ def _getDict(instance): ...@@ -124,54 +142,27 @@ def _getDict(instance):
elif isinstance(instance, dict): elif isinstance(instance, dict):
result = {} result = {}
for key in instance.keys(): for key in instance:
result[key] = _getDict(instance[key]) result[key] = _getDict(instance[key])
return result return result
else: else:
try: try:
dikt = instance.__dict__
result = {}
for key in instance.__dict__.keys():
result[key] = _getDict(instance.__dict__[key])
return result
except AttributeError: except AttributeError:
return instance return instance
result = {}
for key, value in dikt.iteritems():
result[key] = _getDict(value)
return result
class Error(Exception): class Computer(object):
"Base class for exceptions in this module."
def __str__(self):
return self.message
class NoAddressOnBridge(Error):
"""
Exception raised if there's not address on the bridge to construct IPv6
address with.
Attributes:
brige: String, the name of the bridge.
"""
def __init__(self, bridge):
self.message = 'No IPv6 found on bridge %s to construct IPv6 with.' % bridge
class AddressGenerationError(Error):
"""
Exception raised if the generation of an IPv6 based on the prefix obtained
from the bridge failed.
Attributes:
addr: String, the invalid address the exception is raised for.
"""
def __init__(self, addr):
self.message = 'Generated IPv6 %s seems not to be a valid IP.' % addr
class Computer:
"Object representing the computer" "Object representing the computer"
instance_root = None
software_root = None
def __init__(self, reference, bridge=None, addr = None, netmask = None, def __init__(self, reference, bridge=None, addr=None, netmask=None,
ipv6_interface=None): ipv6_interface=None, software_user='slapsoft'):
""" """
Attributes: Attributes:
reference: String, the reference of the computer. reference: String, the reference of the computer.
...@@ -183,6 +174,7 @@ class Computer: ...@@ -183,6 +174,7 @@ class Computer:
self.address = addr self.address = addr
self.netmask = netmask self.netmask = netmask
self.ipv6_interface = ipv6_interface self.ipv6_interface = ipv6_interface
self.software_user = software_user
def __getinitargs__(self): def __getinitargs__(self):
return (self.reference, self.bridge) return (self.reference, self.bridge)
...@@ -259,8 +251,7 @@ class Computer: ...@@ -259,8 +251,7 @@ class Computer:
a valid configuration. a valid configuration.
Return: Return:
A Computer object if the path where pointing on a valid A Computer object.
file, False otherwise.
""" """
dumped_dict = xml_marshaller.loads(open(path_to_xml).read()) dumped_dict = xml_marshaller.loads(open(path_to_xml).read())
...@@ -271,6 +262,7 @@ class Computer: ...@@ -271,6 +262,7 @@ class Computer:
addr = dumped_dict['address'], addr = dumped_dict['address'],
netmask = dumped_dict['netmask'], netmask = dumped_dict['netmask'],
ipv6_interface=ipv6_interface, ipv6_interface=ipv6_interface,
software_user=dumped_dict.get('software_user', 'slapsoft'),
) )
for partition_dict in dumped_dict['partition_list']: for partition_dict in dumped_dict['partition_list']:
...@@ -312,8 +304,8 @@ class Computer: ...@@ -312,8 +304,8 @@ class Computer:
else: else:
os.chmod(path, 0755) os.chmod(path, 0755)
# own self.software_root by slapsoft # own self.software_root by software user
slapsoft = User('slapsoft') slapsoft = User(self.software_user)
slapsoft.path = self.software_root slapsoft.path = self.software_root
if alter_user: if alter_user:
slapsoft.create() slapsoft.create()
...@@ -363,16 +355,20 @@ class Computer: ...@@ -363,16 +355,20 @@ class Computer:
partition.address_list = [] partition.address_list = []
if len(old_partition_address_list) != 2: if len(old_partition_address_list) != 2:
raise ValueError('There should be exactly 2 stored addresses') raise ValueError('There should be exactly 2 stored addresses')
if not any([netaddr.valid_ipv6(q['addr']) for q in old_partition_address_list]): if not any([netaddr.valid_ipv6(q['addr'])
for q in old_partition_address_list]):
raise ValueError('Not valid ipv6 addresses loaded') raise ValueError('Not valid ipv6 addresses loaded')
if not any([netaddr.valid_ipv4(q['addr']) for q in old_partition_address_list]): if not any([netaddr.valid_ipv4(q['addr'])
for q in old_partition_address_list]):
raise ValueError('Not valid ipv6 addresses loaded') raise ValueError('Not valid ipv6 addresses loaded')
for address in old_partition_address_list: for address in old_partition_address_list:
if netaddr.valid_ipv6(address['addr']): if netaddr.valid_ipv6(address['addr']):
partition.address_list.append(self.bridge.addAddr(address['addr'], partition.address_list.append(self.bridge.addAddr(
address['netmask'])) address['addr'],
address['netmask']))
elif netaddr.valid_ipv4(address['addr']): elif netaddr.valid_ipv4(address['addr']):
partition.address_list.append(self.bridge.addIPv4LocalAddress(address['addr'])) partition.address_list.append(self.bridge.addIPv4LocalAddress(
address['addr']))
else: else:
raise ValueError('Address %r is incorrect' % address['addr']) raise ValueError('Address %r is incorrect' % address['addr'])
finally: finally:
...@@ -382,7 +378,7 @@ class Computer: ...@@ -382,7 +378,7 @@ class Computer:
except IndexError: except IndexError:
pass pass
class Partition: class Partition(object):
"Represent a computer partition" "Represent a computer partition"
def __init__(self, reference, path, user, address_list, tap): def __init__(self, reference, path, user, address_list, tap):
...@@ -406,8 +402,8 @@ class Partition: ...@@ -406,8 +402,8 @@ class Partition:
def createPath(self, alter_user=True): def createPath(self, alter_user=True):
""" """
Create the directory of the partition, assign to the partition user and give Create the directory of the partition, assign to the partition user and
it the 750 permission. In case if path exists just modifies it. give it the 750 permission. In case if path exists just modifies it.
""" """
self.path = os.path.abspath(self.path) self.path = os.path.abspath(self.path)
...@@ -419,8 +415,9 @@ class Partition: ...@@ -419,8 +415,9 @@ class Partition:
os.chown(self.path, owner_pw.pw_uid, owner_pw.pw_gid) os.chown(self.path, owner_pw.pw_uid, owner_pw.pw_gid)
os.chmod(self.path, 0750) os.chmod(self.path, 0750)
class User: class User(object):
"User: represent and manipulate a user on the system." "User: represent and manipulate a user on the system."
path = None
def __init__(self, user_name, additional_group_list=None): def __init__(self, user_name, additional_group_list=None):
""" """
...@@ -452,7 +449,8 @@ class User: ...@@ -452,7 +449,8 @@ class User:
except KeyError: except KeyError:
callAndRead(['groupadd', self.name]) callAndRead(['groupadd', self.name])
user_parameter_list = ['-d', self.path, '-g', self.name, '-s', '/bin/false'] user_parameter_list = ['-d', self.path, '-g', self.name, '-s',
'/bin/false']
if self.additional_group_list is not None: if self.additional_group_list is not None:
user_parameter_list.extend(['-G', ','.join(self.additional_group_list)]) user_parameter_list.extend(['-G', ','.join(self.additional_group_list)])
user_parameter_list.append(self.name) user_parameter_list.append(self.name)
...@@ -486,7 +484,7 @@ import fcntl ...@@ -486,7 +484,7 @@ import fcntl
import errno import errno
import threading import threading
class Tap: class Tap(object):
"Tap represent a tap interface on the system" "Tap represent a tap interface on the system"
IFF_TAP = 0x0002 IFF_TAP = 0x0002
TUNSETIFF = 0x400454ca TUNSETIFF = 0x400454ca
...@@ -496,7 +494,6 @@ class Tap: ...@@ -496,7 +494,6 @@ class Tap:
""" """
Attributes: Attributes:
tap_name: String, the name of the tap interface. tap_name: String, the name of the tap interface.
user: User, the owner of the tap interface.
""" """
self.name = str(tap_name) self.name = str(tap_name)
...@@ -558,9 +555,6 @@ class Tap: ...@@ -558,9 +555,6 @@ class Tap:
def createWithOwner(self, owner, attach_to_tap=False): def createWithOwner(self, owner, attach_to_tap=False):
""" """
Create a tap interface on the system. Create a tap interface on the system.
Return:
True: Everything went right.
""" """
# some systems does not have -p switch for tunctl # some systems does not have -p switch for tunctl
...@@ -568,20 +562,19 @@ class Tap: ...@@ -568,20 +562,19 @@ class Tap:
check_file = '/sys/devices/virtual/net/%s/owner' % self.name check_file = '/sys/devices/virtual/net/%s/owner' % self.name
owner_id = None owner_id = None
if os.path.exists(check_file): if os.path.exists(check_file):
owner_id = open(check_file).read().strip()
try: try:
owner_id = int(open(check_file).read().strip()) owner_id = int(owner_id)
except Exception: except ValueError:
pass pass
if (owner_id is None) or (owner_id != pwd.getpwnam(owner.name).pw_uid): if owner_id != pwd.getpwnam(owner.name).pw_uid:
callAndRead(['tunctl', '-t', self.name, '-u', owner.name]) callAndRead(['tunctl', '-t', self.name, '-u', owner.name])
callAndRead(['ip', 'link', 'set', self.name, 'up']) callAndRead(['ip', 'link', 'set', self.name, 'up'])
if attach_to_tap: if attach_to_tap:
threading.Thread(target=self.attach).start() threading.Thread(target=self.attach).start()
return True class Bridge(object):
class Bridge:
"Bridge represent a bridge on the system" "Bridge represent a bridge on the system"
def __init__(self, name, ipv4_local_network, ipv6_interface=None): def __init__(self, name, ipv4_local_network, ipv6_interface=None):
...@@ -596,14 +589,17 @@ class Bridge: ...@@ -596,14 +589,17 @@ class Bridge:
# Attach to TAP network interface, only if the bridge interface does not # Attach to TAP network interface, only if the bridge interface does not
# report carrier # report carrier
returncode, result = callAndRead(['ip', 'addr', 'list', self.name]) _, result = callAndRead(['ip', 'addr', 'list', self.name])
self.attach_to_tap = 'DOWN' in result.split('\n', 1)[0] self.attach_to_tap = 'DOWN' in result.split('\n', 1)[0]
def __getinitargs__(self): def __getinitargs__(self):
return (self.name,) return (self.name,)
def getIPv4LocalAddressList(self): def getIPv4LocalAddressList(self):
"""Returns currently configured local IPv4 addresses which are in ipv4_local_network""" """
Returns currently configured local IPv4 addresses which are in
ipv4_local_network
"""
if not socket.AF_INET in netifaces.ifaddresses(self.name): if not socket.AF_INET in netifaces.ifaddresses(self.name):
return [] return []
return [dict(addr=q['addr'], netmask=q['netmask']) for q in return [dict(addr=q['addr'], netmask=q['netmask']) for q in
...@@ -618,8 +614,9 @@ class Bridge: ...@@ -618,8 +614,9 @@ class Bridge:
else: else:
interface_name = self.name interface_name = self.name
try: try:
address_list = [q for q in netifaces.ifaddresses(interface_name)[socket.AF_INET6] address_list = [q
if isGlobalScopeAddress(q['addr'].split('%')[0])] for q in netifaces.ifaddresses(interface_name)[socket.AF_INET6]
if isGlobalScopeAddress(q['addr'].split('%')[0])]
except KeyError: except KeyError:
raise ValueError("%s must have at least one IPv6 address assigned" % \ raise ValueError("%s must have at least one IPv6 address assigned" % \
interface_name) interface_name)
...@@ -635,7 +632,7 @@ class Bridge: ...@@ -635,7 +632,7 @@ class Bridge:
def getInterfaceList(self): def getInterfaceList(self):
"""Returns list of interfaces already present on bridge""" """Returns list of interfaces already present on bridge"""
interface_list = [] interface_list = []
returncode, result = callAndRead(['brctl', 'show']) _, result = callAndRead(['brctl', 'show'])
in_bridge = False in_bridge = False
for line in result.split('\n'): for line in result.split('\n'):
if len(line.split()) > 1: if len(line.split()) > 1:
...@@ -685,16 +682,18 @@ class Bridge: ...@@ -685,16 +682,18 @@ class Bridge:
if interface != interface_name: if interface != interface_name:
address_dict = netifaces.ifaddresses(interface) address_dict = netifaces.ifaddresses(interface)
if af in address_dict: if af in address_dict:
if address in [q['addr'].split('%')[0] for q in address_dict[af]]: if address in [q['addr'].split('%')[0] for q in address_dict[af]]:
return False return False
if not af in netifaces.ifaddresses(interface_name) or not address in [q['addr'].split('%')[0] for q in netifaces.ifaddresses(interface_name)[af]]: if not af in netifaces.ifaddresses(interface_name) \
or not address in [q['addr'].split('%')[0]
for q in netifaces.ifaddresses(interface_name)[af]]:
# add an address # add an address
callAndRead(['ip', 'addr', 'add', address_string, 'dev', interface_name]) callAndRead(['ip', 'addr', 'add', address_string, 'dev', interface_name])
# wait few moments # wait few moments
time.sleep(2) time.sleep(2)
# check existence on interface # check existence on interface
returncode, result = callAndRead(['ip', 'addr', 'list', interface_name]) _, result = callAndRead(['ip', 'addr', 'list', interface_name])
for l in result.split('\n'): for l in result.split('\n'):
if address in l: if address in l:
if 'tentative' in l: if 'tentative' in l:
...@@ -714,7 +713,8 @@ class Bridge: ...@@ -714,7 +713,8 @@ class Bridge:
while try_num > 0: while try_num > 0:
addr = random.choice([q for q in netaddr.glob_to_iprange( addr = random.choice([q for q in netaddr.glob_to_iprange(
netaddr.cidr_to_glob(self.ipv4_local_network))]).format() netaddr.cidr_to_glob(self.ipv4_local_network))]).format()
if dict(addr=addr, netmask=netmask) not in self.getIPv4LocalAddressList(): if dict(addr=addr, netmask=netmask) not in \
self.getIPv4LocalAddressList():
# Checking the validity of the IPv6 address # Checking the validity of the IPv6 address
if self._addSystemAddress(addr, netmask, False): if self._addSystemAddress(addr, netmask, False):
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
...@@ -729,10 +729,10 @@ class Bridge: ...@@ -729,10 +729,10 @@ class Bridge:
if addr is None: if addr is None:
return self._generateRandomIPv4Address(netmask) return self._generateRandomIPv4Address(netmask)
elif dict(addr=addr, netmask=netmask) not in local_address_list: elif dict(addr=addr, netmask=netmask) not in local_address_list:
if self._addSystemAddress(addr, netmask, False): if self._addSystemAddress(addr, netmask, False):
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
else: else:
return self._generateRandomIPv4Address(netmask) return self._generateRandomIPv4Address(netmask)
else: else:
# confirmed to be configured # confirmed to be configured
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
...@@ -743,8 +743,9 @@ class Bridge: ...@@ -743,8 +743,9 @@ class Bridge:
If addr is specified and exists already on bridge does nothing. If addr is specified and exists already on bridge does nothing.
If addr is specified and does not exists on bridge, tries to add given address. If addr is specified and does not exists on bridge, tries to add given
In case if it is not possible (ex. because network changed) calculates new address. address. If it is not possible (ex. because network changed) calculates new
address.
Args: Args:
addr: Wished address to be added to bridge. addr: Wished address to be added to bridge.
...@@ -779,7 +780,8 @@ class Bridge: ...@@ -779,7 +780,8 @@ class Bridge:
# same netmask, so there is a chance to add good one # same netmask, so there is a chance to add good one
bridge_network = netaddr.ip.IPNetwork('%s/%s' % (address_dict['addr'], bridge_network = netaddr.ip.IPNetwork('%s/%s' % (address_dict['addr'],
netmaskToPrefixIPv6(address_dict['netmask']))) netmaskToPrefixIPv6(address_dict['netmask'])))
requested_network = netaddr.ip.IPNetwork('%s/%s' % (addr, netmaskToPrefixIPv6(netmask))) requested_network = netaddr.ip.IPNetwork('%s/%s' % (addr,
netmaskToPrefixIPv6(netmask)))
if bridge_network.network == requested_network.network: if bridge_network.network == requested_network.network:
# same network, try to add # same network, try to add
if self._addSystemAddress(addr, netmask): if self._addSystemAddress(addr, netmask):
...@@ -790,9 +792,11 @@ class Bridge: ...@@ -790,9 +792,11 @@ class Bridge:
try_num = 10 try_num = 10
netmask = address_dict['netmask'] netmask = address_dict['netmask']
while try_num > 0: while try_num > 0:
addr = ':'.join(address_dict['addr'].split(':')[:-1] + ['%x' % random.randint(1, 65000)]) addr = ':'.join(address_dict['addr'].split(':')[:-1] + ['%x' % (
random.randint(1, 65000), )])
socket.inet_pton(socket.AF_INET6, addr) socket.inet_pton(socket.AF_INET6, addr)
if dict(addr=addr, netmask=netmask) not in self.getGlobalScopeAddressList(): if dict(addr=addr, netmask=netmask) not in \
self.getGlobalScopeAddressList():
# Checking the validity of the IPv6 address # Checking the validity of the IPv6 address
if self._addSystemAddress(addr, netmask): if self._addSystemAddress(addr, netmask):
return dict(addr=addr, netmask=netmask) return dict(addr=addr, netmask=netmask)
...@@ -859,133 +863,153 @@ class Parser(OptionParser): ...@@ -859,133 +863,153 @@ class Parser(OptionParser):
return options, args[0] return options, args[0]
def run(config): def run(config):
try: # Define the computer
# Define the computer if config.input_definition_file:
if config.input_definition_file: filepath = os.path.abspath(config.input_definition_file)
filepath = os.path.abspath(config.input_definition_file) config.logger.info('Using definition file %r' % filepath)
config.logger.info('Using definition file %r' % filepath) computer_definition = ConfigParser.RawConfigParser({
computer_definition = ConfigParser.RawConfigParser() 'software_user': 'slapsoft',
computer_definition.read(filepath) })
bridge = None computer_definition.read(filepath)
address = None bridge = None
netmask = None address = None
if computer_definition.has_option('computer', 'address'): netmask = None
address, netmask = computer_definition.get('computer', 'address').split('/') if computer_definition.has_option('computer', 'address'):
if config.alter_network and config.bridge_name is not None \ address, netmask = computer_definition.get('computer',
and config.ipv4_local_network is not None: 'address').split('/')
bridge = Bridge(config.bridge_name, config.ipv4_local_network, if config.alter_network and config.bridge_name is not None \
and config.ipv4_local_network is not None:
bridge = Bridge(config.bridge_name, config.ipv4_local_network,
config.ipv6_interface)
computer = Computer(
reference=config.computer_id,
bridge=bridge,
addr=address,
netmask=netmask,
ipv6_interface=config.ipv6_interface,
software_user=computer_definition.get('computer', 'software_user'),
)
partition_list = []
for partition_number in range(int(config.partition_amount)):
section = 'partition_%s' % partition_number
user = User(computer_definition.get(section, 'user'))
address_list = []
for a in computer_definition.get(section, 'address').split():
address, netmask = a.split('/')
address_list.append(dict(addr=address, netmask=netmask))
tap = Tap(computer_definition.get(section, 'network_interface'))
partition_list.append(Partition(reference=computer_definition.get(
section, 'pathname'),
path=os.path.join(config.instance_root, computer_definition.get(
section, 'pathname')),
user=user,
address_list=address_list,
tap=tap,
))
computer.partition_list = partition_list
else:
# no definition file, figure out computer
if os.path.exists(config.computer_xml):
config.logger.info('Loading previous computer data from %r' % (
config.computer_xml, ))
computer = Computer.load(config.computer_xml,
reference=config.computer_id, ipv6_interface=config.ipv6_interface)
# Connect to the bridge interface defined by the configuration
computer.bridge = Bridge(config.bridge_name, config.ipv4_local_network,
config.ipv6_interface) config.ipv6_interface)
computer = Computer(
reference=config.computer_id,
bridge=bridge,
addr=address,
netmask=netmask,
ipv6_interface=config.ipv6_interface
)
partition_list = []
for partition_number in range(int(config.partition_amount)):
section = 'partition_%s' % partition_number
user = User(computer_definition.get(section, 'user'))
address_list = []
for a in computer_definition.get(section, 'address').split():
address, netmask = a.split('/')
address_list.append(dict(addr=address, netmask=netmask))
tap = Tap(computer_definition.get(section, 'network_interface'))
partition_list.append(Partition(reference=computer_definition.get(section, 'pathname'),
path=os.path.join(config.instance_root, computer_definition.get(section, 'pathname')),
user=user,
address_list=address_list,
tap=tap,
))
computer.partition_list = partition_list
else: else:
# no definition file, figure out computer # If no pre-existent configuration found, creating a new computer object
if os.path.exists(config.computer_xml): config.logger.warning('Creating new data computer with id %r' % (
config.logger.info('Loading previous computer data from %r' % config.computer_xml) config.computer_id, ))
computer = Computer.load(config.computer_xml, reference=config.computer_id, ipv6_interface=config.ipv6_interface) computer = Computer(
# Connect to the bridge interface defined by the configuration reference=config.computer_id,
computer.bridge = Bridge(config.bridge_name, config.ipv4_local_network, bridge=Bridge(config.bridge_name, config.ipv4_local_network,
config.ipv6_interface) config.ipv6_interface),
else: addr=None,
# If no pre-existent configuration found, creating a new computer object netmask=None,
config.logger.warning('Creating new data computer with id %r' % config.computer_id) ipv6_interface=config.ipv6_interface,
computer = Computer( software_user=config.software_user,
reference=config.computer_id, )
bridge=Bridge(config.bridge_name, config.ipv4_local_network,
config.ipv6_interface),
addr=None,
netmask=None,
ipv6_interface=config.ipv6_interface
)
partition_amount = int(config.partition_amount)
existing_partition_amount = len(computer.partition_list)
if existing_partition_amount > partition_amount:
raise ValueError('Requested amount of computer partitions (%s) is lower '
'then already configured (%s), cannot continue' % (partition_amount,
len(computer.partition_list)))
config.logger.info('Adding %s new partitions' %
(partition_amount-existing_partition_amount))
for nb_iter in range(existing_partition_amount, partition_amount):
# add new ones
user = User("%s%s" % (config.user_base_name, nb_iter))
tap = Tap("%s%s" % (config.tap_base_name, nb_iter))
path = os.path.join(config.instance_root, "%s%s" % (
config.partition_base_name, nb_iter))
computer.partition_list.append(
Partition(
reference="%s%s" % (config.partition_base_name, nb_iter),
path=path,
user=user,
address_list=None,
tap=tap,
))
computer.instance_root = config.instance_root
computer.software_root = config.software_root
config.logger.info('Updating computer')
address = computer.getAddress()
computer.address = address['addr']
computer.netmask = address['netmask']
if config.output_definition_file:
computer_definition = ConfigParser.RawConfigParser()
computer_definition.add_section('computer')
if computer.address is not None and computer.netmask is not None:
computer_definition.set('computer', 'address', '/'.join([computer.address, computer.netmask]))
partition_number = 0
for partition in computer.partition_list:
section = 'partition_%s' % partition_number
computer_definition.add_section(section)
address_list = []
for address in partition.address_list:
address_list.append('/'.join([address['addr'], address['netmask']]))
computer_definition.set(section, 'address', ' '.join(address_list))
computer_definition.set(section, 'user', partition.user.name)
computer_definition.set(section, 'user', partition.user.name)
computer_definition.set(section, 'network_interface', partition.tap.name)
computer_definition.set(section, 'pathname', partition.reference)
partition_number += 1
filepath = os.path.abspath(config.output_definition_file)
computer_definition.write(open(filepath, 'w'))
config.logger.info('Stored computer definition in %r' % filepath)
computer.construct(alter_user=config.alter_user,
alter_network=config.alter_network)
# Dumping and sending to the erp5 the current configuration
if not config.dry_run:
computer.dump(config.computer_xml)
config.logger.info('Posting information to %r' % config.master_url)
computer.send(config)
except:
config.logger.exception('Uncaught exception:')
raise
class Config: partition_amount = int(config.partition_amount)
def checkRequiredBinary(self, binary_list): existing_partition_amount = len(computer.partition_list)
if existing_partition_amount > partition_amount:
raise ValueError('Requested amount of computer partitions (%s) is lower '
'then already configured (%s), cannot continue' % (partition_amount,
len(computer.partition_list)))
config.logger.info('Adding %s new partitions' %
(partition_amount-existing_partition_amount))
for nb_iter in range(existing_partition_amount, partition_amount):
# add new ones
user = User("%s%s" % (config.user_base_name, nb_iter))
tap = Tap("%s%s" % (config.tap_base_name, nb_iter))
path = os.path.join(config.instance_root, "%s%s" % (
config.partition_base_name, nb_iter))
computer.partition_list.append(
Partition(
reference="%s%s" % (config.partition_base_name, nb_iter),
path=path,
user=user,
address_list=None,
tap=tap,
))
computer.instance_root = config.instance_root
computer.software_root = config.software_root
config.logger.info('Updating computer')
address = computer.getAddress()
computer.address = address['addr']
computer.netmask = address['netmask']
if config.output_definition_file:
computer_definition = ConfigParser.RawConfigParser()
computer_definition.add_section('computer')
if computer.address is not None and computer.netmask is not None:
computer_definition.set('computer', 'address', '/'.join(
[computer.address, computer.netmask]))
partition_number = 0
for partition in computer.partition_list:
section = 'partition_%s' % partition_number
computer_definition.add_section(section)
address_list = []
for address in partition.address_list:
address_list.append('/'.join([address['addr'], address['netmask']]))
computer_definition.set(section, 'address', ' '.join(address_list))
computer_definition.set(section, 'user', partition.user.name)
computer_definition.set(section, 'user', partition.user.name)
computer_definition.set(section, 'network_interface', partition.tap.name)
computer_definition.set(section, 'pathname', partition.reference)
partition_number += 1
filepath = os.path.abspath(config.output_definition_file)
computer_definition.write(open(filepath, 'w'))
config.logger.info('Stored computer definition in %r' % filepath)
computer.construct(alter_user=config.alter_user,
alter_network=config.alter_network)
# Dumping and sending to the erp5 the current configuration
if not config.dry_run:
computer.dump(config.computer_xml)
config.logger.info('Posting information to %r' % config.master_url)
computer.send(config)
class Config(object):
key_file = None
cert_file = None
alter_network = None
alter_user = None
computer_xml = None
logger = None
log_file = None
verbose = None
dry_run = None
console = None
software_user = None
@staticmethod
def checkRequiredBinary(binary_list):
missing_binary_list = [] missing_binary_list = []
for b in binary_list: for b in binary_list:
try: try:
...@@ -995,8 +1019,8 @@ class Config: ...@@ -995,8 +1019,8 @@ class Config:
except OSError: except OSError:
missing_binary_list.append(b) missing_binary_list.append(b)
if missing_binary_list: if missing_binary_list:
raise UsageError('Some required binaries are missing or not functional: %s'% raise UsageError('Some required binaries are missing or not '
','.join(missing_binary_list)) 'functional: %s' % (','.join(missing_binary_list), ))
def setConfig(self, option_dict, configuration_file_path): def setConfig(self, option_dict, configuration_file_path):
""" """
...@@ -1029,6 +1053,8 @@ class Config: ...@@ -1029,6 +1053,8 @@ class Config:
self.alter_network = 'True' self.alter_network = 'True'
if self.alter_user is None: if self.alter_user is None:
self.alter_user = 'True' self.alter_user = 'True'
if self.software_user is None:
self.software_user = 'slapsoft'
# set up logging # set up logging
self.logger = logging.getLogger("slapformat") self.logger = logging.getLogger("slapformat")
...@@ -1045,8 +1071,8 @@ class Config: ...@@ -1045,8 +1071,8 @@ class Config:
elif getattr(self, o).lower() == 'false': elif getattr(self, o).lower() == 'false':
setattr(self, o, False) setattr(self, o, False)
else: else:
message = 'Option %r needs to be "True" or "False", wrong value: %r' % ( message = 'Option %r needs to be "True" or "False", wrong value: ' \
o, getattr(self, o)) '%r' % (o, getattr(self, o))
self.logger.error(message) self.logger.error(message)
raise UsageError(message) raise UsageError(message)
...@@ -1076,7 +1102,8 @@ class Config: ...@@ -1076,7 +1102,8 @@ class Config:
os.path.dirname(self.log_file), self.log_file)) os.path.dirname(self.log_file), self.log_file))
else: else:
file_handler = logging.FileHandler(self.log_file) file_handler = logging.FileHandler(self.log_file)
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) file_handler.setFormatter(logging.Formatter("%(asctime)s - "
"%(name)s - %(levelname)s - %(message)s"))
self.logger.addHandler(file_handler) self.logger.addHandler(file_handler)
self.logger.info('Configured logging to file %r' % self.log_file) self.logger.info('Configured logging to file %r' % self.log_file)
# Check mandatory options # Check mandatory options
...@@ -1100,43 +1127,47 @@ def main(*args): ...@@ -1100,43 +1127,47 @@ def main(*args):
"Run default configuration." "Run default configuration."
global os global os
global callAndRead global callAndRead
global pwd
real_callAndRead = callAndRead real_callAndRead = callAndRead
usage = "usage: %s [options] CONFIGURATION_FILE" % sys.argv[0] usage = "usage: %s [options] CONFIGURATION_FILE" % sys.argv[0]
# Parse arguments
options, configuration_file_path = Parser(usage=usage).check_args(args)
config = Config()
try: try:
# Parse arguments
options, configuration_file_path = Parser(usage=usage).check_args(args)
config = Config()
config.setConfig(options, configuration_file_path) config.setConfig(options, configuration_file_path)
os = OS(config)
if config.dry_run:
def dry_callAndRead(argument_list, raise_on_error=True):
if argument_list == ['brctl', 'show']:
return real_callAndRead(argument_list, raise_on_error)
else:
return 0, ''
callAndRead = dry_callAndRead
real_addSystemAddress = Bridge._addSystemAddress
def fake_addSystemAddress(*args, **kw):
real_addSystemAddress(*args, **kw)
# Fake success
return True
Bridge._addSystemAddress = fake_addSystemAddress
def fake_getpwnam(user):
class result:
pw_uid = 12345
pw_gid = 54321
return result
pwd.getpwnam = fake_getpwnam
else:
dry_callAndRead = real_callAndRead
if config.verbose:
def logging_callAndRead(argument_list, raise_on_error=True):
config.logger.debug(' '.join(argument_list))
return dry_callAndRead(argument_list, raise_on_error)
callAndRead = logging_callAndRead
run(config)
except UsageError, err: except UsageError, err:
print >>sys.stderr, err.msg print >>sys.stderr, err.message
print >>sys.stderr, "For help use --help" print >>sys.stderr, "For help use --help"
sys.exit(1)
os = OS(config)
if config.dry_run:
def dry_callAndRead(argument_list, raise_on_error=True):
if argument_list == ['brctl', 'show']:
return real_callAndRead(argument_list, raise_on_error)
else:
return 0, ''
callAndRead = dry_callAndRead
real_addSystemAddress = Bridge._addSystemAddress
def fake_addSystemAddress(*args, **kw):
real_addSystemAddress(*args, **kw)
# Fake success
return True
Bridge._addSystemAddress = fake_addSystemAddress
def fake_getpwnam(user):
class result(object):
pw_uid = 12345
pw_gid = 54321
return result
pwd.getpwnam = fake_getpwnam
else:
dry_callAndRead = real_callAndRead
if config.verbose:
def logging_callAndRead(argument_list, raise_on_error=True):
config.logger.debug(' '.join(argument_list))
return dry_callAndRead(argument_list, raise_on_error)
callAndRead = logging_callAndRead
try:
run(config)
except:
config.logger.exception('Uncaught exception:')
raise
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