Commit 938d65ee authored by Romain Courteaud's avatar Romain Courteaud

slapos_subscription_request:

* subscription scenario needs project now
* project is needed when requesting an instance
* hardcode automated ledger category for the newly created sale packing list
* hardcode automated ledger category for the newly created accounting transactions
* automated ledger path
* add ledger to the accounting template
* only add a project assignment for the existing admin user
* create normal user with the project customer assignment
* update cdn subscription test
  project reference needed
* add project for chinese subscription
* project needed for scenario tests
* all Subscription/Trial object must be linked to a Project
* test: user need to be linked to a project
* propagate source project
* delivery/movement must use source_project instead of follow_up
* set source_project on event
* delivery/movement must use source_project instead of follow_up
* use source_project instead of follow_up
* use source_project instead of follow_up
* test set server allocation_scope/open
* Subscription COndition uses follow_up to link to the Project
* add missing source_project base category on Subscription Request
  XXX Subscription Request must inherit this from ticket instead of defining all of this manually
* Subscription COndition uses follow to link to Project
* also add destination_project on Subscription Request to ensure constraint can be triggered
* fix user account assignment creation from SubscriptionRequest
* create software product/release in test
* improve software product/release
* expect Sale Packing List to use a Software Product
* use Software Product as resource
* drop audit from Subscription Request
parent bb72fbe3
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSContractAlarm</string> </value> <value> <string>testSlapOSContractAlarm</string> </value>
...@@ -55,28 +49,13 @@ ...@@ -55,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <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> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -89,7 +68,7 @@ ...@@ -89,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -98,7 +77,7 @@ ...@@ -98,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
<string>source/organisation_module/slapos</string> <string>source/organisation_module/slapos</string>
<string>price_currency/currency_module/EUR</string> <string>price_currency/currency_module/EUR</string>
<string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string> <string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string>
<string>ledger/automated</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
<string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string> <string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string>
<string>resource/currency_module/CNY</string> <string>resource/currency_module/CNY</string>
<string>payment_mode/wechat</string> <string>payment_mode/wechat</string>
<string>ledger/automated</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
...@@ -95,6 +95,7 @@ ...@@ -95,6 +95,7 @@
<string>price_currency/currency_module/EUR</string> <string>price_currency/currency_module/EUR</string>
<string>resource/currency_module/EUR</string> <string>resource/currency_module/EUR</string>
<string>payment_mode/payzen</string> <string>payment_mode/payzen</string>
<string>ledger/automated</string>
<string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string> <string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string>
</tuple> </tuple>
</value> </value>
......
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
<value> <value>
<tuple> <tuple>
<string>source_section/organisation_module/slapos</string> <string>source_section/organisation_module/slapos</string>
<string>ledger/automated</string>
<string>source/organisation_module/slapos</string> <string>source/organisation_module/slapos</string>
<string>payment_mode/wechat</string> <string>payment_mode/wechat</string>
<string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string> <string>specialise/sale_trade_condition_module/slapos_aggregated_trade_condition</string>
......
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
<portal_type id="Subscription Request"> <portal_type id="Subscription Request">
<item>aggregate</item> <item>aggregate</item>
<item>causality</item> <item>causality</item>
<item>destination_project</item>
<item>destination_section</item> <item>destination_section</item>
<item>source</item> <item>source</item>
<item>source_project</item>
<item>source_section</item> <item>source_section</item>
<item>specialise</item> <item>specialise</item>
</portal_type> </portal_type>
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<item>InstanceTree</item> <item>InstanceTree</item>
<item>Price</item> <item>Price</item>
<item>SlapOSSubscriptionCondition</item> <item>SlapOSSubscriptionCondition</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SoftwareInstance</item> <item>SoftwareInstance</item>
<item>TextDocument</item> <item>TextDocument</item>
<item>Url</item> <item>Url</item>
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
<item>Person</item> <item>Person</item>
<item>Price</item> <item>Price</item>
<item>Reference</item> <item>Reference</item>
<item>SlaposSubscriptionRequestAuditConstraint</item> <item>SlapOSVirtualMasterSourceProjectConstraint</item>
<item>Task</item> <item>Task</item>
<item>Url</item> <item>Url</item>
<item>VariationRange</item> <item>VariationRange</item>
......
...@@ -9,6 +9,6 @@ ...@@ -9,6 +9,6 @@
</chain> </chain>
<chain> <chain>
<type>Subscription Request</type> <type>Subscription Request</type>
<workflow>audit_validation_workflow, edit_workflow, subscription_request_workflow</workflow> <workflow>edit_workflow, subscription_request_workflow</workflow>
</chain> </chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" 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>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SlaposSubscriptionRequestAuditConstraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</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="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>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Script 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>categories</string> </key>
<value>
<tuple>
<string>constraint_type/audit</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SubscriptionRequestCheckRelatedAccounting_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Script Constraint</string> </value>
</item>
<item>
<key> <string>script_id</string> </key>
<value> <string>SubscriptionRequest_checkRelatedAccounting</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>
...@@ -82,6 +82,7 @@ subscription_request = context.subscription_request_module.newContent( ...@@ -82,6 +82,7 @@ subscription_request = context.subscription_request_module.newContent(
quantity=user_input_dict["amount"], quantity=user_input_dict["amount"],
language=target_language, language=target_language,
specialise_value=subscription_condition, specialise_value=subscription_condition,
source_project_value=subscription_condition.getFollowUpValue()
) )
subscription_request.setDefaultEmailText(email) subscription_request.setDefaultEmailText(email)
......
...@@ -13,22 +13,22 @@ if person.getLanguage() in [None, ""]: ...@@ -13,22 +13,22 @@ if person.getLanguage() in [None, ""]:
person.setLanguage(context.getLanguage()) person.setLanguage(context.getLanguage())
# Should come from subscription condition probably or preference # Should come from subscription condition probably or preference
role_list = ['member', 'subscriber'] function_list = ['customer']
open_assignment_list = person.searchFolder(portal_type="Assignment", open_assignment_list = person.searchFolder(portal_type="Assignment",
validation_state="open") validation_state="open")
current_assignment_list = {} current_assignment_list = {}
for assignment in open_assignment_list: for assignment in open_assignment_list:
role = assignment.getRole() function = assignment.getFunction()
if role in current_assignment_list: if function in current_assignment_list:
current_assignment_list[role].append(assignment) current_assignment_list[function].append(assignment)
else: else:
current_assignment_list[role] = [assignment] current_assignment_list[function] = [assignment]
for role in role_list: for function in function_list:
if role in current_assignment_list: if function in current_assignment_list:
# Update assignment (Reset stop/start dates) # Update assignment (Reset stop/start dates)
for assignment in current_assignment_list[role]: for assignment in current_assignment_list[function]:
if assignment.getStartDate() is None or \ if assignment.getStartDate() is None or \
assignment.getStopDate() is None: assignment.getStopDate() is None:
assignment.update() assignment.update()
...@@ -40,8 +40,10 @@ for role in role_list: ...@@ -40,8 +40,10 @@ for role in role_list:
# Create assignment # Create assignment
assignment = person.newContent( assignment = person.newContent(
portal_type='Assignment', portal_type='Assignment',
title = '%s Assignment' % (role.capitalize()), title = '%s Assignment' % (function.capitalize()),
role = role) function = function,
destination_project=context.getSourceProject()
)
assignment.open(comment="Created by Subscription Request") assignment.open(comment="Created by Subscription Request")
...@@ -68,16 +70,6 @@ try: ...@@ -68,16 +70,6 @@ try:
except UnsupportedWorkflowMethod: except UnsupportedWorkflowMethod:
pass pass
person.edit(default_career_role_list=role_list)
default_career = getattr(person,'default_career',None)
# Try to validate the default career
try:
default_career.start(comment="Started by Subscription Request")
default_career.setStartDate(DateTime())
except UnsupportedWorkflowMethod:
pass
context.activate(activity='SQLQueue').SubscriptionRequest_sendAcceptedNotification(reference, password) context.activate(activity='SQLQueue').SubscriptionRequest_sendAcceptedNotification(reference, password)
context.order() context.order()
subscription_request = context
portal = context.getPortalObject()
translate = portal.Base_translateString
status_list = []
def addToStatusList(status_text, mapping):
status_list.append(translate(
status_text,
mapping=mapping
))
if not context.getSimulationState() in ("ordered", "confirmed", "started", "stopped", "delivered"):
return []
subscription_trade_condition = portal.sale_trade_condition_module.slapos_aggregated_subscription_trade_condition
#refund_service = portal.service_module.slapos_reservation_refund
sale_packing_list_list = portal.portal_catalog(
portal_type="Sale Packing List",
strict_causality_uid=subscription_request.getUid(),
strict_destination_uid=subscription_request.getDestinationSectionUid(),
strict_destination_section_uid=subscription_request.getDestinationSectionUid(),
strict_specialise_uid=subscription_trade_condition.getUid(),
simulation_state="delivered",
)
if sale_packing_list_list:
sale_invoice_list = portal.portal_catalog(
portal_type="Sale Invoice Transaction",
strict_causality_uid=[x.getUid() for x in sale_packing_list_list],
)
trade_condition = subscription_request.getSpecialiseValue().getSpecialiseValue()
subscription_currency = trade_condition.getPriceCurrency()
subscription_source_section = trade_condition.getSourceSection()
for sale_invoice in sale_invoice_list:
sale_invoice = sale_invoice.getObject()
if sale_invoice.getPriceCurrency() != subscription_currency:
addToStatusList(
"${invoice_relative_url} Sale Invoice currency ${invoice_currency} do not match subscription currency ${subscription_currency}",
{
"invoice_relative_url": sale_invoice.getRelativeUrl(),
"invoice_currency": sale_invoice.getPriceCurrency(),
"subscription_currency": subscription_currency,
}
)
if sale_invoice.getSourceSection() != subscription_source_section:
addToStatusList(
"${invoice_relative_url} Sale Invoice Source ${invoice_source_section} do not match subscription source section ${subscription_source_section}",
{
"invoice_relative_url": sale_invoice.getRelativeUrl(),
"invoice_source_section": sale_invoice.getSourceSection(),
"subscription_source_section": subscription_source_section,
}
)
if sale_invoice.getSimulationState() not in ("stopped", "delivered", "cancelled"):
addToStatusList(
"${invoice_relative_url} Sale Invoice in unexpected simulation state: ${invoice_simulation_state}",
{
"invoice_relative_url": sale_invoice.absolute_url(),
"invoice_simulation_state": sale_invoice.getSimulationState(),
}
)
return status_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>fixit=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SubscriptionRequest_checkRelatedAccounting</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -13,6 +13,7 @@ if current_invoice is None: ...@@ -13,6 +13,7 @@ if current_invoice is None:
invoice_template = portal.restrictedTraverse(template) invoice_template = portal.restrictedTraverse(template)
current_invoice = invoice_template.Base_createCloneDocument(batch_mode=1) current_invoice = invoice_template.Base_createCloneDocument(batch_mode=1)
assert current_invoice is not None assert current_invoice is not None
current_invoice.manage_delObjects([x for x in current_invoice.manage_delObjects([x for x in
current_invoice.contentIds() if x != "1"]) current_invoice.contentIds() if x != "1"])
current_invoice.edit( current_invoice.edit(
...@@ -38,6 +39,8 @@ if current_invoice is None: ...@@ -38,6 +39,8 @@ if current_invoice is None:
payment_transaction = portal.restrictedTraverse(payment) payment_transaction = portal.restrictedTraverse(payment)
current_invoice.edit( current_invoice.edit(
title="Reservation Fee", title="Reservation Fee",
ledger_value=portal.portal_categories.ledger.automated,
source_project_value=context.getSourceProjectValue(),
destination_value=context.getDestinationSection(), destination_value=context.getDestinationSection(),
destination_section_value=context.getDestinationSection(), destination_section_value=context.getDestinationSection(),
destination_decision_value=context.getDestinationSection(), destination_decision_value=context.getDestinationSection(),
......
...@@ -61,7 +61,9 @@ delivery.edit( ...@@ -61,7 +61,9 @@ delivery.edit(
causality_uid=context.getUid(), causality_uid=context.getUid(),
price_currency=sale_invoice_transaction.getPriceCurrency(), price_currency=sale_invoice_transaction.getPriceCurrency(),
source=sale_invoice_transaction.getSource(), source=sale_invoice_transaction.getSource(),
source_section=sale_invoice_transaction.getSourceSection() source_section=sale_invoice_transaction.getSourceSection(),
ledger_value=portal.portal_categories.ledger.automated,
source_project_value=sale_invoice_transaction.getSourceProjectValue(),
) )
line = delivery.newContent( line = delivery.newContent(
......
...@@ -17,7 +17,8 @@ request_kw = dict( ...@@ -17,7 +17,8 @@ request_kw = dict(
software_type=instance_tree.getSourceReference(), software_type=instance_tree.getSourceReference(),
instance_xml=instance_tree.getTextContent(), instance_xml=instance_tree.getTextContent(),
sla_xml=instance_tree.getSlaXml(), sla_xml=instance_tree.getSlaXml(),
shared=instance_tree.isRootSlave() shared=instance_tree.isRootSlave(),
project_reference=instance_tree.getFollowUpReference()
) )
if not context.SubscriptionRequest_testPaymentBalance(): if not context.SubscriptionRequest_testPaymentBalance():
......
...@@ -32,6 +32,7 @@ request_kw.update( ...@@ -32,6 +32,7 @@ request_kw.update(
sla_xml=subscription_condition.getSlaXml(default_xml).strip(), sla_xml=subscription_condition.getSlaXml(default_xml).strip(),
shared=bool(subscription_condition.getRootSlave(0)), shared=bool(subscription_condition.getRootSlave(0)),
state="started", state="started",
project_reference=subscription_condition.getFollowUpReference()
) )
person.requestSoftwareInstance(**request_kw) person.requestSoftwareInstance(**request_kw)
......
...@@ -33,6 +33,8 @@ if current_invoice is None: ...@@ -33,6 +33,8 @@ if current_invoice is None:
now = DateTime() now = DateTime()
current_payment.edit( current_payment.edit(
title="Payment for Reservation Fee", title="Payment for Reservation Fee",
ledger_value=portal.portal_categories.ledger.automated,
source_project_value=context.getSourceProjectValue(),
specialise_value=trade_condition, specialise_value=trade_condition,
destination_value=context.getDestinationSection(), destination_value=context.getDestinationSection(),
destination_section_value=context.getDestinationSection(), destination_section_value=context.getDestinationSection(),
......
...@@ -62,13 +62,14 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin ...@@ -62,13 +62,14 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin
# now instantiate it on compute_node and set some nice connection dict # now instantiate it on compute_node and set some nice connection dict
self.setServerOpenPersonal(subscription_server) self.setServerOpenPublic(subscription_server)
self.login(self.admin_user.getUserId()) self.login(self.admin_user.getUserId())
self.personRequestInstanceNotReady( self.personRequestInstanceNotReady(
software_release=self.subscription_condition.getUrlString(), software_release=self.subscription_condition.getUrlString(),
software_type=self.subscription_condition.getSourceReference(), software_type=self.subscription_condition.getSourceReference(),
partition_reference="InstanceForSlave%s" % self.new_id partition_reference="InstanceForSlave%s" % self.new_id,
project_reference=self.subscription_project.getReference()
) )
self.stepCallSlaposAllocateInstanceAlarm() self.stepCallSlaposAllocateInstanceAlarm()
...@@ -77,7 +78,8 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin ...@@ -77,7 +78,8 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin
self.personRequestInstance( self.personRequestInstance(
software_release=self.subscription_condition.getUrlString(), software_release=self.subscription_condition.getUrlString(),
software_type=self.subscription_condition.getSourceReference(), software_type=self.subscription_condition.getSourceReference(),
partition_reference="InstanceForSlave%s" % self.new_id partition_reference="InstanceForSlave%s" % self.new_id,
project_reference=self.subscription_project.getReference()
) )
# now instantiate it on compute_node and set some nice connection dict # now instantiate it on compute_node and set some nice connection dict
...@@ -85,7 +87,7 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin ...@@ -85,7 +87,7 @@ class TestSlapOSSubscriptionCDNScenarioMixin(TestSlapOSSubscriptionScenarioMixin
self.tic() self.tic()
self.login() self.login()
self.setServerOpenSubscription(subscription_server) #self.setServerOpenSubscription(subscription_server)
self.setAccessToMemcached(subscription_server) self.setAccessToMemcached(subscription_server)
self.tic() self.tic()
self.simulateSlapgridCP(subscription_server) self.simulateSlapgridCP(subscription_server)
......
...@@ -171,7 +171,7 @@ class testSlapOSSubscriptionDualOrganisationScenario(TestSlapOSSubscriptionScena ...@@ -171,7 +171,7 @@ class testSlapOSSubscriptionDualOrganisationScenario(TestSlapOSSubscriptionScena
name="ABC %s" % self.new_id name="ABC %s" % self.new_id
self.login() self.login()
self.createNormalUser(default_email_text, name, language) self.createNormalUser(default_email_text, name, language, self.subscription_project)
self.tic() self.tic()
......
...@@ -58,7 +58,7 @@ class testSlapOSSubscriptionPerUserTradeConditionScenario(TestSlapOSSubscription ...@@ -58,7 +58,7 @@ class testSlapOSSubscriptionPerUserTradeConditionScenario(TestSlapOSSubscription
name="ABC %s" % self.new_id name="ABC %s" % self.new_id
self.login() self.login()
self.createNormalUser(default_email_text, name, language) self.createNormalUser(default_email_text, name, language, self.subscription_project)
self.createCustomUserSaleTradeCondition(self.normal_user) self.createCustomUserSaleTradeCondition(self.normal_user)
self.tic() self.tic()
...@@ -144,7 +144,7 @@ class testSlapOSSubscriptionPerUserTradeConditionScenarioDetaxed(TestSlapOSSubsc ...@@ -144,7 +144,7 @@ class testSlapOSSubscriptionPerUserTradeConditionScenarioDetaxed(TestSlapOSSubsc
name="ABC %s" % self.new_id name="ABC %s" % self.new_id
self.login() self.login()
self.createNormalUser(default_email_text, name, language) self.createNormalUser(default_email_text, name, language, self.subscription_project)
self.createDetaxedUserSaleTradeCondition(self.normal_user) self.createDetaxedUserSaleTradeCondition(self.normal_user)
self.tic() self.tic()
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSSubscriptionPerUserTradeConditionScenario</string> </value> <value> <string>testSlapOSSubscriptionPerUserTradeConditionScenario</string> </value>
...@@ -61,28 +55,13 @@ ...@@ -61,28 +55,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <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> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -95,7 +74,7 @@ ...@@ -95,7 +74,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -104,7 +83,7 @@ ...@@ -104,7 +83,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -75,8 +75,10 @@ class TestSlapOSSubscriptionScenarioMixin(DefaultScenarioMixin): ...@@ -75,8 +75,10 @@ class TestSlapOSSubscriptionScenarioMixin(DefaultScenarioMixin):
slapos_pre_payment_template.\ slapos_pre_payment_template.\
updateLocalRolesOnSecurityGroups() updateLocalRolesOnSecurityGroups()
self.subscription_project = self.createProject()
# One user to create compute_nodes to deploy the subscription # One user to create compute_nodes to deploy the subscription
self.createAdminUser() self.createAdminUser(self.subscription_project)
self.cleanUpNotificationMessage() self.cleanUpNotificationMessage()
self.portal.portal_catalog.searchAndActivate( self.portal.portal_catalog.searchAndActivate(
portal_type='Active Process', portal_type='Active Process',
...@@ -177,37 +179,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -177,37 +179,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
notification_message.validate() notification_message.validate()
return notification_message return notification_message
def createAdminUser(self): def createNormalUser(self, email, name, language, project):
""" Create a Admin user, to manage compute_nodes and instances eventually """
admin_user_login = self.portal.portal_catalog.getResultValue(
portal_type="ERP5 Login",
reference="admin_user",
validation_state="validated"
)
if admin_user_login is None:
admin_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
admin_user.newContent(
portal_type="ERP5 Login",
reference="admin_user").validate()
admin_user.edit(
first_name="Admin User",
reference="Admin_user",
default_email_text="do_not_reply_to_admin@example.org",
)
for assignment in admin_user.contentValues(portal_type="Assignment"):
assignment.open()
admin_user.validate()
self.admin_user = admin_user
else:
self.admin_user = admin_user_login.getParentValue()
def createNormalUser(self, email, name, language):
""" Create a Normal user """ """ Create a Normal user """
normal_user_login = self.portal.portal_catalog.getResultValue( normal_user_login = self.portal.portal_catalog.getResultValue(
portal_type="ERP5 Login", portal_type="ERP5 Login",
...@@ -233,9 +205,16 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -233,9 +205,16 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
assignment.open() assignment.open()
normal_user.validate() normal_user.validate()
self.normal_user = normal_user
else: else:
self.normal_user = normal_user_login.getParentValue() normal_user = normal_user_login.getParentValue()
normal_user.newContent(
portal_type='Assignment',
destination_project_value=project,
function='customer'
).open()
self.normal_user = normal_user
self.normal_user.setLanguage(language) self.normal_user.setLanguage(language)
def createChineseSubscriptionCondition(self, slave=False): def createChineseSubscriptionCondition(self, slave=False):
...@@ -275,13 +254,40 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -275,13 +254,40 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
sla_xml='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>', sla_xml='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>',
text_content='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>', text_content='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>',
user_input={}, user_input={},
specialise_value=sale_trade_condition specialise_value=sale_trade_condition,
follow_up_value=self.subscription_project
) )
subscription_condition.validate() subscription_condition.validate()
self.tic() self.tic()
return subscription_condition return subscription_condition
def createSubscriptionCondition(self, slave=False): def createSubscriptionCondition(self, slave=False):
url_string = self.generateNewSoftwareReleaseUrl()
# Create Software Product/Release
software_product = self.portal.software_product_module.newContent(
portal_type="Software Product",
title="TestSoftwareProduct",
follow_up_value=self.subscription_project,
use='trade/sale',
quantity_unit='unit/piece',
product_line='cloud/subscription',
base_contribution_list=[
'base_amount/invoicing/discounted',
'base_amount/invoicing/taxable'
]
)
software_product.validate()
software_release = self.portal.software_release_module.newContent(
portal_type="Software Release",
title="TestSoftwareRelease",
url_string=url_string,
aggregate_value=software_product,
follow_up_value=self.subscription_project
)
software_release.share()
sale_trade_condition = self.portal.sale_trade_condition_module.newContent( sale_trade_condition = self.portal.sale_trade_condition_module.newContent(
portal_type="Sale Trade Condition", portal_type="Sale Trade Condition",
title="TestSubscriptionScenario", title="TestSubscriptionScenario",
...@@ -290,13 +296,14 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -290,13 +296,14 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
source_payment=self.expected_source_section + "/bank_account", source_payment=self.expected_source_section + "/bank_account",
price_currency="currency_module/EUR", price_currency="currency_module/EUR",
payment_mode='payzen', payment_mode='payzen',
specialise="sale_trade_condition_module/slapos_subscription_trade_condition" specialise="sale_trade_condition_module/slapos_subscription_trade_condition",
source_project_value=self.subscription_project
) )
# XXX TODO clarify the with / without tax # XXX TODO clarify the with / without tax
sale_trade_condition.newContent( sale_trade_condition.newContent(
portal_type="Sale Supply Line", portal_type="Sale Supply Line",
base_price=self.expected_individual_price_without_tax, base_price=self.expected_individual_price_without_tax,
resource='service_module/slapos_instance_subscription', resource_value=software_product,
) )
sale_trade_condition.newContent( sale_trade_condition.newContent(
portal_type="Sale Supply Line", portal_type="Sale Supply Line",
...@@ -309,7 +316,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -309,7 +316,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
title="TestSubscriptionScenario", title="TestSubscriptionScenario",
short_tile="Test Your Scenario", short_tile="Test Your Scenario",
description="This is a test", description="This is a test",
url_string=self.generateNewSoftwareReleaseUrl(), url_string=url_string,
root_slave=slave, root_slave=slave,
default_source_reference="default", default_source_reference="default",
reference="rapidvm%s" % self.new_id, reference="rapidvm%s" % self.new_id,
...@@ -318,7 +325,8 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -318,7 +325,8 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
sla_xml='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>', sla_xml='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>',
text_content='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>', text_content='<?xml version="1.0" encoding="utf-8"?>\n<instance>\n</instance>',
user_input={}, user_input={},
specialise_value=sale_trade_condition specialise_value=sale_trade_condition,
follow_up_value=self.subscription_project
) )
self.subscription_condition.validate() self.subscription_condition.validate()
self.tic() self.tic()
...@@ -464,9 +472,10 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -464,9 +472,10 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.assertEqual(len(delivery_list), 1) self.assertEqual(len(delivery_list), 1)
sale_packing_list = delivery_list[0] sale_packing_list = delivery_list[0]
instance_tree = subscription_request.getAggregateValue()
subscription_delivery_line_list = self.portal.portal_catalog( subscription_delivery_line_list = self.portal.portal_catalog(
portal_type="Sale Packing List Line", portal_type="Sale Packing List Line",
default_resource_uid=self.portal.service_module.slapos_instance_subscription.getUid(), resource__uid=instance_tree.InstanceTree_getSoftwareProduct().getUid(),
grouping_reference=sale_packing_list.getReference() grouping_reference=sale_packing_list.getReference()
) )
...@@ -999,7 +1008,6 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -999,7 +1008,6 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.assertEqual(len(login_list), 1) self.assertEqual(len(login_list), 1)
self.assertEqual(login_list[0].getReference(), person.getDefaultEmailText()) self.assertEqual(login_list[0].getReference(), person.getDefaultEmailText())
self.assertSameSet(person.getRoleList(), ["member", "subscriber"])
def checkEmailNotification(self, subscription_request, def checkEmailNotification(self, subscription_request,
notification_message="subscription_request-confirmation-with-password"): notification_message="subscription_request-confirmation-with-password"):
...@@ -1098,7 +1106,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1098,7 +1106,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
self.assertEqual(len(sale_packing_list.objectValues()), 2) self.assertEqual(len(sale_packing_list.objectValues()), 2)
sale_packing_list_line = [ i for i in sale_packing_list.objectValues() sale_packing_list_line = [ i for i in sale_packing_list.objectValues()
if i.getResource() == "service_module/slapos_instance_subscription"][0] if i.getResourceValue().getPortalType() == "Software Product"][0]
quantity = subscription_request.getQuantity() quantity = subscription_request.getQuantity()
if sale_trade_condition.getPriceCurrency() == "currency_module/CNY": if sale_trade_condition.getPriceCurrency() == "currency_module/CNY":
...@@ -1235,12 +1243,14 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1235,12 +1243,14 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
# Create a Public Server for admin user, and allow # Create a Public Server for admin user, and allow
subscription_server_title = 'Trial Public Server for Admin User %s' % self.new_id subscription_server_title = 'Trial Public Server for Admin User %s' % self.new_id
subscription_server_id = self.requestComputeNode(subscription_server_title) subscription_server_id = self.requestComputeNode(subscription_server_title,
self.subscription_project.getReference())
subscription_server = self.portal.portal_catalog.getResultValue( subscription_server = self.portal.portal_catalog.getResultValue(
portal_type='Compute Node', reference=subscription_server_id) portal_type='Compute Node', reference=subscription_server_id)
self.setAccessToMemcached(subscription_server) self.setAccessToMemcached(subscription_server)
self.assertNotEqual(None, subscription_server) self.assertNotEqual(None, subscription_server)
self.setServerOpenSubscription(subscription_server) self.setServerOpenPublic(subscription_server)
self.assertEqual('open', subscription_server.getCapacityScope())
# and install some software on them # and install some software on them
subscription_server_software = self.subscription_condition.getUrlString() subscription_server_software = self.subscription_condition.getUrlString()
...@@ -1645,9 +1655,10 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1645,9 +1655,10 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
# Call as anonymous... check response? # Call as anonymous... check response?
default_email_text = "abc%s@nexedi.com" % self.new_id default_email_text = "abc%s@nexedi.com" % self.new_id
name="ABC %s" % self.new_id name="ABC %s" % self.new_id
project_reference = self.subscription_project.getReference()
self.login() self.login()
self.createNormalUser(default_email_text, name, language) self.createNormalUser(default_email_text, name, language, self.subscription_project)
self.tic() self.tic()
self.subscription_server = self.createPublicServerForAdminUser() self.subscription_server = self.createPublicServerForAdminUser()
...@@ -1676,7 +1687,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1676,7 +1687,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
name="ABC %s" % self.new_id name="ABC %s" % self.new_id
self.login() self.login()
self.createNormalUser(default_email_text, name, language) self.createNormalUser(default_email_text, name, language, self.subscription_project)
self.tic() self.tic()
self.subscription_server = self.createPublicServerForAdminUser() self.subscription_server = self.createPublicServerForAdminUser()
...@@ -1696,6 +1707,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1696,6 +1707,7 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
software_release=self.subscription_condition.getUrlString(), software_release=self.subscription_condition.getUrlString(),
software_type="default", software_type="default",
partition_reference="_test_subscription_scenario_with_existing_user_extra_instance", partition_reference="_test_subscription_scenario_with_existing_user_extra_instance",
project_reference=project_reference
) )
self.non_subscription_related_instance_amount = 1 self.non_subscription_related_instance_amount = 1
...@@ -1893,6 +1905,9 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans ...@@ -1893,6 +1905,9 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
class TestSlapOSSubscriptionScenario(TestSlapOSSubscriptionScenarioMixin): class TestSlapOSSubscriptionScenario(TestSlapOSSubscriptionScenarioMixin):
def test_new_subscription_scenario_with_single_vm(self):
self._test_subscription_scenario(amount=1)
def test_subscription_scenario_with_single_vm(self): def test_subscription_scenario_with_single_vm(self):
self._test_subscription_scenario(amount=1) self._test_subscription_scenario(amount=1)
......
...@@ -7,7 +7,9 @@ Subscription Condition | specialise ...@@ -7,7 +7,9 @@ Subscription Condition | specialise
Subscription Request Module | business_application Subscription Request Module | business_application
Subscription Request | aggregate Subscription Request | aggregate
Subscription Request | causality Subscription Request | causality
Subscription Request | destination_project
Subscription Request | destination_section Subscription Request | destination_section
Subscription Request | source Subscription Request | source
Subscription Request | source_project
Subscription Request | source_section Subscription Request | source_section
Subscription Request | specialise Subscription Request | specialise
\ No newline at end of file
Subscription Condition | InstanceTree Subscription Condition | InstanceTree
Subscription Condition | Price Subscription Condition | Price
Subscription Condition | SlapOSSubscriptionCondition Subscription Condition | SlapOSSubscriptionCondition
Subscription Condition | SlapOSVirtualMasterConstraint
Subscription Condition | SoftwareInstance Subscription Condition | SoftwareInstance
Subscription Condition | TextDocument Subscription Condition | TextDocument
Subscription Condition | Url Subscription Condition | Url
...@@ -11,7 +12,7 @@ Subscription Request | InstanceTree ...@@ -11,7 +12,7 @@ Subscription Request | InstanceTree
Subscription Request | Person Subscription Request | Person
Subscription Request | Price Subscription Request | Price
Subscription Request | Reference Subscription Request | Reference
Subscription Request | SlaposSubscriptionRequestAuditConstraint Subscription Request | SlapOSVirtualMasterSourceProjectConstraint
Subscription Request | Task Subscription Request | Task
Subscription Request | Url Subscription Request | Url
Subscription Request | VariationRange Subscription Request | VariationRange
\ No newline at end of file
Email | -coordinate_interaction_workflow Email | -coordinate_interaction_workflow
Subscription Condition | commerce_validation_workflow Subscription Condition | commerce_validation_workflow
Subscription Condition | edit_workflow Subscription Condition | edit_workflow
Subscription Request | audit_validation_workflow
Subscription Request | edit_workflow Subscription Request | edit_workflow
Subscription Request | subscription_request_workflow Subscription Request | subscription_request_workflow
\ No newline at end of file
SlapOSSubscriptionCondition SlapOSSubscriptionCondition
SlaposSubscriptionRequestAuditConstraint
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment