Commit b38bf507 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_cloud: Extent *_slap_interface_workflow for projects

   - Include person.requestProject API on person_slap_interface_workflow
   - Include project_slap_interface_workflow on Projects
parent a580f609
......@@ -19,6 +19,10 @@
<type>Person</type>
<workflow>person_slap_interface_workflow</workflow>
</chain>
<chain>
<type>Project</type>
<workflow>project_slap_interface_workflow</workflow>
</chain>
<chain>
<type>Slave Instance</type>
<workflow>edit_workflow, instance_slap_interface_workflow, item_workflow, slapos_cloud_interaction_workflow</workflow>
......
......@@ -32,6 +32,12 @@
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
......
person = state_change['object']
portal = person.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
project_title = kwargs['project_title']
except KeyError:
raise TypeError, "Person_requestProject takes exactly 1 argument"
tag = "%s_%s_ProjectInProgress" % (person.getUid(),
project_title)
if (portal.portal_activities.countMessageWithTag(tag) > 0):
# The software instance is already under creation but can not be fetched from catalog
# As it is not possible to fetch informations, it is better to raise an error
raise NotImplementedError(tag)
project_portal_type = "Project"
project_list = portal.portal_catalog.portal_catalog(
portal_type=project_portal_type, title=project_title, limit=2)
if len(project_list) == 2:
raise NotImplementedError
elif len(project_list) == 1:
context.REQUEST.set("project_relative_url", project_list[0].getRelativeUrl())
context.REQUEST.set("project_reference", project_list[0].getReference())
else:
module = portal.getDefaultModule(portal_type=project_portal_type)
project = module.newContent(
portal_type=project_portal_type,
title=project_title,
destination_decision_value=person,
activate_kw={'tag': tag}
)
context.REQUEST.set("project_relative_url", project.getRelativeUrl())
context.REQUEST.set("project_reference", project.getReference())
project.approveRegistration()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Person_requestProject</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Person_requestProject</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -17,10 +17,17 @@
<value>
<tuple>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
......
......@@ -2,61 +2,61 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interaction Workflow Interaction" module="erp5.portal_type"/>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>categories</string> </key>
<key> <string>action</string> </key>
<value>
<tuple>
<string>before_commit_script/portal_workflow/slapos_erp5_interaction_workflow/script_Project_validateAndAssign</string>
</tuple>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interaction_Project_setDestinationDecision</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interaction Workflow Interaction</string> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>Project</string>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
<string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_requestProject</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<key> <string>description</string> </key>
<value>
<tuple/>
<none/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>trigger_method_id</string> </key>
<key> <string>icon</string> </key>
<value>
<tuple>
<string>_setDestinationDecision*</string>
</tuple>
<none/>
</value>
</item>
<item>
<key> <string>trigger_once_per_transaction</string> </key>
<value> <int>0</int> </value>
<key> <string>id</string> </key>
<value> <string>transition_request_project</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Project</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source/portal_workflow/project_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>project_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow</string> </value>
</item>
<item>
<key> <string>state_variable</string> </key>
<value> <string>slap_state</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Project Slap Interface Workflow</string> </value>
</item>
<item>
<key> <string>workflow_managed_permission</string> </key>
<value>
<tuple/>
</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="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
project = state_change['object']
portal = project.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
token_id = kwargs['invitation_token']
except KeyError:
raise TypeError("Project_acceptInvitation takes exactly 1 argument")
try:
invitation_token = portal.invitation_token_module[token_id]
except KeyError:
raise ValueError("The Invitation Token can't be found, please review the URL.")
if person is None:
message_str = "Please login before access the invitation link."
raise ValueError(message_str)
if invitation_token.getPortalType() != "Invitation Token":
message_str = "The Invitation Token can't be found, please review the URL."
raise ValueError(message_str)
if invitation_token.getValidationState() != "validated":
message_str = "The Invitation Token was already used and it cannot be reused, please ask a new one."
raise ValueError(message_str)
if invitation_token.getSourceValue() == person:
message_str = "Invitation Token cannot be used by the same user that generated the token!"
raise ValueError(message_str)
for assignment in person.objectValues(portal_type="Assignment"):
if assignment.getDestinationProject() == project.getRelativeUrl() and \
assignment.getValidationState() == "open":
invitation_token.invalidate(comment="User already has assignment to the Person")
break
if invitation_token.getValidationState() == "validated":
person.newContent(
title="Assigment for Project %s" % project.getTitle(),
portal_type="Assignment",
destination_project_value=project).open()
invitation_token.invalidate()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</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>_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>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Project_acceptInvitation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Project_acceptInvitation</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -12,10 +12,14 @@ if project.getReference() in [None, ""]:
id_generator='uid', default=1)
project.setReference(reference)
project.setStartDate(DateTime())
project.validate()
user_id = project.Base_getOwnerId()
# Get the user id of the context owner.
local_role_list = project.get_local_roles()
for group, role_list in local_role_list:
if 'Owner' in role_list:
user_id = group
break
person = portal.portal_catalog.getResultValue(user_id=user_id)
if person is None:
......@@ -31,4 +35,7 @@ for assignment in person.objectValues(portal_type="Assignment"):
person.newContent(
title="Assigment for Project %s" % project.getTitle(),
portal_type="Assignment",
destination_project_value=project).open()
destination_project=project.getRelativeUrl()).open()
project.edit(start_date=DateTime())
project.validate()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</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>_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>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Project_approveRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Project_approveRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Project_checkConsistency</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
project = state_change['object']
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
request_method = "POST"
script_name = "Project_acceptInvitation"
web_site = context.getWebSiteValue()
if web_site is None:
web_site = portal
request_url = "%s/%s/%s" % (web_site.absolute_url(), project.getRelativeUrl(), script_name)
# Maybe it would be better to use another portal_type
token = portal.invitation_token_module.newContent(
portal_type="Invitation Token",
source_value=person,
url_string=request_url,
url_method=request_method
)
token.validate()
context.REQUEST.set('request_token_id', token.getId())
context.REQUEST.set('request_token_url_string', request_url)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Project_generateInvitation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from zExceptions import Unauthorized
project = state_change['object']
portal = project.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
if person is None:
raise Unauthorized
if project.getDestinationDecision() == person.getRelativeUrl():
project.setDestinationDecision(None)
for assignment in person.objectValues(portal_type="Assignment"):
if assignment.getDestinationProject() == project.getRelativeUrl() and \
assignment.getValidationState() != 'closed':
assignment.close()
break
......@@ -60,9 +60,15 @@
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_Project_validateAndAssign</string> </value>
<value> <string>script_Project_leaveProject</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow State" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>destination/portal_workflow/project_slap_interface_workflow/transition_accept_invitation</string>
<string>destination/portal_workflow/project_slap_interface_workflow/transition_approve_registration</string>
<string>destination/portal_workflow/project_slap_interface_workflow/transition_leave_project</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>state_draft</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow State</string> </value>
</item>
<item>
<key> <string>state_permission_role_list_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>state_type</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</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>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>after_script/portal_workflow/project_slap_interface_workflow/script_Project_acceptInvitation</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_accept_invitation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Accept Invitation</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="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/project_slap_interface_workflow/script_Project_checkConsistency</string>
<string>after_script/portal_workflow/project_slap_interface_workflow/script_Project_approveRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_approve_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Approve Registration</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="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>destination/portal_workflow/project_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_draft</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</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="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/project_slap_interface_workflow/script_Project_checkConsistency</string>
<string>after_script/portal_workflow/project_slap_interface_workflow/script_Project_leaveProject</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_leave_project</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Leave Project</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="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_action</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>transition/getReference|nothing</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The name of the user who performed the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_actor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>user/getUserName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Comments about the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_comment</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Error message if validation failed</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_history</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>portal type (use as filter for worklists)</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_portal_type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Time of the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_time</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getDateTime</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Compute Partition | compute_partition_slap_interface_workflow
Compute Node | compute_node_slap_interface_workflow
Compute Node | slapos_cloud_interaction_workflow
Compute Partition | compute_partition_slap_interface_workflow
Hosting Subscription | edit_workflow
Instance Tree | edit_workflow
Instance Tree | instance_slap_interface_workflow
Instance Tree | instance_tree_workflow
Person | person_slap_interface_workflow
Project | project_slap_interface_workflow
Slave Instance | edit_workflow
Slave Instance | instance_slap_interface_workflow
Slave Instance | item_workflow
......
audit_validation_workflow
compute_partition_slap_interface_workflow
compute_node_slap_interface_workflow
instance_tree_workflow
compute_partition_slap_interface_workflow
installation_slap_interface_workflow
instance_slap_interface_workflow
instance_tree_workflow
person_slap_interface_workflow
project_slap_interface_workflow
slapos_cloud_interaction_workflow
\ No newline at end of file
......@@ -77,7 +77,7 @@
</chain>
<chain>
<type>Project</type>
<workflow>local_permission_slapos_interaction_workflow, slapos_erp5_interaction_workflow</workflow>
<workflow>local_permission_slapos_interaction_workflow</workflow>
</chain>
<chain>
<type>Purchase Packing List</type>
......
......@@ -330,79 +330,6 @@ class TestSlapOSERP5InteractionWorkflowComputerNetworkSetReference(
self.assertEqual(computer_network.getSourceAdministration(),
None)
class TestSlapOSERP5InteractionWorkflowProjectSetDestination(
SlapOSTestCaseMixin):
def test_Project_validateAndAssign(self):
person = self.makePerson()
self.tic()
project = self.portal.project_module.newContent(
portal_type="Project"
)
project.setDestinationDecisionValue(person)
self.commit()
self.assertEqual(project.getValidationState(), "validated")
self.assertNotEqual(project.getStartDate(), None)
self.assertNotEqual(project.getReference(), None)
self.assertTrue(project.getReference().startswith("PROJ-"),
"%s don't start with PROJ-" % project.getReference())
def test_Project_validateAndAssign_with_owner(self):
person = self.makePerson(user=1)
self.tic()
assignment_amount = len(person.objectValues(portal_type="Assignment"))
self.login(person.getUserId())
project = self.portal.project_module.newContent(
portal_type="Project"
)
project.setDestinationDecisionValue(person)
self.commit()
self.assertEqual(project.getValidationState(), "validated")
self.assertNotEqual(project.getStartDate(), None)
self.assertNotEqual(project.getReference(), None)
self.assertTrue(project.getReference().startswith("PROJ-"),
"%s don't start with PROJ-" % project.getReference())
self.assertEqual(assignment_amount + 1,
len(person.objectValues(portal_type="Assignment")))
self.assertNotEqual([],
[i for i in person.objectValues(portal_type="Assignment")
if (i.getDestinationProjectValue() == project and i.getValidationState() == "open")])
def test_Project_validateAndAssign_with_assignment(self):
person = self.makePerson(user=1)
self.tic()
assignment_amount = len(person.objectValues(portal_type="Assignment"))
self.login(person.getUserId())
project = self.portal.project_module.newContent(
portal_type="Project"
)
person.newContent(
title="Assigment for Project %s" % project.getTitle(),
portal_type="Assignment",
destination_project_value=project)
self.tic()
project.setDestinationDecisionValue(person)
self.commit()
self.assertEqual(project.getValidationState(), "validated")
self.assertNotEqual(project.getStartDate(), None)
self.assertNotEqual(project.getReference(), None)
self.assertTrue(project.getReference().startswith("PROJ-"),
"%s don't start with PROJ-" % project.getReference())
self.assertEqual(assignment_amount + 1,
len(person.objectValues(portal_type="Assignment")))
self.assertNotEqual([],
[i for i in person.objectValues(portal_type="Assignment")
if (i.getDestinationProjectValue() == project and i.getValidationState() == "open")])
class TestSlapOSERP5InteractionWorkflowOrganisationSetRole(
SlapOSTestCaseMixin):
......@@ -494,4 +421,3 @@ class TestSlapOSERP5InteractionWorkflowOrganisationSetRole(
[i for i in person.objectValues(portal_type="Assignment")
if (i.getSubordinationValue() == organisation and i.getValidationState() == "open")])
Acknowledgement | local_permission_slapos_interaction_workflow
Cloud Contract | local_permission_slapos_interaction_workflow
Compute Node | local_permission_slapos_interaction_workflow
Compute Node | slapos_erp5_interaction_workflow
Computer Model | local_permission_slapos_interaction_workflow
Computer Network | local_permission_slapos_interaction_workflow
Computer Network | slapos_erp5_interaction_workflow
Compute Node | local_permission_slapos_interaction_workflow
Compute Node | slapos_erp5_interaction_workflow
Contract Invitation Token | edit_workflow
Contract Invitation Token | validation_workflow
Delivery Cell | -immobilisation_movement_interaction_workflow
......@@ -24,7 +24,6 @@ Payment Transaction | local_permission_slapos_interaction_workflow
Payzen Event | local_permission_slapos_interaction_workflow
Person | local_permission_slapos_interaction_workflow
Project | local_permission_slapos_interaction_workflow
Project | slapos_erp5_interaction_workflow
Purchase Packing List Cell | -immobilisation_movement_interaction_workflow
Purchase Packing List Line | -immobilisation_movement_interaction_workflow
Purchase Packing List | -immobilisation_movement_interaction_workflow
......
import json
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
request = context.REQUEST
response = request.RESPONSE
if person is None:
response.setStatus(403)
else:
request_kw = dict(project_title=title)
person.requestProject(**request_kw)
project = context.restrictedTraverse(context.REQUEST.get('project'))
return json.dumps({
"reference": project.getReference(),
"relative_url": project.getRelativeUrl()
})
<?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>_params</string> </key>
<value> <string>title</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_requestProject</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from zExceptions import Unauthorized
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
......@@ -15,43 +14,11 @@ def redirect(message, message_type):
"/#/?page=slap_notify_and_redirect&message_type=%s" % message_type + \
"&portal_status_message=%s" % context.Base_translateString(message))
if invitation_token is None:
message_str = "The Invitation Token is not present on the URL, please review the URL."
return redirect(message_str, "error")
if context.getPortalType() != "Project":
raise Unauthorized("Context is not an Project, please review your URL.")
try:
invitation_token = portal.invitation_token_module[invitation_token]
except KeyError:
message_str = "The Invitation Token can't be found, please review the URL."
return redirect(message_str, "error")
if invitation_token.getPortalType() != "Invitation Token":
message_str = "The Invitation Token can't be found, please review the URL."
return redirect(message_str, "error")
if invitation_token.getValidationState() != "validated":
message_str = "The Invitation Token was already used and it cannot be reused, please ask a new one."
return redirect(message_str, "error")
if invitation_token.getSourceValue() == person:
message_str = "Invitation Token cannot be used by the same user that generated the token!"
return redirect(message_str, "error")
for assignment in person.objectValues(portal_type="Assignment"):
if assignment.getDestinationProject() == context.getRelativeUrl():
invitation_token.invalidate(comment="User already has assignment to the Person")
message_str = "You sucessfully join a new project: %s." % context.getTitle()
return redirect(message_str, "success")
person.newContent(
title="Assigment for Project %s" % context.getTitle(),
portal_type="Assignment",
destination_project_value=context).open()
invitation_token.invalidate()
context.acceptInvitation(invitation_token)
except ValueError as e:
return redirect(context.Base_translateString(e), "error")
message_str = "You sucessfully join a new project: %s." % context.getTitle()
message_str = context.Base_translateString("You sucessfully join a new project: ")
message_str += context.getTitle()
return redirect(message_str, "success")
person = context.getPortalObject().portal_membership.getAuthenticatedMember().getUserValue()
for assignment in person.objectValues(portal_type="Assignment"):
if assignment.getDestinationProject() == context.getRelativeUrl():
assignment.close()
return
return context.leaveProject()
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