From 786eb339728661538e5dc993a95cf954110c0ffc Mon Sep 17 00:00:00 2001
From: Alain Takoudjou <alain.takoudjou@nexedi.com>
Date: Mon, 11 Apr 2016 12:30:37 +0000
Subject: [PATCH] slapos_crm: migrate to new bt format

---
 ...RelatedToSuspendedRegularisationRequest.py |   8 ++
 ...elatedToSuspendedRegularisationRequest.xml |  12 ---
 .../Alarm_createRegularisationRequest.py      |  13 +++
 .../Alarm_createRegularisationRequest.xml     |  17 ----
 ...ngSubscriptionFromRegularisationRequest.py |  14 +++
 ...gSubscriptionFromRegularisationRequest.xml |  18 ----
 ...nvalidateSuspendedRegularisationRequest.py |   8 ++
 ...validateSuspendedRegularisationRequest.xml |  12 ---
 ...ngSubscriptionFromRegularisationRequest.py |  17 ++++
 ...gSubscriptionFromRegularisationRequest.xml |  21 -----
 ...onOnAcknowledgmentRegularisationRequest.py |   9 ++
 ...nOnAcknowledgmentRegularisationRequest.xml |  13 ---
 ...onOnDeleteReminderRegularisationRequest.py |   9 ++
 ...nOnDeleteReminderRegularisationRequest.xml |  13 ---
 ...StopAcknowledgmentRegularisationRequest.py |   9 ++
 ...topAcknowledgmentRegularisationRequest.xml |  13 ---
 ...tionOnStopReminderRegularisationRequest.py |   9 ++
 ...ionOnStopReminderRegularisationRequest.xml |  13 ---
 ...ription_deleteFromRegularisationRequest.py |  21 +++++
 ...iption_deleteFromRegularisationRequest.xml |  25 ------
 ...scription_stopFromRegularisationRequest.py |  21 +++++
 ...cription_stopFromRegularisationRequest.xml |  25 ------
 ...rson_checkToCreateRegularisationRequest.py |  77 ++++++++++++++++
 ...son_checkToCreateRegularisationRequest.xml |  85 ------------------
 .../RegularisationRequest_afterClone.py       |   1 +
 .../RegularisationRequest_afterClone.xml      |   5 --
 ...t_cancelInvoiceIfPersonOpenOrderIsEmpty.py |  62 +++++++++++++
 ..._cancelInvoiceIfPersonOpenOrderIsEmpty.xml |  66 --------------
 ...ularisationRequest_checkToSendUniqEvent.py |  50 +++++++++++
 ...larisationRequest_checkToSendUniqEvent.xml |  58 ------------
 ...equest_checkToTriggerNextEscalationStep.py |  24 +++++
 ...quest_checkToTriggerNextEscalationStep.xml |  32 -------
 ...onRequest_deleteHostingSubscriptionList.py |  22 +++++
 ...nRequest_deleteHostingSubscriptionList.xml |  26 ------
 ...gularisationRequest_getResourceItemList.py |   1 +
 ...ularisationRequest_getResourceItemList.xml |   5 --
 .../slapos_crm/RegularisationRequest_init.py  |  14 +++
 .../slapos_crm/RegularisationRequest_init.xml |  18 ----
 ...onRequest_invalidateIfPersonBalanceIsOk.py |  12 +++
 ...nRequest_invalidateIfPersonBalanceIsOk.xml |  20 -----
 ...tionRequest_stopHostingSubscriptionList.py |  22 +++++
 ...ionRequest_stopHostingSubscriptionList.xml |  26 ------
 ...Request_triggerAcknowledgmentEscalation.py |  30 +++++++
 ...equest_triggerAcknowledgmentEscalation.xml |  34 -------
 ...Request_triggerDeleteReminderEscalation.py |  29 ++++++
 ...equest_triggerDeleteReminderEscalation.xml |  33 -------
 ...est_triggerStopAcknowledgmentEscalation.py |  29 ++++++
 ...st_triggerStopAcknowledgmentEscalation.xml |  33 -------
 ...onRequest_triggerStopReminderEscalation.py |  29 ++++++
 ...nRequest_triggerStopReminderEscalation.xml |  33 -------
 .../slapos_crm/rss_feed_image.png             | Bin 0 -> 1510 bytes
 .../slapos_crm/rss_feed_image.xml             |  30 -------
 ...m_checkAndUpdateComputerAllocationScope.py |  15 ++++
 ..._checkAndUpdateComputerAllocationScope.xml |  19 ----
 ...ndUpdatePersonalComputerAllocationScope.py |  16 ++++
 ...dUpdatePersonalComputerAllocationScope.xml |  26 +-----
 .../Alarm_checkComputerState.py               |  18 ++++
 .../Alarm_checkComputerState.xml              |  22 -----
 .../Alarm_checkHostingSubscriptionState.py    |  10 +++
 .../Alarm_checkHostingSubscriptionState.xml   |  14 ---
 .../Base_generateSupportRequestForSlapOS.py   |  55 ++++++++++++
 .../Base_generateSupportRequestForSlapOS.xml  |  59 ------------
 .../Computer_checkAndUpdateAllocationScope.py |  57 ++++++++++++
 ...Computer_checkAndUpdateAllocationScope.xml |  61 -------------
 ...r_checkAndUpdatePersonalAllocationScope.py |   3 +
 ..._checkAndUpdatePersonalAllocationScope.xml |   7 --
 .../Computer_checkState.py                    |  64 +++++++++++++
 .../Computer_checkState.xml                   |  72 ---------------
 ...ERP5Site_isSupportRequestCreationClosed.py |  13 +++
 ...RP5Site_isSupportRequestCreationClosed.xml |  21 -----
 .../Folder_getOpenTicketList.py               |   3 +
 .../Folder_getOpenTicketList.xml              |   7 --
 ...Subscription_checkSoftwareInstanceState.py |  49 ++++++++++
 ...ubscription_checkSoftwareInstanceState.xml |  57 ------------
 ...gSubscription_createSupportRequestEvent.py |  37 ++++++++
 ...Subscription_createSupportRequestEvent.xml |  41 ---------
 .../Person_isServiceProvider.py               |   9 ++
 .../Person_isServiceProvider.xml              |  13 ---
 .../SoftwareInstallation_hasReportedError.py  |  22 +++++
 .../SoftwareInstallation_hasReportedError.xml |  26 ------
 .../SoftwareInstance_hasReportedError.py      |  24 +++++
 .../SoftwareInstance_hasReportedError.xml     |  28 ------
 ...pportRequest_trySendNotificationMessage.py |  31 +++++++
 ...portRequest_trySendNotificationMessage.xml |  35 --------
 84 files changed, 967 insertions(+), 1193 deletions(-)
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.png
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.py
 create mode 100644 master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py

diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.py
new file mode 100644
index 000000000..8d314e429
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.py
@@ -0,0 +1,8 @@
+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()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.xml
index d0885c9f3..070ea9c7b 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_cancelInvoiceRelatedToSuspendedRegularisationRequest.xml
@@ -48,18 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      method_id=\'RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.py
new file mode 100644
index 000000000..dff5d0911
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.py
@@ -0,0 +1,13 @@
+portal = context.getPortalObject()
+from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, NegatedQuery
+
+# XXX TODO: use getInventory to directly fetch user with a wrong balance
+portal.portal_catalog.searchAndActivate(
+      portal_type="Person", 
+      validation_state="validated",
+      reference=NegatedQuery(SimpleQuery(reference=None)),
+      default_email_text=NegatedQuery(SimpleQuery(default_email_text=None)),
+      method_id='Person_checkToCreateRegularisationRequest',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.xml
index 744a045ac..981d4b84d 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_createRegularisationRequest.xml
@@ -48,23 +48,6 @@
               </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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.py
new file mode 100644
index 000000000..fc4691c0e
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.py
@@ -0,0 +1,14 @@
+portal = context.getPortalObject()
+sub_tag = "RegularisationRequest_deleteHostingSubscriptionList"
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=portal.service_module.slapos_crm_delete_acknowledgement.getUid(),
+      method_id='RegularisationRequest_deleteHostingSubscriptionList',
+      method_args=(sub_tag,),
+      # Limit activity number, as method_id also calls searchAndActivate
+      activity_count=1,
+      packet_size=1,
+      activate_kw={'tag': tag, 'after_tag': sub_tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.xml
index 4af30d2cc..1df845b4d 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_deleteHostingSubscriptionFromRegularisationRequest.xml
@@ -48,24 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-sub_tag = "RegularisationRequest_deleteHostingSubscriptionList"\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=portal.service_module.slapos_crm_delete_acknowledgement.getUid(),\n
-      method_id=\'RegularisationRequest_deleteHostingSubscriptionList\',\n
-      method_args=(sub_tag,),\n
-      # Limit activity number, as method_id also calls searchAndActivate\n
-      activity_count=1,\n
-      packet_size=1,\n
-      activate_kw={\'tag\': tag, \'after_tag\': sub_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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.py
new file mode 100644
index 000000000..110670506
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.py
@@ -0,0 +1,8 @@
+portal = context.getPortalObject()
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      method_id='RegularisationRequest_invalidateIfPersonBalanceIsOk',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.xml
index 9d7a1e54f..1ec79a751 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_invalidateSuspendedRegularisationRequest.xml
@@ -48,18 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      method_id=\'RegularisationRequest_invalidateIfPersonBalanceIsOk\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.py
new file mode 100644
index 000000000..cdac3f99a
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.py
@@ -0,0 +1,17 @@
+portal = context.getPortalObject()
+sub_tag = "RegularisationRequest_stopHostingSubscriptionList"
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=[
+        portal.service_module.slapos_crm_stop_acknowledgement.getUid(),
+        portal.service_module.slapos_crm_delete_reminder.getUid(),
+      ],
+      method_id='RegularisationRequest_stopHostingSubscriptionList',
+      method_args=(sub_tag,),
+      # Limit activity number, as method_id also calls searchAndActivate
+      activity_count=1,
+      packet_size=1,
+      activate_kw={'tag': tag, 'after_tag': sub_tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.xml
index 2c0dcb91c..e4471ef59 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_stopHostingSubscriptionFromRegularisationRequest.xml
@@ -48,27 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-sub_tag = "RegularisationRequest_stopHostingSubscriptionList"\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=[\n
-        portal.service_module.slapos_crm_stop_acknowledgement.getUid(),\n
-        portal.service_module.slapos_crm_delete_reminder.getUid(),\n
-      ],\n
-      method_id=\'RegularisationRequest_stopHostingSubscriptionList\',\n
-      method_args=(sub_tag,),\n
-      # Limit activity number, as method_id also calls searchAndActivate\n
-      activity_count=1,\n
-      packet_size=1,\n
-      activate_kw={\'tag\': tag, \'after_tag\': sub_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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.py
new file mode 100644
index 000000000..7ad418a62
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.py
@@ -0,0 +1,9 @@
+portal = context.getPortalObject()
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=portal.service_module.slapos_crm_acknowledgement.getUid(),
+      method_id='RegularisationRequest_triggerAcknowledgmentEscalation',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.xml
index 01d3505fa..4ed2b4813 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnAcknowledgmentRegularisationRequest.xml
@@ -48,19 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=portal.service_module.slapos_crm_acknowledgement.getUid(),\n
-      method_id=\'RegularisationRequest_triggerAcknowledgmentEscalation\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.py
new file mode 100644
index 000000000..7b65bf5cc
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.py
@@ -0,0 +1,9 @@
+portal = context.getPortalObject()
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=portal.service_module.slapos_crm_delete_reminder.getUid(),
+      method_id='RegularisationRequest_triggerDeleteReminderEscalation',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.xml
index 6bd64c48c..123cacab9 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnDeleteReminderRegularisationRequest.xml
@@ -48,19 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=portal.service_module.slapos_crm_delete_reminder.getUid(),\n
-      method_id=\'RegularisationRequest_triggerDeleteReminderEscalation\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.py
new file mode 100644
index 000000000..a3a4b9660
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.py
@@ -0,0 +1,9 @@
+portal = context.getPortalObject()
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=portal.service_module.slapos_crm_stop_acknowledgement.getUid(),
+      method_id='RegularisationRequest_triggerStopAcknowledgmentEscalation',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.xml
index 85bb2cbd4..e4f2dd404 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopAcknowledgmentRegularisationRequest.xml
@@ -48,19 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=portal.service_module.slapos_crm_stop_acknowledgement.getUid(),\n
-      method_id=\'RegularisationRequest_triggerStopAcknowledgmentEscalation\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.py
new file mode 100644
index 000000000..e09f9821e
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.py
@@ -0,0 +1,9 @@
+portal = context.getPortalObject()
+portal.portal_catalog.searchAndActivate(
+      portal_type="Regularisation Request", 
+      simulation_state=["suspended"],
+      default_resource_uid=portal.service_module.slapos_crm_stop_reminder.getUid(),
+      method_id='RegularisationRequest_triggerStopReminderEscalation',
+      activate_kw={'tag': tag}
+      )
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.xml
index 4c32350db..738603bcd 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Alarm_triggerEscalationOnStopReminderRegularisationRequest.xml
@@ -48,19 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-portal.portal_catalog.searchAndActivate(\n
-      portal_type="Regularisation Request", \n
-      simulation_state=["suspended"],\n
-      default_resource_uid=portal.service_module.slapos_crm_stop_reminder.getUid(),\n
-      method_id=\'RegularisationRequest_triggerStopReminderEscalation\',\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.py
new file mode 100644
index 000000000..f2d62fcaa
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.py
@@ -0,0 +1,21 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+hosting_subscription = context
+assert hosting_subscription.getDefaultDestinationSection() == person_relative_url
+person = hosting_subscription.getDefaultDestinationSectionValue()
+
+slap_state = hosting_subscription.getSlapState()
+if (slap_state in ['start_requested', 'stop_requested']):
+  person.requestSoftwareInstance(
+    state='destroyed',
+    software_release=hosting_subscription.getUrlString(),
+    software_title=hosting_subscription.getTitle(),
+    software_type=hosting_subscription.getSourceReference(),
+    instance_xml=hosting_subscription.getTextContent(),
+    sla_xml=hosting_subscription.getSlaXml(),
+    shared=hosting_subscription.isRootSlave()
+  )
+  return True
+return False
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.xml
index ce58e61d3..ecde787f7 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_deleteFromRegularisationRequest.xml
@@ -48,31 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-hosting_subscription = context\n
-assert hosting_subscription.getDefaultDestinationSection() == person_relative_url\n
-person = hosting_subscription.getDefaultDestinationSectionValue()\n
-\n
-slap_state = hosting_subscription.getSlapState()\n
-if (slap_state in [\'start_requested\', \'stop_requested\']):\n
-  person.requestSoftwareInstance(\n
-    state=\'destroyed\',\n
-    software_release=hosting_subscription.getUrlString(),\n
-    software_title=hosting_subscription.getTitle(),\n
-    software_type=hosting_subscription.getSourceReference(),\n
-    instance_xml=hosting_subscription.getTextContent(),\n
-    sla_xml=hosting_subscription.getSlaXml(),\n
-    shared=hosting_subscription.isRootSlave()\n
-  )\n
-  return True\n
-return False\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>person_relative_url, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.py
new file mode 100644
index 000000000..616da907b
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.py
@@ -0,0 +1,21 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+hosting_subscription = context
+assert hosting_subscription.getDefaultDestinationSection() == person_relative_url
+person = hosting_subscription.getDefaultDestinationSectionValue()
+
+slap_state = hosting_subscription.getSlapState()
+if (slap_state == 'start_requested'):
+  person.requestSoftwareInstance(
+    state='stopped',
+    software_release=hosting_subscription.getUrlString(),
+    software_title=hosting_subscription.getTitle(),
+    software_type=hosting_subscription.getSourceReference(),
+    instance_xml=hosting_subscription.getTextContent(),
+    sla_xml=hosting_subscription.getSlaXml(),
+    shared=hosting_subscription.isRootSlave()
+  )
+  return True
+return False
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.xml
index 8fb66625b..90bf17b63 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/HostingSubscription_stopFromRegularisationRequest.xml
@@ -48,31 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-hosting_subscription = context\n
-assert hosting_subscription.getDefaultDestinationSection() == person_relative_url\n
-person = hosting_subscription.getDefaultDestinationSectionValue()\n
-\n
-slap_state = hosting_subscription.getSlapState()\n
-if (slap_state == \'start_requested\'):\n
-  person.requestSoftwareInstance(\n
-    state=\'stopped\',\n
-    software_release=hosting_subscription.getUrlString(),\n
-    software_title=hosting_subscription.getTitle(),\n
-    software_type=hosting_subscription.getSourceReference(),\n
-    instance_xml=hosting_subscription.getTextContent(),\n
-    sla_xml=hosting_subscription.getSlaXml(),\n
-    shared=hosting_subscription.isRootSlave()\n
-  )\n
-  return True\n
-return False\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>person_relative_url, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.py
new file mode 100644
index 000000000..e8bc50a89
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.py
@@ -0,0 +1,77 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+portal = context.getPortalObject()
+person = context
+ticket_portal_type = "Regularisation Request"
+
+# XXX TODO
+# # Prevent to create 2 tickets during the same transaction
+# transactional_variable = getTransactionalVariable()
+# if tag in transactional_variable:
+#   raise RuntimeError, 'ticket %s already exist' % tag
+# else:
+#   transactional_variable[tag] = None
+
+ticket = portal.portal_catalog.getResultValue(
+  portal_type=ticket_portal_type,
+  default_source_project_uid=person.getUid(),
+  simulation_state=['suspended', 'validated'],
+)
+if (ticket is None) and int(person.Entity_statBalance()) > 0:
+
+  tag = "%s_addRegularisationRequest_inProgress" % person.getUid()
+  if (portal.portal_activities.countMessageWithTag(tag) > 0):
+    # The regularisation request is already under creation but can not be fetched from catalog
+    # As it is not possible to fetch informations, it is better to raise an error
+    return None, None
+
+  # Prevent concurrent transaction to create 2 tickets for the same person
+  person.serialize()
+
+  # Time to create the ticket
+  regularisation_request_template = portal.restrictedTraverse(
+    portal.portal_preferences.getPreferredRegularisationRequestTemplate())
+  ticket = regularisation_request_template.Base_createCloneDocument(batch_mode=1)
+  ticket.edit(
+    source_project_value=context,
+    title='Account regularisation expected for "%s"' % context.getTitle(),
+    destination_decision_value=context,
+    destination_value=context,
+    start_date=DateTime(),
+    resource=portal.portal_preferences.getPreferredRegularisationRequestResource(),
+  )
+  ticket.validate(comment='New automatic ticket for %s' % context.getTitle())
+  ticket.suspend(comment='New automatic ticket for %s' % context.getTitle())
+
+  ticket.reindexObject(activate_kw={'tag': tag})
+
+  notification_message = context.getPortalObject().portal_notifications.getDocumentValue(
+    reference="slapos-crm.create.regularisation.request")
+  if notification_message is None:
+    subject = 'Invoice payment requested'
+    body = """Dear user,
+
+A new invoice has been generated. 
+You can access it in your invoice section at %s.
+
+Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
+
+Regards,
+The slapos team
+""" % portal.portal_preferences.getPreferredSlaposWebSiteUrl()
+
+  else:
+    subject = notification_message.getTitle()
+    body = notification_message.convert(format='text')[1]
+
+  mail_message = ticket.RegularisationRequest_checkToSendUniqEvent(
+    portal.portal_preferences.getPreferredRegularisationRequestResource(),
+    subject,
+    body,
+    'Requested manual payment.')
+
+  return ticket, mail_message
+
+return ticket, None
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.xml
index c7b96f1b0..c6f792408 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/Person_checkToCreateRegularisationRequest.xml
@@ -48,91 +48,6 @@
               </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
-    destination_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
-  notification_message = context.getPortalObject().portal_notifications.getDocumentValue(\n
-    reference="slapos-crm.create.regularisation.request")\n
-  if notification_message is None:\n
-    subject = \'Invoice payment requested\'\n
-    body = """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
-\n
-  else:\n
-    subject = notification_message.getTitle()\n
-    body = notification_message.convert(format=\'text\')[1]\n
-\n
-  mail_message = ticket.RegularisationRequest_checkToSendUniqEvent(\n
-    portal.portal_preferences.getPreferredRegularisationRequestResource(),\n
-    subject,\n
-    body,\n
-    \'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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.py
new file mode 100644
index 000000000..761427727
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.py
@@ -0,0 +1 @@
+context.RegularisationRequest_init()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.xml
index 629844409..1b2facd80 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_afterClone.xml
@@ -48,11 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>context.RegularisationRequest_init()\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.py
new file mode 100644
index 000000000..a18a75e48
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.py
@@ -0,0 +1,62 @@
+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
+else:
+  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 None) or \
+   (open_order.getValidationState() != "validated") or \
+   (len(open_order.contentValues(portal_type="Open Sale Order Line")) != 0):
+    return mail_message, invoice_list
+  else:
+    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.payzen.getUid(),
+          default_destination_section_uid=person.getUid(),
+          simulation_state=["started"],
+          ):
+      
+      if 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())
+
+    # XXX Hardcoded
+    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
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.xml
index 22f7426c0..10668644d 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty.xml
@@ -48,72 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-mail_message = None\n
-invoice_list = []\n
-\n
-state = context.getSimulationState()\n
-person = context.getSourceProjectValue(portal_type="Person")\n
-if (state != \'suspended\') or \\\n
-   (person is None):\n
-  return mail_message, invoice_list\n
-else:\n
-  portal = context.getPortalObject()\n
-\n
-  open_order = portal.portal_catalog.getResultValue(\n
-    portal_type="Open Sale Order",\n
-    validation_state="validated",\n
-    default_destination_decision_uid=person.getUid())\n
-\n
-  if (open_order is None) or \\\n
-   (open_order.getValidationState() != "validated") or \\\n
-   (len(open_order.contentValues(portal_type="Open Sale Order Line")) != 0):\n
-    return mail_message, invoice_list\n
-  else:\n
-    assert open_order.getDestinationDecisionUid() == person.getUid()\n
-    ticket = context\n
-\n
-    for payment in portal.portal_catalog(\n
-          portal_type="Payment Transaction", \n
-          payment_mode_uid=portal.portal_categories.payment_mode.payzen.getUid(),\n
-          default_destination_section_uid=person.getUid(),\n
-          simulation_state=["started"],\n
-          ):\n
-      \n
-      if payment.PaymentTransaction_getPayzenId()[1] is None:\n
-        invoice = payment.getCausalityValue(portal_type="Sale Invoice Transaction")\n
-        assert payment.getDestinationSectionUid() == person.getUid()\n
-        invoice.SaleInvoiceTransaction_createReversalPayzenTransaction()\n
-        invoice_list.append(invoice.getRelativeUrl())\n
-\n
-    # XXX Hardcoded\n
-    cancel_service = portal.service_module.slapos_crm_invoice_cancellation\n
-    mail_message = ticket.RegularisationRequest_checkToSendUniqEvent(\n
-      cancel_service.getRelativeUrl(),\n
-      \'Cancellation of your bill\',\n
-      """Hello,\n
-\n
-Thank you to have used our decentralized Cloud Computing service slapos.org.\n
-\n
-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.\n
-\n
-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.*\n
-\n
-We hope to see you using our services in the future.\n
-\n
-Regards,\n
-The slapos team\n
-""",\n
-      \'Cancelled payment.\')\n
-\n
-return mail_message, invoice_list\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.py
new file mode 100644
index 000000000..f568caf47
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.py
@@ -0,0 +1,50 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+portal = context.getPortalObject()
+ticket = context
+service = portal.restrictedTraverse(service_relative_url)
+assert service.getPortalType() == "Service"
+event_portal_type = "Mail Message"
+
+# XXX TODO
+# # Prevent to create 2 tickets during the same transaction
+# transactional_variable = getTransactionalVariable()
+# if tag in transactional_variable:
+#   raise RuntimeError, 'ticket %s already exist' % tag
+# else:
+#   transactional_variable[tag] = None
+
+event = portal.portal_catalog.getResultValue(
+  portal_type=event_portal_type,
+  default_resource_uid=service.getUid(),
+  default_follow_up_uid=ticket.getUid(),
+)
+
+if (event is None) and (ticket.getSimulationState() == 'suspended'):
+  tag = "%s_addUniqEvent_%s" % (ticket.getUid(), service.getUid())
+  if (portal.portal_activities.countMessageWithTag(tag) > 0):
+    # The event is already under creation but can not be fetched from catalog
+    return None
+
+  # Prevent concurrent transaction to create 2 events for the same ticket
+  ticket.edit(resource=service_relative_url)
+
+  event = portal.event_module.newContent(
+    portal_type=event_portal_type,
+    start_date=DateTime(),
+    destination=ticket.getDestination(),
+    follow_up=ticket.getRelativeUrl(),
+    source=context.getSource(),
+    title=title,
+    resource=service_relative_url,
+    text_content=text_content,
+  )
+
+  portal.portal_workflow.doActionFor(event, 'start_action', send_mail=True, comment=comment)
+  event.stop(comment=comment)
+  event.deliver(comment=comment)
+  event.reindexObject(activate_kw={'tag': tag})
+
+return event
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.xml
index 303cb71e1..b95639f22 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToSendUniqEvent.xml
@@ -48,64 +48,6 @@
               </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
-ticket = context\n
-service = portal.restrictedTraverse(service_relative_url)\n
-assert service.getPortalType() == "Service"\n
-event_portal_type = "Mail Message"\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
-event = portal.portal_catalog.getResultValue(\n
-  portal_type=event_portal_type,\n
-  default_resource_uid=service.getUid(),\n
-  default_follow_up_uid=ticket.getUid(),\n
-)\n
-\n
-if (event is None) and (ticket.getSimulationState() == \'suspended\'):\n
-  tag = "%s_addUniqEvent_%s" % (ticket.getUid(), service.getUid())\n
-  if (portal.portal_activities.countMessageWithTag(tag) > 0):\n
-    # The event is already under creation but can not be fetched from catalog\n
-    return None\n
-\n
-  # Prevent concurrent transaction to create 2 events for the same ticket\n
-  ticket.edit(resource=service_relative_url)\n
-\n
-  event = portal.event_module.newContent(\n
-    portal_type=event_portal_type,\n
-    start_date=DateTime(),\n
-    destination=ticket.getDestination(),\n
-    follow_up=ticket.getRelativeUrl(),\n
-    source=context.getSource(),\n
-    title=title,\n
-    resource=service_relative_url,\n
-    text_content=text_content,\n
-  )\n
-\n
-  portal.portal_workflow.doActionFor(event, \'start_action\', send_mail=True, comment=comment)\n
-  event.stop(comment=comment)\n
-  event.deliver(comment=comment)\n
-  event.reindexObject(activate_kw={\'tag\': tag})\n
-\n
-return event\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>service_relative_url, title, text_content, comment, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.py
new file mode 100644
index 000000000..e7bb3b3cc
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.py
@@ -0,0 +1,24 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+portal = context.getPortalObject()
+ticket = context
+current_service = portal.restrictedTraverse(current_service_relative_url)
+assert current_service.getPortalType() == "Service"
+
+event_portal_type = "Mail Message"
+
+event = portal.portal_catalog.getResultValue(
+  portal_type=event_portal_type,
+  default_resource_uid=current_service.getUid(),
+  default_follow_up_uid=ticket.getUid(),
+  simulation_state="delivered",
+)
+
+if (ticket.getSimulationState() == 'suspended') and (event is not None) and (ticket.getResource() == current_service_relative_url):
+  if (DateTime() - event.getStartDate()) > delay_period_in_days:
+    ticket.RegularisationRequest_checkToSendUniqEvent(next_service_relative_url, title, text_content, comment)
+    return event.getRelativeUrl()
+
+return None
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.xml
index 32a13aced..4bede6112 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_checkToTriggerNextEscalationStep.xml
@@ -48,38 +48,6 @@
               </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
-ticket = context\n
-current_service = portal.restrictedTraverse(current_service_relative_url)\n
-assert current_service.getPortalType() == "Service"\n
-\n
-event_portal_type = "Mail Message"\n
-\n
-event = portal.portal_catalog.getResultValue(\n
-  portal_type=event_portal_type,\n
-  default_resource_uid=current_service.getUid(),\n
-  default_follow_up_uid=ticket.getUid(),\n
-  simulation_state="delivered",\n
-)\n
-\n
-if (ticket.getSimulationState() == \'suspended\') and (event is not None) and (ticket.getResource() == current_service_relative_url):\n
-  if (DateTime() - event.getStartDate()) > delay_period_in_days:\n
-    ticket.RegularisationRequest_checkToSendUniqEvent(next_service_relative_url, title, text_content, comment)\n
-    return event.getRelativeUrl()\n
-\n
-return None\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>delay_period_in_days, current_service_relative_url, next_service_relative_url, title, text_content, comment, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.py
new file mode 100644
index 000000000..dbdb30687
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.py
@@ -0,0 +1,22 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+ticket = context
+state = ticket.getSimulationState()
+person = ticket.getSourceProjectValue(portal_type="Person")
+if (state == 'suspended') and \
+   (person is not None) and \
+   (ticket.getResource() == 'service_module/slapos_crm_delete_acknowledgement'):
+   
+  portal = context.getPortalObject()
+  portal.portal_catalog.searchAndActivate(
+    portal_type="Hosting Subscription",
+    validation_state=["validated"],
+    default_destination_section_uid=person.getUid(),
+    method_id='HostingSubscription_deleteFromRegularisationRequest',
+    method_args=(person.getRelativeUrl(),),
+    activate_kw={'tag': tag}
+  )
+  return True
+return False
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.xml
index dc71357ba..fe78a86c5 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_deleteHostingSubscriptionList.xml
@@ -48,32 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-ticket = context\n
-state = ticket.getSimulationState()\n
-person = ticket.getSourceProjectValue(portal_type="Person")\n
-if (state == \'suspended\') and \\\n
-   (person is not None) and \\\n
-   (ticket.getResource() == \'service_module/slapos_crm_delete_acknowledgement\'):\n
-   \n
-  portal = context.getPortalObject()\n
-  portal.portal_catalog.searchAndActivate(\n
-    portal_type="Hosting Subscription",\n
-    validation_state=["validated"],\n
-    default_destination_section_uid=person.getUid(),\n
-    method_id=\'HostingSubscription_deleteFromRegularisationRequest\',\n
-    method_args=(person.getRelativeUrl(),),\n
-    activate_kw={\'tag\': tag}\n
-  )\n
-  return True\n
-return False\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>tag, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.py
new file mode 100644
index 000000000..92253e5a4
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.py
@@ -0,0 +1 @@
+return context.Ticket_getResourceItemList()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.xml
index 7fe5cc30f..627bcc0cd 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_getResourceItemList.xml
@@ -48,11 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>return context.Ticket_getResourceItemList()\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.py
new file mode 100644
index 000000000..304f4dcf9
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.py
@@ -0,0 +1,14 @@
+# Define Reference from ID provided by portal_ids
+portal = context.getPortalObject()
+type_definition = context.getTypeInfo()
+
+short_portal_type = type_definition.getShortTitle()
+if not short_portal_type:
+  short_portal_type = ''.join(s for s in type_definition.getId() if s.isupper())
+
+id_group = ('reference', short_portal_type)
+default = 1
+new_id = portal.portal_ids.generateNewId(id_group=id_group, default=default)
+reference = '%s-%s' % (short_portal_type, new_id)
+
+context.setReference(reference)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.xml
index 5ae7edaba..c6b600602 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_init.xml
@@ -48,24 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string># Define Reference from ID provided by portal_ids\n
-portal = context.getPortalObject()\n
-type_definition = context.getTypeInfo()\n
-\n
-short_portal_type = type_definition.getShortTitle()\n
-if not short_portal_type:\n
-  short_portal_type = \'\'.join(s for s in type_definition.getId() if s.isupper())\n
-\n
-id_group = (\'reference\', short_portal_type)\n
-default = 1\n
-new_id = portal.portal_ids.generateNewId(id_group=id_group, default=default)\n
-reference = \'%s-%s\' % (short_portal_type, new_id)\n
-\n
-context.setReference(reference)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>**kw</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.py
new file mode 100644
index 000000000..7abd57fa1
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.py
@@ -0,0 +1,12 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+state = context.getSimulationState()
+person = context.getSourceProjectValue(portal_type="Person")
+if (state != 'suspended') or \
+   (person is None) or \
+   (int(person.Entity_statBalance()) > 0):
+  return
+else:
+  context.invalidate(comment="Automatically disabled as balance is %s" % person.Entity_statBalance())
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.xml
index 1b700e117..71b424043 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_invalidateIfPersonBalanceIsOk.xml
@@ -48,26 +48,6 @@
               </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
-state = context.getSimulationState()\n
-person = context.getSourceProjectValue(portal_type="Person")\n
-if (state != \'suspended\') or \\\n
-   (person is None) or \\\n
-   (int(person.Entity_statBalance()) > 0):\n
-  return\n
-else:\n
-  context.invalidate(comment="Automatically disabled as balance is %s" % person.Entity_statBalance())\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.py
new file mode 100644
index 000000000..7256ad0a3
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.py
@@ -0,0 +1,22 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+ticket = context
+state = ticket.getSimulationState()
+person = ticket.getSourceProjectValue(portal_type="Person")
+if (state == 'suspended') and \
+   (person is not None) and \
+   (ticket.getResource() in ['service_module/slapos_crm_stop_acknowledgement', 'service_module/slapos_crm_delete_reminder']):
+   
+  portal = context.getPortalObject()
+  portal.portal_catalog.searchAndActivate(
+    portal_type="Hosting Subscription",
+    validation_state=["validated"],
+    default_destination_section_uid=person.getUid(),
+    method_id='HostingSubscription_stopFromRegularisationRequest',
+    method_args=(person.getRelativeUrl(),),
+    activate_kw={'tag': tag}
+  )
+  return True
+return False
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.xml
index 5c6fc2f1e..b0438b1bc 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_stopHostingSubscriptionList.xml
@@ -48,32 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-ticket = context\n
-state = ticket.getSimulationState()\n
-person = ticket.getSourceProjectValue(portal_type="Person")\n
-if (state == \'suspended\') and \\\n
-   (person is not None) and \\\n
-   (ticket.getResource() in [\'service_module/slapos_crm_stop_acknowledgement\', \'service_module/slapos_crm_delete_reminder\']):\n
-   \n
-  portal = context.getPortalObject()\n
-  portal.portal_catalog.searchAndActivate(\n
-    portal_type="Hosting Subscription",\n
-    validation_state=["validated"],\n
-    default_destination_section_uid=person.getUid(),\n
-    method_id=\'HostingSubscription_stopFromRegularisationRequest\',\n
-    method_args=(person.getRelativeUrl(),),\n
-    activate_kw={\'tag\': tag}\n
-  )\n
-  return True\n
-return False\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>tag, REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.py
new file mode 100644
index 000000000..c1d731ffc
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.py
@@ -0,0 +1,30 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.acknowledgment.escalation")
+if notification_message is None:
+  subject = 'Reminder: invoice payment requested'
+  body = """Dear user,
+
+We would like to remind you the unpaid invoice you have on %s.
+If no payment is done during the coming days, we will stop all your current instances to free some hardware resources.
+
+Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
+
+Regards,
+The slapos team
+""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()
+
+else:
+  subject = notification_message.getTitle()
+  body = notification_message.convert(format='text')[1]
+
+return context.RegularisationRequest_checkToTriggerNextEscalationStep(
+  38,
+  'service_module/slapos_crm_acknowledgement',
+  'service_module/slapos_crm_stop_reminder',
+  subject,
+  body,
+  'Stopping reminder.',
+)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.xml
index 95a98551a..419280e5b 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerAcknowledgmentEscalation.xml
@@ -48,40 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.acknowledgment.escalation")\n
-if notification_message is None:\n
-  subject = \'Reminder: invoice payment requested\'\n
-  body = """Dear user,\n
-\n
-We would like to remind you the unpaid invoice you have on %s.\n
-If no payment is done during the coming days, we will stop all your current instances to free some hardware resources.\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
-""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()\n
-\n
-else:\n
-  subject = notification_message.getTitle()\n
-  body = notification_message.convert(format=\'text\')[1]\n
-\n
-return context.RegularisationRequest_checkToTriggerNextEscalationStep(\n
-  38,\n
-  \'service_module/slapos_crm_acknowledgement\',\n
-  \'service_module/slapos_crm_stop_reminder\',\n
-  subject,\n
-  body,\n
-  \'Stopping reminder.\',\n
-)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.py
new file mode 100644
index 000000000..f9afee7ea
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.py
@@ -0,0 +1,29 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.delete.reminder.escalation")
+if notification_message is None:
+  subject = 'Acknowledgment: instances deleted'
+  body = """Dear user,
+
+Despite our last reminder, you still have an unpaid invoice on %s.
+We will now delete all your instances.
+
+Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
+
+Regards,
+The slapos team
+""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()
+else:
+  subject = notification_message.getTitle()
+  body = notification_message.convert(format='text')[1]
+
+return context.RegularisationRequest_checkToTriggerNextEscalationStep(
+  2,
+  'service_module/slapos_crm_delete_reminder',
+  'service_module/slapos_crm_delete_acknowledgement',
+  subject,
+  body,
+  'Deleting acknowledgment.',
+)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.xml
index e7b7f4b29..062df7f08 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerDeleteReminderEscalation.xml
@@ -48,39 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.delete.reminder.escalation")\n
-if notification_message is None:\n
-  subject = \'Acknowledgment: instances deleted\'\n
-  body = """Dear user,\n
-\n
-Despite our last reminder, you still have an unpaid invoice on %s.\n
-We will now delete all your instances.\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
-""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()\n
-else:\n
-  subject = notification_message.getTitle()\n
-  body = notification_message.convert(format=\'text\')[1]\n
-\n
-return context.RegularisationRequest_checkToTriggerNextEscalationStep(\n
-  2,\n
-  \'service_module/slapos_crm_delete_reminder\',\n
-  \'service_module/slapos_crm_delete_acknowledgement\',\n
-  subject,\n
-  body,\n
-  \'Deleting acknowledgment.\',\n
-)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.py
new file mode 100644
index 000000000..051f2baf2
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.py
@@ -0,0 +1,29 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.stop.acknowledgment.escalation")
+if notification_message is None:
+  subject = 'Last reminder: invoice payment requested'
+  body = """Dear user,
+
+We would like to remind you the unpaid invoice you have on %s.
+If no payment is done during the coming days, we will delete all your instances.
+
+Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
+
+Regards,
+The slapos team
+""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()
+else:
+  subject = notification_message.getTitle()
+  body = notification_message.convert(format='text')[1]
+
+return context.RegularisationRequest_checkToTriggerNextEscalationStep(
+  13,
+  'service_module/slapos_crm_stop_acknowledgement',
+  'service_module/slapos_crm_delete_reminder',
+  subject,
+  body,
+  'Deleting reminder.',
+)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.xml
index a5351f227..c2d6f4f08 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopAcknowledgmentEscalation.xml
@@ -48,39 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.stop.acknowledgment.escalation")\n
-if notification_message is None:\n
-  subject = \'Last reminder: invoice payment requested\'\n
-  body = """Dear user,\n
-\n
-We would like to remind you the unpaid invoice you have on %s.\n
-If no payment is done during the coming days, we will delete all your instances.\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
-""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()\n
-else:\n
-  subject = notification_message.getTitle()\n
-  body = notification_message.convert(format=\'text\')[1]\n
-\n
-return context.RegularisationRequest_checkToTriggerNextEscalationStep(\n
-  13,\n
-  \'service_module/slapos_crm_stop_acknowledgement\',\n
-  \'service_module/slapos_crm_delete_reminder\',\n
-  subject,\n
-  body,\n
-  \'Deleting reminder.\',\n
-)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.py
new file mode 100644
index 000000000..2dafeb5b3
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.py
@@ -0,0 +1,29 @@
+from zExceptions import Unauthorized
+if REQUEST is not None:
+  raise Unauthorized
+
+notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.stop.reminder.escalation")
+if notification_message is None:
+  subject = 'Acknowledgment: instances stopped'
+  body = """Dear user,
+
+Despite our last reminder, you still have an unpaid invoice on %s.
+We will now stop all your current instances to free some hardware resources.
+
+Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.
+
+Regards,
+The slapos team
+""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()
+else:
+  subject = notification_message.getTitle()
+  body = notification_message.convert(format='text')[1]
+
+return context.RegularisationRequest_checkToTriggerNextEscalationStep(
+  7,
+  'service_module/slapos_crm_stop_reminder',
+  'service_module/slapos_crm_stop_acknowledgement',
+  subject,
+  body,
+  'Stopping acknowledgment.',
+)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.xml
index 9bd5cfa2a..b36e4e507 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/RegularisationRequest_triggerStopReminderEscalation.xml
@@ -48,39 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from zExceptions import Unauthorized\n
-if REQUEST is not None:\n
-  raise Unauthorized\n
-\n
-notification_message = context.getPortalObject().portal_notifications.getDocumentValue(reference="slapos-crm.stop.reminder.escalation")\n
-if notification_message is None:\n
-  subject = \'Acknowledgment: instances stopped\'\n
-  body = """Dear user,\n
-\n
-Despite our last reminder, you still have an unpaid invoice on %s.\n
-We will now stop all your current instances to free some hardware resources.\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
-""" % context.getPortalObject().portal_preferences.getPreferredSlaposWebSiteUrl()\n
-else:\n
-  subject = notification_message.getTitle()\n
-  body = notification_message.convert(format=\'text\')[1]\n
-\n
-return context.RegularisationRequest_checkToTriggerNextEscalationStep(\n
-  7,\n
-  \'service_module/slapos_crm_stop_reminder\',\n
-  \'service_module/slapos_crm_stop_acknowledgement\',\n
-  subject,\n
-  body,\n
-  \'Stopping acknowledgment.\',\n
-)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>REQUEST=None</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.png b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbde3c7fb587d9d6b06ace9a833c1fb09d9bea20
GIT binary patch
literal 1510
zcmV<C1sVE@P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%h)G02RCwCNS6gfpRT%!}vNOHxvh8lS
z<<d%9wpFPmMjA{LqG+NqBuWr5Q4@_JL?6(^V7xsL@c~~%eCI)tU?S>+4<M-Fq9$Av
zQEJ+1khZW}TBJzZWiPWkbNtWTc4jYyL<nd1%Q<sq=KSCJ{{Q^vjKCPf?JR;r;LQ8c
zeyX+;`fst#V}#Ai-k#z$WT%%I?9+v9>3HOxrz~dm9e@(O{&0HkhODxg0kgjH$Cv%%
z7wYy<v(rbwFc5Df;|wB<^aZf1zX4(mK`qvjYF{hFkRS%ArXd9J`cl`lL&zq<Z6wC_
zcR2k;1;`UDorIxHgJmZyBVwM662t=8pxUt77IYg92|koiT>)*DCZ|G7kHQ;vMFn&Q
zBbA`pCr#tEYm)SW^CUAFvce2lW`YL0Ok~f)m^u!YpSBfo$VhX@pjtL`R)K&)?wmPi
z%|c{mB{0DzAz1%Fm?k=puDih~W~H{L!Di1wpZp%izo)E0M6L!WQdtdd!!YJmB0#2e
zd$zh(H0lW8&cgDS0KuXb>Vh1M!<ZgGVRR3vbCo(BB67Jabjy}gM4t=zO&cEF?7!f-
zw&47DTWsh>p!Yq9jmybZ8A8qislpgsSmRf50rMFCVQbNs0{J$$;6BJT4T!`aMbpxC
zP(q7rHQb8auOblNNP!zdA$ib>3CSRSvekAKs1}4C0?XPwvavj}`4iAnGG>n-LE^}}
zsPA|L9S?0mU988>X!f(jCeZl|t)?016F-_$W}YA|Rlw&0&aM(bjB7}cdZ~bxdJWyN
z9Ku%)VCa)o7(KMrl)2O`YWD_8WK9$kX#%+<p9Q!}su9pV{+}D9R9-`!m_tWn2Kj-H
zFu3<Q>Pr{n!*-k6`x=Zwp47NT1kzNe%`tSniVIkwc%x~P^^}qM2gb|@@`=OH&L2cR
zdDNk7N)u5Gq$c-c==0~%^XwNiCDF}Ca;P1FJJvw^>oYKl4}lcqHYzJ%pyDbJYh#dG
zR-ktIn+UHxgz&nbAT{@U)X1A^)J-11-v_tYt3`0tP&(Jrb2^M%%7Sj$s<I4=s8#|C
z`q8-ls7c6uzMz{VvZp@4%=l@tE4V}?S~-FCCtze}Y2QkfjW3qEz`@)*i-ge1ZK&^i
z%lA%HEnsZlJ7u{;?Oso=OqnQkfm|AdPWfh&#Z6L!h%8x&#j9RLZ0Tb@9-#-eL7N;v
z_Uyi*LgU|Jdh8^^i&warR0*|0iu53V>G!fAthx+)=Ucd|A%)<@0~p@98pB_`PI7C0
z5)bd-CfxUeG^NX@_m*W+H1&}iu2o-#rK#8rMhciZ8gy|3kUst)26k`s5m2IWs9kG)
z?`R{3N__?~)=M#vnIjPy{^X;!J&5@){c3`@d0(`a?hWq7r8E0{!^=w^_q{7l4N`LQ
zZ75KqU9<{vWvRHT0+A<oL79KA3Ep=4!<1Do9^T;}ymf`|-2l^&o1XA16<$P3wlLRb
z#C)5P&LjjpZSOsK{Fr}f24lYa)`a}A!h_j)#=9N+c0(oBiQMEl^Lk*{%UJf}PV2<{
z@kT^FvMDTsuU{yh10@QwyPN$4j=r%3n(hll^t6y#EuAoi&sRysdT~pZX=#1;%0jc<
z8m4}wWU!|4gNC<sHKO8SgjI6^KP<@eXd04&Y+@Ke(*I7+shk=A|ARnnZZ~Z(HdfIE
zXGeZM5pVCi9}3B&L|YMPXuc_5BKfPApiLzphnqn*$d))#MnEgD4MPcG`=7~^eOAxt
zE%+!Jg~5bhbjCK9eVPe^xsmh04-z6g$(bo`uEYL~6>fkpiCO+(L`ZQ_m~Gfgz{v~T
zXf1ac5Ad5rfQKmmhRfJw4A*W60f&SG;U;O%tfcM&Wdv?l`A>iW0D1c<a5!6m6aWAK
M07*qoM6N<$f;uPC=Kufz

literal 0
HcmV?d00001

diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.xml
index 054643045..d601ac845 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm/rss_feed_image.xml
@@ -18,36 +18,6 @@
             <key> <string>content_type</string> </key>
             <value> <string>image/png</string> </value>
         </item>
-        <item>
-            <key> <string>data</string> </key>
-            <value> <string encoding="base64">iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
-bWFnZVJlYWR5ccllPAAABYhJREFUeNrEV1tsFFUY/uayM73ssu1ut+XSSlu2VaklRhpME6JoojEk
-ShAxURONIUQf0MRgvD0Q8QFfRHznQZFgIuqDDyCo4aImXBRRatpqkLawW1qkSNtlL7M7c/zP3HZm
-L4VECGf3yzlzZub83/n+//znjMAYw+0sgkPgzPvRfqq2E/pvsc1jhM3L3p7iNWSnlxns04Vt6Xjk
-nqcsZvUdgBK9/nB67oasspkBs77yx5f94xfq9lCz00fAMBBvJOMMIoz0BbCrvwFiDUEt1pJqXyvE
-kCAGqKYhBPH6Ute0Q8gmwW0kxvZ3OP1FBcgTLJ2EoU2DZScsI2KejBLEAtmg2rDaFnQbDgk+lFBd
-AW2WJqdCTI/CG3ZFBXQGI5Wg2SdN47VrkvSC8yQzGbLCDFhmgga7TGTPw5g6DpafthVxyEhzyKBa
-NnRWgYBB7pw5Z81CZGYlMMEmIVj/QJgmOo+uu8EoZqW2p8Fmz0Kf/B7Gv6esQUSuBidSWQ1uwzDm
-VSJApnR7trpWNOoI4M7C8pcAwaIW6oIcjMOYHkBhdA+pc5U6HSJyuSt0y5ZTRJ8L+E0bHt3sv+C5
-tuD8eFts6EWg9z2IjcvJVRlCzgKpwhhcWONXcQHzGP5ha9GXAvk2uOA+yDUNiMQfRdPSdVBCi2w1
-3IrcryIQ30iBG0IhedCKCckgfrLVdhWoFoQeAsvaPLKxPLL5E9BTMmaPH0HiyLuo73gEHQ9tQV2s
-x85o9rPEJtD5DK2mGegTP5pTZp4gLVXA5wLOrhJAjGtIkHqpgJZ6Dd2xHMJXDmDok1UYPbTVlLnU
-LWr3BkpkTRQTaQK5JJ8FuEuqEdA9/p8bpFReQ52YQ0djBvmBjzC49znqSxfjw3ab2vsajEKe1LhG
-BNJUp80xdL2KC1iheKNpk/WUkfkHxswI8onD0M4fRD551KFsShNRDKQm92Po8+fR8+wXNCXRzUdy
-qB2BO9ZA++szMIoPgRTkNiorYKDiKhBrY5BbVqB2+ZsIrz2E8LqfIDX3e9TIm2rUTR7A3we32KtF
-cNVQOtfSczqMXMqCbtmqsgyLqFYCC/rRuP6oSch9vqCbJLKnPsDM+GmyK7hEJFo5gfYnYGRnad9K
-lY0vlrrAwdw7i4TQym2o73vL905ULWBs3ztluUPtXk+uTJkodYFcGoRO+WaTxU1Sg4gsWYnFq15F
-bOljPh6hB7ZBmxxA9uy+okLj32J67CTCi1e4mVQJtUKK9CB/6feyIKy6DHvnW7irIYXgxQMY3rka
-w1+9TnJrfhIP7+Am3PeCNKXLp/eWZVI09ZEbrlVfhqWp2A1GCpg6GnRxA5A+/iEGdm/0EVCicahd
-a33vaCOHSn0GMdZLMZCZIxEZ/uSjtj2I+S/9aoK3eV+0lu4N7salM/t8w8tLHve9K04NUnLybShQ
-o120CnJlqbiqApEnd0GZf68J3nb6w5RVLx7e4R+8dYXv3QDTkJue8CsVXkRLtjDXZsR8m5HOJAQ8
-be89efyYf2kGY7771oT8scKD2XnGux37dkMl1onc5DnzemDXy1j24k7rxPzxRkQ9siksg69fKJ4D
-JQqyu5v9BI6+sQSa7gtF9LSQWi2dMIbPV0nFenFLlmlpfffKQrPdGqZ+pWSwpvKDhrd0NaLiYYRV
-cwE/LMjzaBqSgmxiGEHS/07PqZwZ//+DQG1uN20wNlbRBWdHfj4Rb++7HwrJpERbEWhovilfIvmr
-l6BNJSCHm0E2yJY4UkZAK7ANQwlh+5/Jk31Wz+gt+CgahcGEX3TGNpd9mgmCuZHzwA8SIjzJmSlu
-rsP+jRVugC+JWf5hREhxUZht2EvAyQvcaC13GQ/wm0SAhyj/hsvYZAzXbgkBh4QD4SZpz6yk7gJl
-BG5X+U+AAQB5+ylwOFuBFAAAAABJRU5ErkJggg==</string> </value>
-        </item>
         <item>
             <key> <string>height</string> </key>
             <value> <int>32</int> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.py
new file mode 100644
index 000000000..d40b3cbab
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.py
@@ -0,0 +1,15 @@
+portal = context.getPortalObject()
+
+category_public = portal.restrictedTraverse("portal_categories/allocation_scope/open/public", None)
+category_friend = portal.restrictedTraverse("portal_categories/allocation_scope/open/friend", None)
+
+if category_public is not None:
+  portal.portal_catalog.searchAndActivate(
+    portal_type='Computer',
+    default_allocation_scope_uid=[category_public.getUid(), category_friend.getUid()],
+    validation_state="validated",
+    method_id='Computer_checkAndUpdateAllocationScope',
+    activate_kw={'tag': tag}
+  )
+
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.xml
index 30f87da20..1266aa30b 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdateComputerAllocationScope.xml
@@ -48,25 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-\n
-category_public = portal.restrictedTraverse("portal_categories/allocation_scope/open/public", None)\n
-category_friend = portal.restrictedTraverse("portal_categories/allocation_scope/open/friend", None)\n
-\n
-if category_public is not None:\n
-  portal.portal_catalog.searchAndActivate(\n
-    portal_type=\'Computer\',\n
-    default_allocation_scope_uid=[category_public.getUid(), category_friend.getUid()],\n
-    validation_state="validated",\n
-    method_id=\'Computer_checkAndUpdateAllocationScope\',\n
-    activate_kw={\'tag\': tag}\n
-  )\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.py
new file mode 100644
index 000000000..09e0c85c5
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.py
@@ -0,0 +1,16 @@
+portal = context.getPortalObject()
+
+category_personal = portal.restrictedTraverse("portal_categories/allocation_scope/open/personal", None)
+
+if category_personal is not None:
+  portal.portal_catalog.searchAndActivate(
+    portal_type='Computer', 
+    validation_state='validated', 
+    modification_date=(DateTime() - 30).strftime('<=%Y/%m/%d'), 
+    default_allocation_scope_uid=category_personal.getUid(), 
+    left_join_list=['aggregate_related_uid'], 
+    aggregate_related_uid=None,
+    method_id='Computer_checkAndUpdatePersonalAllocationScope',
+    activate_kw={'tag': tag})
+
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.xml
index c37301e4a..3fe05eda5 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkAndUpdatePersonalComputerAllocationScope.xml
@@ -48,30 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string encoding="cdata"><![CDATA[
-
-portal = context.getPortalObject()\n
-\n
-category_personal = portal.restrictedTraverse("portal_categories/allocation_scope/open/personal", None)\n
-\n
-if category_personal is not None:\n
-  portal.portal_catalog.searchAndActivate(\n
-    portal_type=\'Computer\', \n
-    validation_state=\'validated\', \n
-    modification_date=(DateTime() - 30).strftime(\'<=%Y/%m/%d\'), \n
-    default_allocation_scope_uid=category_personal.getUid(), \n
-    left_join_list=[\'aggregate_related_uid\'], \n
-    aggregate_related_uid=None,\n
-    method_id=\'Computer_checkAndUpdatePersonalAllocationScope\',\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>
@@ -83,4 +59,4 @@ context.activate(after_tag=tag).getId()\n
       </dictionary>
     </pickle>
   </record>
-</ZopeData>
\ No newline at end of file
+</ZopeData>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.py
new file mode 100644
index 000000000..fba3683b6
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.py
@@ -0,0 +1,18 @@
+portal = context.getPortalObject()
+public_category_uid = portal.restrictedTraverse(
+  "portal_categories/allocation_scope/open/public", None).getUid()
+
+friend_category_uid = portal.restrictedTraverse(
+  "portal_categories/allocation_scope/open/friend", None).getUid()
+
+
+if None not in [friend_category_uid, public_category_uid]:
+  portal.portal_catalog.searchAndActivate(
+    portal_type = 'Computer',
+    validation_state = 'validated',
+    default_allocation_scope_uid = [public_category_uid, friend_category_uid],
+    method_id = 'Computer_checkState',
+    activate_kw = {'tag':tag}  
+  )
+
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.xml
index 7abb5b4cf..e297aa941 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkComputerState.xml
@@ -48,28 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-public_category_uid = portal.restrictedTraverse(\n
-  "portal_categories/allocation_scope/open/public", None).getUid()\n
-\n
-friend_category_uid = portal.restrictedTraverse(\n
-  "portal_categories/allocation_scope/open/friend", None).getUid()\n
-\n
-\n
-if None not in [friend_category_uid, public_category_uid]:\n
-  portal.portal_catalog.searchAndActivate(\n
-    portal_type = \'Computer\',\n
-    validation_state = \'validated\',\n
-    default_allocation_scope_uid = [public_category_uid, friend_category_uid],\n
-    method_id = \'Computer_checkState\',\n
-    activate_kw = {\'tag\':tag}  \n
-  )\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.py
new file mode 100644
index 000000000..6cd2505b9
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.py
@@ -0,0 +1,10 @@
+portal = context.getPortalObject()
+
+portal.portal_catalog.searchAndActivate(
+    portal_type='Hosting Subscription',
+    validation_state='validated',
+    method_id='HostingSubscription_checkSofwareInstanceState',
+    activate_kw = {'tag':tag}
+  )
+
+context.activate(after_tag=tag).getId()
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.xml
index f018dd6f4..a09f1f61b 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Alarm_checkHostingSubscriptionState.xml
@@ -48,20 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-\n
-portal.portal_catalog.searchAndActivate(\n
-    portal_type=\'Hosting Subscription\',\n
-    validation_state=\'validated\',\n
-    method_id=\'HostingSubscription_checkSofwareInstanceState\',\n
-    activate_kw = {\'tag\':tag}\n
-  )\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>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py
new file mode 100644
index 000000000..a7a1bad31
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py
@@ -0,0 +1,55 @@
+from DateTime import DateTime
+
+portal = context.getPortalObject()
+source_project_value = portal.restrictedTraverse(source_relative_url)
+
+if source_project_value.getPortalType() == "Computer":
+  destination_decision = source_project_value.getSourceAdministration()
+elif source_project_value.getPortalType() == "Software Instance":
+  destination_decision = source_project_value.getSpecialiseValue().getDestinationSection()
+elif source_project_value.getPortalType() == "Hosting Subscription":
+  destination_decision = source_project_value.getDestinationSection()
+elif source_project_value.getPortalType() == "Software Installation":
+  destination_decision = source_project_value.getDestinationSection()
+else:
+  destination_decision = None
+
+if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):
+  # Stop ticket creation
+  return
+
+support_request_in_progress = portal.portal_catalog.getResultValue(
+  portal_type = 'Support Request',
+  title = title,
+  simulation_state = ["validated", "submitted", "suspended"],
+  source_project_uid = source_project_value.getUid(),
+)
+
+if support_request_in_progress is not None:
+  return support_request_in_progress
+
+support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)
+
+if support_request_in_progress is not None:
+  return portal.restrictedTraverse(support_request_in_progress)
+
+resource = portal.service_module.\
+                  slapos_crm_monitoring.getRelativeUrl()
+
+support_request = portal.\
+    support_request_module.\
+    slapos_crm_support_request_template_for_monitoring.\
+    Base_createCloneDocument(batch_mode=1)
+support_request.edit(
+    title = title,
+    description = description,
+    start_date = DateTime(),
+    destination_decision=destination_decision,
+    source_project_value = source_project_value,
+    resource=resource
+  )
+support_request.validate()
+
+context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())
+
+return support_request
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml
index f1e767147..3629c9852 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml
@@ -48,65 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from DateTime import DateTime\n
-\n
-portal = context.getPortalObject()\n
-source_project_value = portal.restrictedTraverse(source_relative_url)\n
-\n
-if source_project_value.getPortalType() == "Computer":\n
-  destination_decision = source_project_value.getSourceAdministration()\n
-elif source_project_value.getPortalType() == "Software Instance":\n
-  destination_decision = source_project_value.getSpecialiseValue().getDestinationSection()\n
-elif source_project_value.getPortalType() == "Hosting Subscription":\n
-  destination_decision = source_project_value.getDestinationSection()\n
-elif source_project_value.getPortalType() == "Software Installation":\n
-  destination_decision = source_project_value.getDestinationSection()\n
-else:\n
-  destination_decision = None\n
-\n
-if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):\n
-  # Stop ticket creation\n
-  return\n
-\n
-support_request_in_progress = portal.portal_catalog.getResultValue(\n
-  portal_type = \'Support Request\',\n
-  title = title,\n
-  simulation_state = ["validated", "submitted", "suspended"],\n
-  source_project_uid = source_project_value.getUid(),\n
-)\n
-\n
-if support_request_in_progress is not None:\n
-  return support_request_in_progress\n
-\n
-support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)\n
-\n
-if support_request_in_progress is not None:\n
-  return portal.restrictedTraverse(support_request_in_progress)\n
-\n
-resource = portal.service_module.\\\n
-                  slapos_crm_monitoring.getRelativeUrl()\n
-\n
-support_request = portal.\\\n
-    support_request_module.\\\n
-    slapos_crm_support_request_template_for_monitoring.\\\n
-    Base_createCloneDocument(batch_mode=1)\n
-support_request.edit(\n
-    title = title,\n
-    description = description,\n
-    start_date = DateTime(),\n
-    destination_decision=destination_decision,\n
-    source_project_value = source_project_value,\n
-    resource=resource\n
-  )\n
-support_request.validate()\n
-\n
-context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())\n
-\n
-return support_request\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>title, description, source_relative_url</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.py
new file mode 100644
index 000000000..c07c31edb
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.py
@@ -0,0 +1,57 @@
+from DateTime import DateTime
+
+computer = context
+portal = context.getPortalObject()
+allocation_scope = computer.getAllocationScope()
+computer_reference = computer.getReference()
+
+if allocation_scope not in ['open/public', 'open/friend', 'open/personal']:
+  return
+
+if allocation_scope == target_allocation_scope:
+  # already changed
+  return
+
+person = computer.getSourceAdministrationValue(portal_type="Person")
+if not person:
+  return
+
+if not person.Person_isServiceProvider():
+  edit_kw = {
+    'allocation_scope': target_allocation_scope,
+  }
+
+  # Create a ticket (or re-open it) for this issue!
+  request_title = 'We have changed allocation scope for %s' % computer_reference
+  request_description = 'Allocation scope has been changed to ' \
+                       '%s for %s' % (target_allocation_scope, computer_reference)
+            
+  support_request = context.Base_generateSupportRequestForSlapOS(
+                 request_title,
+                 request_description,
+                 computer.getRelativeUrl()
+               )
+
+  if support_request.getSimulationState() != "validated":
+    support_request.validate()
+  
+  # Send notification message
+  message = request_description
+  notification_message = portal.portal_notifications.getDocumentValue(
+                 reference=notification_message_reference)
+
+  if notification_message is not None:
+    mapping_dict = {'computer_title':computer.getTitle(),
+                    'computer_id':computer_reference,
+                    'allocation_scope':allocation_scope}
+
+    message = notification_message.asText(
+              substitution_method_parameter_dict={'mapping_dict': mapping_dict})
+
+  event = support_request.SupportRequest_trySendNotificationMessage(
+           request_title, message, person.getRelativeUrl())
+
+  if event is not None:
+    computer.edit(**edit_kw)
+
+  return support_request
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.xml
index d55bb8b56..acefb66ed 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdateAllocationScope.xml
@@ -48,67 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from DateTime import DateTime\n
-\n
-computer = context\n
-portal = context.getPortalObject()\n
-allocation_scope = computer.getAllocationScope()\n
-computer_reference = computer.getReference()\n
-\n
-if allocation_scope not in [\'open/public\', \'open/friend\', \'open/personal\']:\n
-  return\n
-\n
-if allocation_scope == target_allocation_scope:\n
-  # already changed\n
-  return\n
-\n
-person = computer.getSourceAdministrationValue(portal_type="Person")\n
-if not person:\n
-  return\n
-\n
-if not person.Person_isServiceProvider():\n
-  edit_kw = {\n
-    \'allocation_scope\': target_allocation_scope,\n
-  }\n
-\n
-  # Create a ticket (or re-open it) for this issue!\n
-  request_title = \'We have changed allocation scope for %s\' % computer_reference\n
-  request_description = \'Allocation scope has been changed to \' \\\n
-                       \'%s for %s\' % (target_allocation_scope, computer_reference)\n
-            \n
-  support_request = context.Base_generateSupportRequestForSlapOS(\n
-                 request_title,\n
-                 request_description,\n
-                 computer.getRelativeUrl()\n
-               )\n
-\n
-  if support_request.getSimulationState() != "validated":\n
-    support_request.validate()\n
-  \n
-  # Send notification message\n
-  message = request_description\n
-  notification_message = portal.portal_notifications.getDocumentValue(\n
-                 reference=notification_message_reference)\n
-\n
-  if notification_message is not None:\n
-    mapping_dict = {\'computer_title\':computer.getTitle(),\n
-                    \'computer_id\':computer_reference,\n
-                    \'allocation_scope\':allocation_scope}\n
-\n
-    message = notification_message.asText(\n
-              substitution_method_parameter_dict={\'mapping_dict\': mapping_dict})\n
-\n
-  event = support_request.SupportRequest_trySendNotificationMessage(\n
-           request_title, message, person.getRelativeUrl())\n
-\n
-  if event is not None:\n
-    computer.edit(**edit_kw)\n
-\n
-  return support_request\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>target_allocation_scope=\'open/personal\', notification_message_reference=\'slapos-crm-computer_allocation_scope.notification\'</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.py
new file mode 100644
index 000000000..30d986133
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.py
@@ -0,0 +1,3 @@
+return context.Computer_checkAndUpdateAllocationScope(
+  target_allocation_scope = 'close/termination',
+  notification_message_reference='slapos-crm-computer_personal_allocation_scope.notification')
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.xml
index fa227f811..96583f6b4 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkAndUpdatePersonalAllocationScope.xml
@@ -48,13 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>return context.Computer_checkAndUpdateAllocationScope(\n
-  target_allocation_scope = \'close/termination\',\n
-  notification_message_reference=\'slapos-crm-computer_personal_allocation_scope.notification\')\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>**kw</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.py
new file mode 100644
index 000000000..44cc3f6d2
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.py
@@ -0,0 +1,64 @@
+from DateTime import DateTime
+import json
+
+portal = context.getPortalObject()
+
+if portal.ERP5Site_isSupportRequestCreationClosed():
+  # Stop ticket creation
+  return
+
+reference = context.getReference()
+computer_title = context.getTitle()
+ticket_title = "[MONITORING] Lost contact with computer %s" % reference
+description = ""
+should_notify = True
+last_contact = "No Contact Information"
+
+memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(
+  key_prefix='slap_tool',
+  plugin_path='portal_memcached/default_memcached_plugin')
+
+try:
+  d = memcached_dict[reference]
+  d = json.loads(d)
+  last_contact = DateTime(d.get('created_at'))
+  if (DateTime() - last_contact) > 0.01:
+    description = "The Computer %s (%s) has not contacted the server for more than 30 minutes" \
+    "(last contact date: %s)" % (computer_title, reference, last_contact)
+  else:
+    should_notify = False
+except KeyError:
+  ticket_title = "[MONITORING] No information about %s" % reference
+  description = "The Computer %s (%s)  has not contacted the server (No Contact Information)" % (
+                  computer_title, reference)
+
+if should_notify:
+  support_request = context.Base_generateSupportRequestForSlapOS(
+    ticket_title,
+    description,
+    context.getRelativeUrl()
+  )
+
+  person = context.getSourceAdministrationValue(portal_type="Person")
+  if not person:
+    return support_request
+
+  # Send Notification message
+  notification_reference = 'slapos-crm-computer_check_state.notification'
+  notification_message = portal.portal_notifications.getDocumentValue(
+                 reference=notification_reference)
+
+  if notification_message is None:
+    message = """%s""" % description
+  else:
+    mapping_dict = {'computer_title':context.getTitle(),
+                    'computer_id':reference,
+                    'last_contact':last_contact}
+    message = notification_message.asText(
+              substitution_method_parameter_dict={'mapping_dict':mapping_dict})
+
+  support_request.SupportRequest_trySendNotificationMessage(
+              ticket_title,
+              message, person.getRelativeUrl())
+              
+  return support_request
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.xml
index 79374cd1d..4442e3b2e 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Computer_checkState.xml
@@ -48,78 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string encoding="cdata"><![CDATA[
-
-from DateTime import DateTime\n
-import json\n
-\n
-portal = context.getPortalObject()\n
-\n
-if portal.ERP5Site_isSupportRequestCreationClosed():\n
-  # Stop ticket creation\n
-  return\n
-\n
-reference = context.getReference()\n
-computer_title = context.getTitle()\n
-ticket_title = "[MONITORING] Lost contact with computer %s" % reference\n
-description = ""\n
-should_notify = True\n
-last_contact = "No Contact Information"\n
-\n
-memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
-  key_prefix=\'slap_tool\',\n
-  plugin_path=\'portal_memcached/default_memcached_plugin\')\n
-\n
-try:\n
-  d = memcached_dict[reference]\n
-  d = json.loads(d)\n
-  last_contact = DateTime(d.get(\'created_at\'))\n
-  if (DateTime() - last_contact) > 0.01:\n
-    description = "The Computer %s (%s) has not contacted the server for more than 30 minutes" \\\n
-    "(last contact date: %s)" % (computer_title, reference, last_contact)\n
-  else:\n
-    should_notify = False\n
-except KeyError:\n
-  ticket_title = "[MONITORING] No information about %s" % reference\n
-  description = "The Computer %s (%s)  has not contacted the server (No Contact Information)" % (\n
-                  computer_title, reference)\n
-\n
-if should_notify:\n
-  support_request = context.Base_generateSupportRequestForSlapOS(\n
-    ticket_title,\n
-    description,\n
-    context.getRelativeUrl()\n
-  )\n
-\n
-  person = context.getSourceAdministrationValue(portal_type="Person")\n
-  if not person:\n
-    return support_request\n
-\n
-  # Send Notification message\n
-  notification_reference = \'slapos-crm-computer_check_state.notification\'\n
-  notification_message = portal.portal_notifications.getDocumentValue(\n
-                 reference=notification_reference)\n
-\n
-  if notification_message is None:\n
-    message = """%s""" % description\n
-  else:\n
-    mapping_dict = {\'computer_title\':context.getTitle(),\n
-                    \'computer_id\':reference,\n
-                    \'last_contact\':last_contact}\n
-    message = notification_message.asText(\n
-              substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
-\n
-  support_request.SupportRequest_trySendNotificationMessage(\n
-              ticket_title,\n
-              message, person.getRelativeUrl())\n
-              \n
-  return support_request\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.py
new file mode 100644
index 000000000..59c7b9479
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.py
@@ -0,0 +1,13 @@
+# HARDCODED LIMIT TO BE MOVED TO GLOBAL PREFERENCES
+limit = 5
+
+kw['limit'] = limit
+kw['portal_type'] = 'Support Request'
+kw['simulation_state'] = ["validated","submitted"]
+if destination_decision:
+  kw['default_destination_decision_uid'] = context.restrictedTraverse(
+                          destination_decision).getUid()
+
+support_request_list = context.portal_catalog(**kw)
+
+return len(support_request_list) >= limit
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.xml
index b2ef19aeb..34e9851d3 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ERP5Site_isSupportRequestCreationClosed.xml
@@ -48,27 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string encoding="cdata"><![CDATA[
-
-# HARDCODED LIMIT TO BE MOVED TO GLOBAL PREFERENCES\n
-limit = 5\n
-\n
-kw[\'limit\'] = limit\n
-kw[\'portal_type\'] = \'Support Request\'\n
-kw[\'simulation_state\'] = ["validated","submitted"]\n
-if destination_decision:\n
-  kw[\'default_destination_decision_uid\'] = context.restrictedTraverse(\n
-                          destination_decision).getUid()\n
-\n
-support_request_list = context.portal_catalog(**kw)\n
-\n
-return len(support_request_list) >= limit\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>destination_decision=None, **kw</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.py
new file mode 100644
index 000000000..d34af07a6
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.py
@@ -0,0 +1,3 @@
+kw['simulation_state'] = ['validated','submitted']
+kw['sort_on'] = [('modification_date', 'DESC'),]
+return context.searchFolder(**kw)
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.xml
index 0cd202cd4..e9d76cda4 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Folder_getOpenTicketList.xml
@@ -48,13 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>kw[\'simulation_state\'] = [\'validated\',\'submitted\']\n
-kw[\'sort_on\'] = [(\'modification_date\', \'DESC\'),]\n
-return context.searchFolder(**kw)\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>**kw</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.py
new file mode 100644
index 000000000..586b4ddd2
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.py
@@ -0,0 +1,49 @@
+from DateTime import DateTime
+from Products.ERP5Type.DateUtils import addToDate
+
+hosting_subscription = context
+portal = context.getPortalObject()
+
+if portal.ERP5Site_isSupportRequestCreationClosed():
+  # Stop ticket creation
+  return
+
+date_check_limit = addToDate(DateTime(), to_add={'hour': -1})
+
+if (date_check_limit - hosting_subscription.getCreationDate()) < 0:
+  # Too early to check
+  return
+
+#if not source_instance:
+#  return
+
+software_instance_list = hosting_subscription.getSpecialiseRelatedValueList(
+                 portal_type=["Software Instance", "Slave Instance"])
+
+has_newest_allocated_instance = False
+has_unallocated_instance = False
+failing_instance = None
+
+# Check if at least one software Instance is Allocated
+for instance in software_instance_list:
+  if instance.getSlapState() not in ["start_requested", "stop_requested"]:
+    continue
+
+  if (date_check_limit - instance.getCreationDate()) < 0:
+    continue
+
+  if instance.getAggregateValue() is not None:
+    has_newest_allocated_instance = True
+    if instance.getPortalType() == "Software Instance" and \
+        instance.SoftwareInstance_hasReportedError():
+      return context.HostingSubscription_createSupportRequestEvent(
+        instance, 'slapos-crm-hosting-subscription-instance-state.notification')
+  else:
+    has_unallocated_instance = True
+    failing_instance = instance
+
+  if has_unallocated_instance and has_newest_allocated_instance:
+    return context.HostingSubscription_createSupportRequestEvent(
+      failing_instance, 'slapos-crm-hosting-subscription-instance-allocation.notification')
+
+return
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.xml
index 693e491ea..b55f1f223 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_checkSoftwareInstanceState.xml
@@ -48,63 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string encoding="cdata"><![CDATA[
-
-from DateTime import DateTime\n
-from Products.ERP5Type.DateUtils import addToDate\n
-\n
-hosting_subscription = context\n
-portal = context.getPortalObject()\n
-\n
-if portal.ERP5Site_isSupportRequestCreationClosed():\n
-  # Stop ticket creation\n
-  return\n
-\n
-date_check_limit = addToDate(DateTime(), to_add={\'hour\': -1})\n
-\n
-if (date_check_limit - hosting_subscription.getCreationDate()) < 0:\n
-  # Too early to check\n
-  return\n
-\n
-#if not source_instance:\n
-#  return\n
-\n
-software_instance_list = hosting_subscription.getSpecialiseRelatedValueList(\n
-                 portal_type=["Software Instance", "Slave Instance"])\n
-\n
-has_newest_allocated_instance = False\n
-has_unallocated_instance = False\n
-failing_instance = None\n
-\n
-# Check if at least one software Instance is Allocated\n
-for instance in software_instance_list:\n
-  if instance.getSlapState() not in ["start_requested", "stop_requested"]:\n
-    continue\n
-\n
-  if (date_check_limit - instance.getCreationDate()) < 0:\n
-    continue\n
-\n
-  if instance.getAggregateValue() is not None:\n
-    has_newest_allocated_instance = True\n
-    if instance.getPortalType() == "Software Instance" and \\\n
-        instance.SoftwareInstance_hasReportedError():\n
-      return context.HostingSubscription_createSupportRequestEvent(\n
-        instance, \'slapos-crm-hosting-subscription-instance-state.notification\')\n
-  else:\n
-    has_unallocated_instance = True\n
-    failing_instance = instance\n
-\n
-  if has_unallocated_instance and has_newest_allocated_instance:\n
-    return context.HostingSubscription_createSupportRequestEvent(\n
-      failing_instance, \'slapos-crm-hosting-subscription-instance-allocation.notification\')\n
-\n
-return\n
-
-
-]]></string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.py
new file mode 100644
index 000000000..179a8fc0c
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.py
@@ -0,0 +1,37 @@
+portal = context.getPortalObject()
+
+ticket_title = "Hosting Subscription %s is failing." % context.getTitle()
+
+description = "%s contains software instances which are unallocated or reporting errors." % (
+        context.getTitle())
+       
+support_request = context.Base_generateSupportRequestForSlapOS(
+  ticket_title,
+  description,
+  context.getRelativeUrl())
+
+if support_request is None:
+  return
+  
+person = context.getDestinationSectionValue(portal_type="Person")
+if not person:
+  return
+  
+if support_request.getSimulationState() != "validated":
+  support_request.validate()
+
+# Send Notification message
+message = description
+
+notification_reference = notification_message_reference
+notification_message = portal.portal_notifications.getDocumentValue(
+                 reference=notification_reference)
+if notification_message is not None:
+  mapping_dict = {'hosting_subscription_title':context.getTitle(),
+                  'instance': instance.getTitle()}
+
+  message = notification_message.asText(
+              substitution_method_parameter_dict={'mapping_dict':mapping_dict})
+  
+return support_request.SupportRequest_trySendNotificationMessage(
+              ticket_title, message, person.getRelativeUrl())
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.xml
index 5582b3bac..541ea4fc0 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/HostingSubscription_createSupportRequestEvent.xml
@@ -48,47 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>portal = context.getPortalObject()\n
-\n
-ticket_title = "Hosting Subscription %s is failing." % context.getTitle()\n
-\n
-description = "%s contains software instances which are unallocated or reporting errors." % (\n
-        context.getTitle())\n
-       \n
-support_request = context.Base_generateSupportRequestForSlapOS(\n
-  ticket_title,\n
-  description,\n
-  context.getRelativeUrl())\n
-\n
-if support_request is None:\n
-  return\n
-  \n
-person = context.getDestinationSectionValue(portal_type="Person")\n
-if not person:\n
-  return\n
-  \n
-if support_request.getSimulationState() != "validated":\n
-  support_request.validate()\n
-\n
-# Send Notification message\n
-message = description\n
-\n
-notification_reference = notification_message_reference\n
-notification_message = portal.portal_notifications.getDocumentValue(\n
-                 reference=notification_reference)\n
-if notification_message is not None:\n
-  mapping_dict = {\'hosting_subscription_title\':context.getTitle(),\n
-                  \'instance\': instance.getTitle()}\n
-\n
-  message = notification_message.asText(\n
-              substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
-  \n
-return support_request.SupportRequest_trySendNotificationMessage(\n
-              ticket_title, message, person.getRelativeUrl())\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>instance, notification_message_reference</string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.py
new file mode 100644
index 000000000..ea515bbad
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.py
@@ -0,0 +1,9 @@
+if 'service_provider' in context.getRoleList():
+  return True
+
+for assignment in context.contentValues(portal_type="Assignment"):
+  if assignment.getValidationState() == "open" and \
+    assignment.getRole() == 'service_provider':
+    return True
+
+return False
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.xml
index 4f266b958..4c293779e 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Person_isServiceProvider.xml
@@ -48,19 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>if \'service_provider\' in context.getRoleList():\n
-  return True\n
-\n
-for assignment in context.contentValues(portal_type="Assignment"):\n
-  if assignment.getValidationState() == "open" and \\\n
-    assignment.getRole() == \'service_provider\':\n
-    return True\n
-\n
-return False\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.py
new file mode 100644
index 000000000..e5044f514
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.py
@@ -0,0 +1,22 @@
+from DateTime import DateTime
+import json
+
+memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(
+  key_prefix='slap_tool',
+  plugin_path='portal_memcached/default_memcached_plugin')
+
+try:
+  d = memcached_dict[context.getReference()]
+except KeyError:
+  # Information not available
+  return None
+
+d = json.loads(d)
+result = d['text']
+last_contact = DateTime(d.get('created_at'))
+
+# Optimise by checking memcache information first.
+if result.startswith('#error '):
+  return last_contact
+
+return None
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.xml
index c2c13d4a0..e2d84937d 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstallation_hasReportedError.xml
@@ -48,32 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from DateTime import DateTime\n
-import json\n
-\n
-memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
-  key_prefix=\'slap_tool\',\n
-  plugin_path=\'portal_memcached/default_memcached_plugin\')\n
-\n
-try:\n
-  d = memcached_dict[context.getReference()]\n
-except KeyError:\n
-  # Information not available\n
-  return None\n
-\n
-d = json.loads(d)\n
-result = d[\'text\']\n
-last_contact = DateTime(d.get(\'created_at\'))\n
-\n
-# Optimise by checking memcache information first.\n
-if result.startswith(\'#error \'):\n
-  return last_contact\n
-\n
-return None\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.py
new file mode 100644
index 000000000..0d905e40b
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.py
@@ -0,0 +1,24 @@
+from DateTime import DateTime
+import json
+
+memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(
+  key_prefix='slap_tool',
+  plugin_path='portal_memcached/default_memcached_plugin')
+
+if context.getAggregateValue(portal_type="Computer Partition") is not None:
+  try:
+    d = memcached_dict[context.getReference()]
+  except KeyError:
+    return  
+
+  d = json.loads(d)
+  result = d['text']
+  last_contact = DateTime(d.get('created_at'))
+
+  # Optimise by checking memcache information first.
+  if result.startswith('#error '):
+    return last_contact
+
+  # XXX time limit of 48 hours for run at least once.
+
+return None
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.xml
index b897891f1..483fc8901 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SoftwareInstance_hasReportedError.xml
@@ -48,34 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>from DateTime import DateTime\n
-import json\n
-\n
-memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
-  key_prefix=\'slap_tool\',\n
-  plugin_path=\'portal_memcached/default_memcached_plugin\')\n
-\n
-if context.getAggregateValue(portal_type="Computer Partition") is not None:\n
-  try:\n
-    d = memcached_dict[context.getReference()]\n
-  except KeyError:\n
-    return  \n
-\n
-  d = json.loads(d)\n
-  result = d[\'text\']\n
-  last_contact = DateTime(d.get(\'created_at\'))\n
-\n
-  # Optimise by checking memcache information first.\n
-  if result.startswith(\'#error \'):\n
-    return last_contact\n
-\n
-  # XXX time limit of 48 hours for run at least once.\n
-\n
-return None\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string></string> </value>
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py
new file mode 100644
index 000000000..b9d8384d8
--- /dev/null
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py
@@ -0,0 +1,31 @@
+support_request = context
+portal = context.getPortalObject()
+
+resource = portal.service_module.slapos_crm_information.getRelativeUrl()
+# create Web message if needed for this ticket
+last_event = context.portal_catalog.getResultValue(
+             title=message_title,
+             follow_up_uid=support_request.getUid(), 
+             sort_on=[('delivery.start_date', 'DESC')],
+)
+if last_event:
+  # User has already been notified for this problem.
+  return last_event
+
+event = portal.event_module.slapos_crm_web_message_template.\
+  Base_createCloneDocument(batch_mode=1)
+
+event.edit(
+  title=message_title,
+  text_content=message,
+  start_date = DateTime(),
+  resource = resource,
+  source=source_relative_url,
+  follow_up=support_request.getRelativeUrl(),
+)
+event.stop()
+event.deliver()
+
+event.immediateReindexObject()
+
+return event
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml
index ad293e57a..a1e036a9c 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml
@@ -48,41 +48,6 @@
               </object>
             </value>
         </item>
-        <item>
-            <key> <string>_body</string> </key>
-            <value> <string>support_request = context\n
-portal = context.getPortalObject()\n
-\n
-resource = portal.service_module.slapos_crm_information.getRelativeUrl()\n
-# create Web message if needed for this ticket\n
-last_event = context.portal_catalog.getResultValue(\n
-             title=message_title,\n
-             follow_up_uid=support_request.getUid(), \n
-             sort_on=[(\'delivery.start_date\', \'DESC\')],\n
-)\n
-if last_event:\n
-  # User has already been notified for this problem.\n
-  return last_event\n
-\n
-event = portal.event_module.slapos_crm_web_message_template.\\\n
-  Base_createCloneDocument(batch_mode=1)\n
-\n
-event.edit(\n
-  title=message_title,\n
-  text_content=message,\n
-  start_date = DateTime(),\n
-  resource = resource,\n
-  source=source_relative_url,\n
-  follow_up=support_request.getRelativeUrl(),\n
-)\n
-event.stop()\n
-event.deliver()\n
-\n
-event.immediateReindexObject()\n
-\n
-return event\n
-</string> </value>
-        </item>
         <item>
             <key> <string>_params</string> </key>
             <value> <string>message_title, message, source_relative_url</string> </value>
-- 
2.30.9