Commit f71bc366 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_crm: Drop auto-cancellation of the invoices

   This isn't a decision to be taken automatically, but a decision for the site administrator
parent 825b35e7
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_crm_cancel_invoice</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1288051200.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>sense_method_id</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Cancel Invoice</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type="Regularisation Request",
simulation_state=["suspended"],
method_id='RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty',
activate_kw={'tag': tag}
)
context.activate(after_tag=tag).getId()
<?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>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
mail_message = None
invoice_list = []
state = context.getSimulationState()
person = context.getSourceProjectValue(portal_type="Person")
if (state != 'suspended') or \
(person is None):
return mail_message, invoice_list
portal = context.getPortalObject()
open_order = portal.portal_catalog.getResultValue(
portal_type="Open Sale Order",
validation_state="validated",
default_destination_decision_uid=person.getUid())
if (open_order is not None) and (
(open_order.getValidationState() != "validated") or \
(len(open_order.contentValues(portal_type="Open Sale Order Line")) != 0)):
return mail_message, invoice_list
if open_order is None:
# No open order was found, check if the latest archived order
# exists and contains no line.
open_order_list = portal.portal_catalog(
portal_type="Open Sale Order",
validation_state="archived",
sort_on=(('creation_date', 'DESC'),),
default_destination_decision_uid=person.getUid(),
limit=10)
if len(open_order_list):
# Ensure the list is indeed sorted to maximum know presicision
open_order = sorted(open_order_list, key=lambda x: x.getCreationDate(), reverse=True)[0]
if len(open_order.contentValues(portal_type="Open Sale Order Line")) != 0:
raise ValueError("Something is wrong, this Open Sale Order should had no Line")
else:
return mail_message, invoice_list
assert open_order.getDestinationDecisionUid() == person.getUid()
ticket = context
for payment in portal.portal_catalog(
portal_type="Payment Transaction",
payment_mode_uid=[
portal.portal_categories.payment_mode.wechat.getUid(),
portal.portal_categories.payment_mode.payzen.getUid()],
default_destination_section_uid=person.getUid(),
simulation_state=["started"],
):
if payment.getPaymentMode() == "payzen" and payment.PaymentTransaction_getPayzenId()[1] is None:
invoice = payment.getCausalityValue(portal_type="Sale Invoice Transaction")
assert payment.getDestinationSectionUid() == person.getUid()
invoice.SaleInvoiceTransaction_createReversalPayzenTransaction()
invoice_list.append(invoice.getRelativeUrl())
# Missing wechat cancellation
if len(invoice_list) > 0:
cancel_service = portal.service_module.slapos_crm_invoice_cancellation
mail_message = ticket.RegularisationRequest_checkToSendUniqEvent(
cancel_service.getRelativeUrl(),
'Cancellation of your bill',
"""Hello,
Thank you to have used our decentralized Cloud Computing service slapos.org.
We noticed that all your instances have been removed upon receiving your bill, so we conclude that the instances that you requested were not being used but probably ordered then forgotten.
To not to charge our first users a "non use" of our service, we have choosen to cancel your bill. That's mean: *You have nothing to pay us.*
We hope to see you using our services in the future.
Regards,
The slapos team
""",
'Cancelled payment.')
return mail_message, invoice_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>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>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -79,38 +79,6 @@ class TestSlapOSCrmInvalidateSuspendedRegularisationRequest(SlapOSTestCaseMixinW
slapos_crm_invalidate_suspended_regularisation_request
self._test_alarm(alarm, ticket, "RegularisationRequest_invalidateIfPersonBalanceIsOk")
class TestSlapOSCrmCancelInvoiceRelatedToSuspendedRegularisationRequest(SlapOSTestCaseMixinWithAbort):
def createRegularisationRequest(self):
new_id = self.generateNewId()
return self.portal.regularisation_request_module.newContent(
portal_type='Regularisation Request',
title="Test Reg. Req.%s" % new_id,
reference="TESTREGREQ-%s" % new_id,
)
def test_alarm_not_suspended_regularisation_request(self):
ticket = self.createRegularisationRequest()
ticket.validate()
self.tic()
alarm = self.portal.portal_alarms.\
slapos_crm_cancel_invoice
self._test_alarm_not_visited(alarm, ticket,
"RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty")
def test_alarm_suspended_regularisation_request(self):
ticket = self.createRegularisationRequest()
ticket.validate()
ticket.suspend()
self.tic()
alarm = self.portal.portal_alarms.\
slapos_crm_cancel_invoice
self._test_alarm(alarm, ticket,
"RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty")
class TestSlapOSCrmTriggerEscalationOnAcknowledgmentRegularisationRequest(SlapOSTestCaseMixinWithAbort):
def createRegularisationRequest(self):
......
......@@ -394,233 +394,6 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(SlapOSTestCaseMixin):
'', '', '', '',
REQUEST={})
class TestSlapOSRegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty(
SlapOSTestCaseMixinWithAbort):
def createRegularisationRequest(self):
new_id = self.generateNewId()
return self.portal.regularisation_request_module.newContent(
portal_type='Regularisation Request',
title="Test Reg. Req.%s" % new_id,
reference="TESTREGREQ-%s" % new_id,
resource='foo/bar',
)
def createOpenOrder(self):
new_id = self.generateNewId()
return self.portal.open_sale_order_module.newContent(
portal_type='Open Sale Order',
title="Test Open Order %s" % new_id,
reference="TESTOPENORDER-%s" % new_id,
)
def createSaleInvoiceTransaction(self):
new_id = self.generateNewId()
return self.portal.accounting_module.newContent(
portal_type='Sale Invoice Transaction',
title="Test Sale Invoice %s" % new_id,
reference="TESTSALEINVOICE-%s" % new_id,
)
def createPaymentTransaction(self):
new_id = self.generateNewId()
return self.portal.accounting_module.newContent(
portal_type='Payment Transaction',
title="Test Payment %s" % new_id,
reference="TESTPAYMENT-%s" % new_id,
)
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_REQUEST_disallowed(self):
ticket = self.createRegularisationRequest()
self.assertRaises(
Unauthorized,
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty,
REQUEST={})
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by SaleInvoiceTransaction_createReversalPayzenTransaction")')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'service_relative_url, title, text_content, comment, REQUEST=None',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by RegularisationRequest_checkToSendUniqEvent ' \
'%s %s %s %s" % (service_relative_url, title, text_content, comment))\n' \
'return "fooevent"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_invoice_to_cancel(self):
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
source_project_value=person)
ticket.validate()
ticket.suspend()
order = self.createOpenOrder()
order.edit(destination_decision_value=person)
self.portal.portal_workflow._jumpToStateFor(order, 'validated')
invoice = self.createSaleInvoiceTransaction()
invoice.edit(
payment_mode="payzen",
)
payment = self.createPaymentTransaction()
payment.edit(
payment_mode="payzen",
causality_value=invoice,
destination_section_value=person)
self.portal.portal_workflow._jumpToStateFor(payment, 'started')
self.tic()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
expected_service = 'service_module/slapos_crm_invoice_cancellation'
expected_title = 'Cancellation of your bill'
expected_text= """Hello,
Thank you to have used our decentralized Cloud Computing service slapos.org.
We noticed that all your instances have been removed upon receiving your bill, so we conclude that the instances that you requested were not being used but probably ordered then forgotten.
To not to charge our first users a "non use" of our service, we have choosen to cancel your bill. That's mean: *You have nothing to pay us.*
We hope to see you using our services in the future.
Regards,
The slapos team
"""
expected_comment = 'Cancelled payment.'
self.assertEqual(
'Visited by RegularisationRequest_checkToSendUniqEvent %s %s %s %s' % \
(expected_service, expected_title, expected_text, expected_comment),
ticket.workflow_history['edit_workflow'][-1]['comment'])
self.assertEqual(
'Visited by SaleInvoiceTransaction_createReversalPayzenTransaction',
invoice.workflow_history['edit_workflow'][-1]['comment'])
self.assertEqual(event, "fooevent")
self.assertEqual(invoice_list, [invoice.getRelativeUrl()])
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_not_suspended_ticket(self):
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
source_project_value=person)
ticket.validate()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
self.assertEqual(event, None)
self.assertEqual(invoice_list, [])
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_no_person_related(self):
ticket = self.createRegularisationRequest()
ticket.validate()
ticket.suspend()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
self.assertEqual(event, None)
self.assertEqual(invoice_list, [])
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_no_open_order(self):
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
source_project_value=person)
ticket.validate()
ticket.suspend()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
self.assertEqual(event, None)
self.assertEqual(invoice_list, [])
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_with_open_order_line(self):
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
source_project_value=person)
ticket.validate()
ticket.suspend()
order = self.createOpenOrder()
order.edit(destination_decision_value=person)
order.newContent(portal_type="Open Sale Order Line")
self.portal.portal_workflow._jumpToStateFor(order, 'validated')
self.tic()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
self.assertEqual(event, None)
self.assertEqual(invoice_list, [])
@simulate('SaleInvoiceTransaction_createReversalPayzenTransaction',
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
@simulate('RegularisationRequest_checkToSendUniqEvent',
'service_relative_url, title, text_content, comment, REQUEST=None',
'context.portal_workflow.doActionFor(' \
'context, action="edit_action", ' \
'comment="Visited by RegularisationRequest_checkToSendUniqEvent ' \
'%s %s %s %s" % (service_relative_url, title, text_content, comment))\n' \
'return "fooevent"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_no_invoice(self):
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
source_project_value=person)
ticket.validate()
ticket.suspend()
order = self.createOpenOrder()
order.edit(destination_decision_value=person)
self.portal.portal_workflow._jumpToStateFor(order, 'validated')
self.tic()
event, invoice_list = \
ticket.RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty()
self.assertNotEqual(event, "fooevent")
self.assertEqual(invoice_list, [])
class TestSlapOSRegularisationRequest_checkToTriggerNextEscalationStep(
SlapOSTestCaseMixinWithAbort):
......
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