Commit bdb8aa14 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_*: Added script calculate Outstanding deposit amount

  Include checkInstanceAllocationWithDeposit on tests to checks the use case
    whenever the pay the deposit is required to allocate.

  Update tests to pay precise deposit, since a more accurate use case is
    check and pay a proper amount of deposit and check if the steps are
    working properly (ie.: Subscription request stays in submitted)
parent d6b8772d
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
portal = context.getPortalObject()
ledger_uid = portal.portal_categories.ledger.automated.getUid()
if not currency_uid:
raise ValueError("You must provide an currency to calculate the amount")
outstanding_amount_list = context.Entity_getOutstandingDepositAmountList(
resource_uid=currency_uid, ledger_uid=ledger_uid)
if not outstanding_amount_list:
# Nothing found
return 0
if len(outstanding_amount_list) > 1:
raise ValueError('More them one value for the %s currency was found' % currency_uid)
return outstanding_amount_list[0].total_price
<?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>currency_uid, REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Entity_getOutstandingDepositAmount</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
from Products.ERP5Type.Document import newTempBase
query_kw = {
"portal_type": "Subscription Request",
"simulation_state": "submitted"
}
if ledger_uid:
query_kw['ledger__uid'] = ledger_uid
if resource_uid is not None:
query_kw['price_currency__uid'] = resource_uid
object_dict = {}
for subscription_request_brain in portal.portal_catalog(
destination_section__uid=context.getUid(),
**query_kw):
subscription_request = subscription_request_brain.getObject()
subscription_request_total_price = subscription_request.getTotalPrice()
if 0 < subscription_request_total_price:
currency = subscription_request.getPriceCurrency()
# Future proof in case we implement B2B payment
object_index = "%s_%s" % (currency, subscription_request.getDestinationSection())
if object_index not in object_dict:
object_dict[object_index] = dict(
causality_list=[],
uid=object_index,
price_currency=currency,
destination_section=subscription_request.getDestinationSection(),
total_price = 0)
object_dict[object_index]['total_price'] = \
object_dict[object_index]['total_price'] + subscription_request_total_price
object_dict[object_index]['causality_list'].append(subscription_request.getRelativeUrl())
object_list = []
for key in object_dict:
object_list.append(newTempBase(
portal, object_dict[key]['causality_list'][0], **object_dict[key]))
return object_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>resource_uid=None, ledger_uid=None,**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Entity_getOutstandingDepositAmountList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -581,15 +581,16 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
if q.getTitle() == instance_title]
self.assertEqual(0, len(instance_tree_list))
def checkServiceSubscriptionRequest(self, service):
def checkServiceSubscriptionRequest(self, service, simulation_state='invalidated'):
self.login()
subscription_request = self.portal.portal_catalog.getResultValue(
portal_type="Subscription Request",
aggregate__uid=service.getUid(),
simulation_state='invalidated'
simulation_state=simulation_state
)
self.assertNotEqual(subscription_request, None)
return subscription_request
def checkInstanceAllocation(self, person_user_id, person_reference,
instance_title, software_release, software_type, server,
......@@ -644,6 +645,90 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
partition.contentValues(portal_type='Internet Protocol Address')],
connection_dict.values())
def checkInstanceAllocationWithDeposit(self, person_user_id, person_reference,
instance_title, software_release, software_type, server,
project_reference, deposit_amount, currency):
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
project_reference=project_reference
)
self.tic()
instance_tree = self.portal.portal_catalog.getResultValue(
portal_type="Instance Tree",
title=instance_title,
follow_up__reference=project_reference
)
person = instance_tree.getDestinationSectionValue()
self.assertEqual(person.getUserId(), person_user_id)
subscription_request = self.checkServiceSubscriptionRequest(instance_tree, 'submitted')
self.assertEqual(subscription_request.getTotalPrice(), deposit_amount)
self.tic()
amount = person.Entity_getOutstandingDepositAmount(
currency.getUid())
self.assertEqual(amount, deposit_amount)
# Action to submit project subscription
def wrapWithShadow(_person, *arg):
return _person.Person_addDepositPayment(*arg)
payment_transaction = person.Person_restrictMethodAsShadowUser(
shadow_document=person,
callable_object=wrapWithShadow,
argument_list=[person, deposit_amount, currency.getRelativeUrl(), 1])
self.tic()
self.logout()
self.login()
# payzen interface will only stop the payment
payment_transaction.stop()
self.tic()
assert payment_transaction.receivable.getGroupingReference(None) is not None
self.login(person_user_id)
self.checkServiceSubscriptionRequest(instance_tree, 'invalidated')
amount = person.Entity_getOutstandingDepositAmount(currency.getUid())
self.assertEqual(0, amount)
self.login(person_user_id)
self.personRequestInstance(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
project_reference=project_reference
)
# now instantiate it on compute_node and set some nice connection dict
self.simulateSlapgridCP(server)
# let's find instances of user and check connection strings
instance_tree_list = [q.getObject() for q in
self._getCurrentInstanceTreeList()
if q.getTitle() == instance_title]
self.assertEqual(1, len(instance_tree_list))
instance_tree = instance_tree_list[0]
software_instance = instance_tree.getSuccessorValue()
self.assertEqual(software_instance.getTitle(),
instance_tree.getTitle())
connection_dict = software_instance.getConnectionXmlAsDict()
self.assertSameSet(('url_1', 'url_2'), connection_dict.keys())
self.login()
partition = software_instance.getAggregateValue()
self.assertSameSet(
['http://%s/' % q.getIpAddress() for q in
partition.contentValues(portal_type='Internet Protocol Address')],
connection_dict.values())
def findMessage(self, email, body):
for candidate in reversed(self.portal.MailHost.getMessageList()):
if [q for q in candidate[1] if email in q] and body in candidate[2]:
......
......@@ -472,11 +472,11 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
reference=owner_reference).getParentValue()
self.tic()
# hooray
self.logout()
self.login(owner_person.getUserId())
# XXX XXX do reservation payment for a huge amount, to check if other services are ok
# Pre-input a reservation payment for a huge amount, to have enough amount.
# to check if other services are ok
total_price = 1234
# Action to submit project subscription
......@@ -565,7 +565,6 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
# payzen interface will only stop the payment
payment_transaction.stop()
self.tic()
self.portal.log('SubscriptionRequest_validateIfSubmitted %s' % payment_transaction.getSimulationState())
preference = self.portal.portal_preferences.slapos_default_system_preference
preference.edit(
......@@ -759,32 +758,27 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
self.logout()
# lets join as slapos administrator, which will manager the project
owner_reference = 'project-%s' % self.generateNewId()
self.joinSlapOS(self.web_site, owner_reference)
project_owner_reference = 'project-%s' % self.generateNewId()
self.joinSlapOS(self.web_site, project_owner_reference)
self.login()
owner_person = self.portal.portal_catalog.getResultValue(
project_owner_person = self.portal.portal_catalog.getResultValue(
portal_type="ERP5 Login",
reference=owner_reference).getParentValue()
#owner_person.setCareerSubordinationValue(seller_organisation)
reference=project_owner_reference).getParentValue()
# owner_person.setCareerSubordinationValue(seller_organisation)
self.tic()
# hooray, now it is time to create compute_nodes
self.logout()
self.login(sale_person.getUserId())
project_relative_url = self.addProject(is_accountable=True, person=owner_person, currency=currency)
project_relative_url = self.addProject(
is_accountable=True, person=project_owner_person, currency=currency)
self.logout()
self.login()
project = self.portal.restrictedTraverse(project_relative_url)
payment_transaction = owner_person.Person_addDepositPayment(99*10, currency.getRelativeUrl(), 1)
# payzen interface will only stop the payment
payment_transaction.stop()
preference = self.portal.portal_preferences.slapos_default_system_preference
preference.edit(
preferred_subscription_assignment_category_list=[
......@@ -822,6 +816,8 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
)
sale_supply.validate()
self.tic()
# some preparation
self.logout()
......@@ -860,6 +856,32 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
# format the compute_nodes
self.formatComputeNode(public_server)
self.logout()
self.login(project_owner_person.getUserId())
# Pay deposit to validate virtual master.
deposit_amount = 42.0 + 99.0
amount = project_owner_person.Entity_getOutstandingDepositAmount(
currency.getUid())
self.assertEqual(amount, deposit_amount)
def wrapWithShadow(_person, *arg):
return _person.Person_addDepositPayment(*arg)
payment_transaction = project_owner_person.Person_restrictMethodAsShadowUser(
shadow_document=project_owner_person,
callable_object=wrapWithShadow,
argument_list=[project_owner_person, deposit_amount, currency.getRelativeUrl(), 1])
self.tic()
self.logout()
self.login()
# payzen interface will only stop the payment
payment_transaction.stop()
self.tic()
assert payment_transaction.receivable.getGroupingReference(None) is not None
self.login(project_owner_person.getUserId())
amount = project_owner_person.Entity_getOutstandingDepositAmount(currency.getUid())
self.assertEqual(0, amount)
# join as the another visitor and request software instance on public
# compute_node
self.logout()
......@@ -871,16 +893,13 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
portal_type="ERP5 Login",
reference=public_reference).getParentValue()
payment_transaction = public_person.Person_addDepositPayment(99*10, currency.getRelativeUrl(), 1)
# payzen interface will only stop the payment
payment_transaction.stop()
with PinnedDateTime(self, DateTime('2024/02/17 01:01')):
public_instance_title = 'Public title %s' % self.generateNewId()
self.checkInstanceAllocation(public_person.getUserId(),
self.checkInstanceAllocationWithDeposit(public_person.getUserId(),
public_reference, public_instance_title,
public_server_software, public_instance_type,
public_server, project.getReference())
public_server, project.getReference(),
9.0, currency)
self.login()
public_person = self.portal.portal_catalog.getResultValue(
......@@ -919,7 +938,7 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
assert len(inventory_list) == 1, len(inventory_list)
assert inventory_list[0].quantity == 1, inventory_list[0].quantity
resource_vcl = [
#'software_release/%s' % release_variation.getRelativeUrl(),
# 'software_release/%s' % release_variation.getRelativeUrl(),
'software_type/%s' % type_variation.getRelativeUrl()
]
resource_vcl.sort()
......@@ -930,7 +949,7 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
assert len(transaction_list) == 2, len(transaction_list)
self.assertSameSet(
[x.total_price for x in transaction_list],
[990.0, -990.0],
[9.0, -9.0],
[x.total_price for x in transaction_list]
)
......@@ -941,7 +960,7 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
# 3 allocation supply / line / cell
# 1 compute node
# 2 credential request
# 1 event
# 2 event
# 1 instance tree
# 6 open sale order / line
# 5 (can reduce to 2) assignment
......@@ -953,7 +972,7 @@ class TestSlapOSVirtualMasterScenario(TestSlapOSVirtualMasterScenarioMixin):
# 1 software instance
# 1 software product
# 3 subscription requests
self.assertRelatedObjectCount(project, 52)
self.assertRelatedObjectCount(project, 53)
self.checkERP5StateBeforeExit()
......
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