Commit 6bcb0fc4 authored by Romain Courteaud's avatar Romain Courteaud

New alarm to automatically create registration request.

This alarm send the first invoice reminder to the user.
parent df8f5b58
No related merge requests found
<?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_createRegularisationRequest</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_create_regularisation_request</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value> <int>2</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>Create regularisation request</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, NegatedQuery\n
\n
# XXX TODO: use getInventory to directly fetch user with a wrong balance\n
portal.portal_catalog.searchAndActivate(\n
portal_type="Person", \n
validation_state="validated",\n
reference=NegatedQuery(SimpleQuery(reference=None)),\n
default_email_text=NegatedQuery(SimpleQuery(default_email_text=None)),\n
method_id=\'Person_checkToCreateRegularisationRequest\',\n
activate_kw={\'tag\': tag}\n
)\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_createRegularisationRequest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
portal = context.getPortalObject()\n
person = context\n
ticket_portal_type = "Regularisation Request"\n
\n
# XXX TODO\n
# # Prevent to create 2 tickets during the same transaction\n
# transactional_variable = getTransactionalVariable()\n
# if tag in transactional_variable:\n
# raise RuntimeError, \'ticket %s already exist\' % tag\n
# else:\n
# transactional_variable[tag] = None\n
\n
ticket = portal.portal_catalog.getResultValue(\n
portal_type=ticket_portal_type,\n
default_source_project_uid=person.getUid(),\n
simulation_state=[\'suspended\', \'validated\'],\n
)\n
if (ticket is None) and int(person.Entity_statBalance()) > 0:\n
\n
tag = "%s_addRegularisationRequest_inProgress" % person.getUid()\n
if (portal.portal_activities.countMessageWithTag(tag) > 0):\n
# The regularisation request is already under creation but can not be fetched from catalog\n
# As it is not possible to fetch informations, it is better to raise an error\n
return None, None\n
\n
# Prevent concurrent transaction to create 2 tickets for the same person\n
person.serialize()\n
\n
# Time to create the ticket\n
regularisation_request_template = portal.restrictedTraverse(\n
portal.portal_preferences.getPreferredRegularisationRequestTemplate())\n
ticket = regularisation_request_template.Base_createCloneDocument(batch_mode=1)\n
ticket.edit(\n
source_project_value=context,\n
title=\'Account regularisation expected for "%s"\' % context.getTitle(),\n
destination_decision_value=context,\n
start_date=DateTime(),\n
resource=portal.portal_preferences.getPreferredRegularisationRequestResource(),\n
)\n
ticket.validate(comment=\'New automatic ticket for %s\' % context.getTitle())\n
ticket.suspend(comment=\'New automatic ticket for %s\' % context.getTitle())\n
\n
ticket.reindexObject(activate_kw={\'tag\': tag})\n
\n
# Inform user that the ticket has been created.\n
mail_message = portal.event_module.newContent(\n
portal_type=\'Mail Message\',\n
start_date=DateTime(),\n
destination_value=person,\n
follow_up=ticket.getRelativeUrl(),\n
source_value=ticket.getSourceValue(),\n
title=\'Invoice payment requested\',\n
resource=ticket.getResource(),\n
text_content="""\n
Dear user,\n
\n
A new invoice has been generated. \n
You can access it in your invoice section at %s.\n
\n
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.\n
\n
Regards,\n
The slapos team\n
""" % portal.portal_preferences.getPreferredSlaposWebSiteUrl())\n
portal.portal_workflow.doActionFor(mail_message, \'start_action\', send_mail=True, comment=\'Requested manual payment.\')\n
mail_message.stop(comment=\'Requested manual payment.\')\n
mail_message.deliver(comment=\'Requested manual payment.\')\n
\n
return ticket, mail_message\n
\n
return ticket, None\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_checkToCreateRegularisationRequest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript
class TestSlapOSCRMCreateRegularisationRequest(testSlapOSMixin):
def _simulatePerson_checkToCreateRegularisationRequest(self):
script_name = 'Person_checkToCreateRegularisationRequest'
if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom,
script_name,
'*args, **kwargs',
'# Script body\n'
"""portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by Person_checkToCreateRegularisationRequest') """ )
transaction.commit()
def _dropPerson_checkToCreateRegularisationRequest(self):
script_name = 'Person_checkToCreateRegularisationRequest'
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
def test_alarm_expected_person(self):
new_id = self.generateNewId()
person = self.portal.person_module.newContent(
portal_type='Person',
title="Test person %s" % new_id,
reference="TESTPERS_%s" % new_id,
default_email_text="%s@example.org" % new_id,
)
person.validate()
self.tic()
self._simulatePerson_checkToCreateRegularisationRequest()
try:
self.portal.portal_alarms.\
slapos_crm_create_regularisation_request.activeSense()
self.tic()
finally:
self._dropPerson_checkToCreateRegularisationRequest()
self.assertEqual(
'Visited by Person_checkToCreateRegularisationRequest',
person.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_no_email(self):
new_id = self.generateNewId()
person = self.portal.person_module.newContent(
portal_type='Person',
title="Test person %s" % new_id,
reference="TESTPERS_%s" % new_id,
)
person.validate()
self.tic()
self._simulatePerson_checkToCreateRegularisationRequest()
try:
self.portal.portal_alarms.\
slapos_crm_create_regularisation_request.activeSense()
self.tic()
finally:
self._dropPerson_checkToCreateRegularisationRequest()
self.assertNotEqual(
'Visited by Person_checkToCreateRegularisationRequest',
person.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_no_reference(self):
new_id = self.generateNewId()
person = self.portal.person_module.newContent(
portal_type='Person',
title="Test person %s" % new_id,
default_email_text="%s@example.org" % new_id,
)
person.validate()
self.tic()
self._simulatePerson_checkToCreateRegularisationRequest()
try:
self.portal.portal_alarms.\
slapos_crm_create_regularisation_request.activeSense()
self.tic()
finally:
self._dropPerson_checkToCreateRegularisationRequest()
self.assertNotEqual(
'Visited by Person_checkToCreateRegularisationRequest',
person.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_not_validated(self):
new_id = self.generateNewId()
person = self.portal.person_module.newContent(
portal_type='Person',
title="Test person %s" % new_id,
reference="TESTPERS_%s" % new_id,
default_email_text="%s@example.org" % new_id,
)
person.validate()
person.invalidate()
self.tic()
self._simulatePerson_checkToCreateRegularisationRequest()
try:
self.portal.portal_alarms.\
slapos_crm_create_regularisation_request.activeSense()
self.tic()
finally:
self._dropPerson_checkToCreateRegularisationRequest()
self.assertNotEqual(
'Visited by Person_checkToCreateRegularisationRequest',
person.workflow_history['edit_workflow'][-1]['comment'])
# def test_alarm_not_suspended_support_request(self):
# new_id = self.generateNewId()
# payment = self.portal.accounting_module.newContent(
# portal_type='Payment Transaction',
# title="Payment %s" % new_id,
# reference="TESTPAY-%s" % new_id,
# )
# new_id = self.generateNewId()
# ticket = self.portal.support_request_module.newContent(
# portal_type='Support Request',
# title="Ticket %s" % new_id,
# reference="TESTSUPREQ-%s" % new_id,
# source_project_value=payment,
# )
# ticket.validate()
#
# self.tic()
# self._simulatePerson_checkToCreateRegularisationRequest()
# try:
# self.portal.portal_alarms.\
# slapos_payzen_update_suspended_support_request.activeSense()
# self.tic()
# finally:
# self._dropPerson_checkToCreateRegularisationRequest()
# self.assertNotEqual(
# 'Visited by Person_checkToCreateRegularisationRequest',
# ticket.workflow_history['edit_workflow'][-1]['comment'])
#
# def test_alarm_suspended_support_request(self):
# new_id = self.generateNewId()
# payment = self.portal.accounting_module.newContent(
# portal_type='Payment Transaction',
# title="Payment %s" % new_id,
# reference="TESTPAY-%s" % new_id,
# )
# new_id = self.generateNewId()
# ticket = self.portal.support_request_module.newContent(
# portal_type='Support Request',
# title="Ticket %s" % new_id,
# reference="TESTSUPREQ-%s" % new_id,
# source_project_value=payment,
# )
# ticket.validate()
# ticket.suspend()
#
# self.tic()
# self._simulatePerson_checkToCreateRegularisationRequest()
# try:
# self.portal.portal_alarms.\
# slapos_payzen_update_suspended_support_request.activeSense()
# self.tic()
# finally:
# self._dropPerson_checkToCreateRegularisationRequest()
# self.assertEqual(
# 'Visited by Person_checkToCreateRegularisationRequest',
# ticket.workflow_history['edit_workflow'][-1]['comment'])
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
from zExceptions import Unauthorized
from DateTime import DateTime
from functools import wraps
from Products.ERP5Type.tests.utils import createZODBPythonScript
import difflib
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
class TestSlapOSPerson_checkToCreateRegularisationRequest(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
return self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_payment_requested(self):
for preference in \
self.portal.portal_catalog(portal_type="System Preference"):
preference = preference.getObject()
if preference.getPreferenceState() == 'global':
preference.setPreferredSlaposWebSiteUrl('http://foobar.org/')
person = self.createPerson()
before_date = DateTime()
ticket, event = person.Person_checkToCreateRegularisationRequest()
after_date = DateTime()
self.assertEquals(ticket.getPortalType(), 'Regularisation Request')
self.assertEquals(ticket.getSimulationState(), 'suspended')
self.assertEquals(ticket.getSourceProject(), person.getRelativeUrl())
self.assertEquals(ticket.getTitle(),
'Account regularisation expected for "%s"' % person.getTitle())
self.assertEquals(event.getPortalType(), 'Mail Message')
self.assertTrue(event.getStartDate() >= before_date)
self.assertTrue(event.getStopDate() <= after_date)
self.assertEquals(event.getTitle(), "Invoice payment requested")
self.assertEquals(event.getDestination(),
person.getRelativeUrl())
self.assertEquals(event.getSource(),
ticket.getSource())
expected_text_content = """
Dear user,
A new invoice has been generated.
You can access it in your invoice section at http://foobar.org/.
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
Regards,
The slapos team
"""
self.assertEquals(event.getTextContent(), expected_text_content,
'\n'.join([x for x in difflib.unified_diff(
event.getTextContent().splitlines(),
expected_text_content.splitlines())]))
self.assertEquals(event.getSimulationState(), 'delivered')
# def test_addRegularisationRequest_do_not_duplicate_ticket(self):
# person = self.createPerson()
# ticket = person.Person_checkToCreateRegularisationRequest()
# ticket2 = person.Person_checkToCreateRegularisationRequest()
# self.assertEquals(ticket.getRelativeUrl(), ticket2.getRelativeUrl())
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_do_not_duplicate_ticket_if_not_reindexed(self):
person = self.createPerson()
ticket, event = person.Person_checkToCreateRegularisationRequest()
transaction.commit()
ticket2, event2 = person.Person_checkToCreateRegularisationRequest()
self.assertNotEquals(ticket, None)
self.assertNotEquals(event, None)
self.assertEquals(ticket2, None)
self.assertEquals(event2, None)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "0"')
def test_addRegularisationRequest_balance_ok(self):
person = self.createPerson()
ticket, event = person.Person_checkToCreateRegularisationRequest()
self.assertEquals(ticket, None)
self.assertEquals(event, None)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_suspended_ticket(self):
person = self.createPerson()
ticket, event = person.Person_checkToCreateRegularisationRequest()
transaction.commit()
self.tic()
ticket2, event2 = person.Person_checkToCreateRegularisationRequest()
self.assertNotEquals(ticket, None)
self.assertNotEquals(event, None)
self.assertEquals(ticket2.getRelativeUrl(), ticket.getRelativeUrl())
self.assertEquals(event2, None)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_validated_ticket(self):
person = self.createPerson()
ticket, event = person.Person_checkToCreateRegularisationRequest()
ticket.validate()
transaction.commit()
self.tic()
ticket2, event2 = person.Person_checkToCreateRegularisationRequest()
self.assertNotEquals(ticket, None)
self.assertNotEquals(event, None)
self.assertEquals(ticket2.getRelativeUrl(), ticket.getRelativeUrl())
self.assertEquals(event2, None)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_invalidated_ticket(self):
person = self.createPerson()
ticket, event = person.Person_checkToCreateRegularisationRequest()
ticket.invalidate()
transaction.commit()
self.tic()
ticket2, event2 = person.Person_checkToCreateRegularisationRequest()
self.assertNotEquals(ticket2.getRelativeUrl(), ticket.getRelativeUrl())
self.assertNotEquals(event2, None)
def test_addRegularisationRequest_REQUEST_disallowed(self):
date = DateTime()
person = self.createPerson()
self.assertRaises(
Unauthorized,
person.Person_checkToCreateRegularisationRequest,
REQUEST={})
9
\ No newline at end of file
10
\ No newline at end of file
event_module/slapos_crm_web_message_template
portal_alarms/slapos_crm_create_regularisation_request
regularisation_request_module/slapos_crm_regularisation_request_template
service_module/slapos_crm_acknowledgement
service_module/slapos_crm_complaint
......
testSlapOSCRMSkins
testSlapOSCRMAlarm
\ 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