Commit 4a9d5ff2 authored by Romain Courteaud's avatar Romain Courteaud 🐸

Be sure that each subscription period is one month.

Periodicity calculation should only be based on Hosting Subscription
periodicity, and not hardcoded in a script.

Limit as possible number of modifications on open order line.

Subscription start date should be based on beginning of the slap workflow, to
ensure compatibility with old data.
parent 74f13417
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
from Products.ERP5Type.DateUtils import addToDate, getClosestDate\n
\n
hosting_subscription = context\n
portal = context.getPortalObject()\n
\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
start_date = None\n
for item in workflow_item_list:\n
start_date = item.get(\'time\')\n
if start_date:\n
break\n
\n
if start_date is None:\n
# Compatibility with old Hosting subscription\n
start_date = hosting_subscription.getCreationDate()\n
\n
start_date = getClosestDate(target_date=start_date, precision=\'day\')\n
\n
return start_date\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_calculateSubscriptionStartDate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from zExceptions import Unauthorized\n
if REQUEST is not None:\n
raise Unauthorized\n
\n
from Products.ERP5Type.DateUtils import addToDate, getClosestDate\n
\n
hosting_subscription = context\n
portal = context.getPortalObject()\n
\n
start_date = context.HostingSubscription_calculateSubscriptionStartDate()\n
\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
result_date = None\n
for item in workflow_item_list:\n
if item.get(\'slap_state\') == \'destroy_requested\':\n
end_date = item.get(\'time\')\n
result_date = getClosestDate(target_date=end_date, precision=\'day\')\n
if result_date <= end_date:\n
result_date = addToDate(result_date, to_add={\'day\': 1})\n
break\n
\n
return result_date\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>HostingSubscription_calculateSubscriptionStopDate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -89,40 +89,20 @@ def newOpenOrder(open_sale_order):\n
def storeWorkflowComment(document, comment):\n
portal.portal_workflow.doActionFor(document, \'edit_action\', comment=comment)\n
\n
def getHostingSubscriptionSimulationStartDate(hosting_subscription):\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
start_date = None\n
for item in workflow_item_list:\n
if item.get(\'action\') == \'request_instance\':\n
start_date = item.get(\'time\')\n
break\n
if start_date is None:\n
# Compatibility with old Hosting subscription\n
start_date = hosting_subscription.getCreationDate()\n
\n
start_date = getClosestDate(target_date=start_date, precision=\'day\')\n
while start_date.day() >= 29:\n
start_date = addToDate(start_date, to_add={\'day\': -1})\n
\n
return start_date\n
\n
def getHostingSubscriptionSimulationStopDate(hosting_subscription, start_date):\n
workflow_item_list = portal.portal_workflow.getInfoFor(\n
ob=hosting_subscription,\n
name=\'history\',\n
wf_id=\'instance_slap_interface_workflow\')\n
end_date = now\n
for item in workflow_item_list:\n
if item.get(\'slap_state\') == \'destroy_requested\':\n
end_date = item.get(\'time\')\n
break\n
\n
stop_date = start_date\n
while stop_date <= end_date:\n
stop_date = addToDate(stop_date, to_add={\'month\': 1})\n
def calculateOpenOrderLineStopDate(open_order_line, hosting_subscription):\n
end_date = hosting_subscription.HostingSubscription_calculateSubscriptionStopDate()\n
if end_date is None: \n
# Be sure that start date is different from stop date\n
next_stop_date = hosting_subscription.getNextPeriodicalDate(hosting_subscription.HostingSubscription_calculateSubscriptionStartDate())\n
current_stop_date = next_stop_date\n
while next_stop_date < now:\n
# Return result should be < now, it order to provide stability in simulation (destruction if it happen should be >= now)\n
current_stop_date = next_stop_date\n
next_stop_date = \\\n
hosting_subscription.getNextPeriodicalDate(current_stop_date)\n
return addToDate(current_stop_date, to_add={\'second\': -1})\n
else:\n
stop_date = end_date\n
return stop_date\n
\n
# Prevent concurrent transaction to update the open order\n
......@@ -161,20 +141,12 @@ if open_sale_order is not None:\n
assert current_start_date < current_stop_date\n
\n
hosting_subscription = open_order_line.getAggregateValue(portal_type=\'Hosting Subscription\')\n
assert current_start_date == getHostingSubscriptionSimulationStartDate(hosting_subscription)\n
assert current_start_date == hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()\n
\n
# First check if the hosting subscription has been correctly simulated (this script may run only once per year...)\n
stop_date = getHostingSubscriptionSimulationStopDate(hosting_subscription, current_start_date)\n
stop_date = calculateOpenOrderLineStopDate(open_order_line, hosting_subscription)\n
if current_stop_date != stop_date:\n
# Bingo, new subscription to generate\n
try:\n
assert stop_date == getHostingSubscriptionSimulationStopDate(hosting_subscription, current_stop_date)\n
except:\n
raise ValueError, "%s (%s) != %s (%s)" % (stop_date,\n
current_start_date,\n
getHostingSubscriptionSimulationStopDate(hosting_subscription,\n
current_stop_date),\n
current_stop_date)\n
open_order_line.edit(\n
stop_date=stop_date,\n
activate_kw=activate_kw)\n
......@@ -229,12 +201,12 @@ if (add_line_list):\n
for hosting_subscription in add_line_list:\n
open_sale_order_line = open_sale_order_line_template.Base_createCloneDocument(batch_mode=1,\n
destination=open_sale_order)\n
start_date = getHostingSubscriptionSimulationStartDate(hosting_subscription)\n
start_date = hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()\n
open_sale_order_line.edit(\n
activate_kw=activate_kw,\n
title=hosting_subscription.getTitle(),\n
start_date=start_date,\n
stop_date=getHostingSubscriptionSimulationStopDate(hosting_subscription, start_date),\n
stop_date=calculateOpenOrderLineStopDate(open_sale_order_line, hosting_subscription),\n
aggregate_value=hosting_subscription,\n
)\n
storeWorkflowComment(open_sale_order_line, "Created for %s" % hosting_subscription.getRelativeUrl())\n
......
......@@ -13,7 +13,7 @@ from Products.SlapOS.tests.testSlapOSMixin import \
import os
import tempfile
from DateTime import DateTime
from Products.ERP5Type.DateUtils import addToDate
from Products.ERP5Type.DateUtils import addToDate, getClosestDate
from zExceptions import Unauthorized
class Simulator:
......@@ -798,6 +798,11 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.assertEqual(open_sale_order_line_template.getPrice(),
line.getPrice())
self.assertEqual(DateTime().earliestTime(), line.getStartDate())
self.assertEqual(DateTime().day(),
subscription.getPeriodicityMonthDay())
start_date = addToDate(line.getStartDate(), to_add={'month': 1})
start_date = addToDate(start_date, to_add={'second': -1})
self.assertEqual(start_date, line.getStopDate())
def test_usualLifetime_HostingSubscription(self):
person = self.portal.person_module.template_member\
......@@ -811,14 +816,17 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.portal.portal_workflow._jumpToStateFor(subscription, 'validated')
request_time = DateTime('2012/01/01')
subscription.workflow_history['instance_slap_interface_workflow'].append({
subscription.workflow_history['instance_slap_interface_workflow'] = [{
'comment':'Simulated request instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'start_requested',
'time': request_time,
'action': 'request_instance'
})
}]
subscription.edit(periodicity_month_day_list=[])
subscription.fixConsistency()
self.assertEqual(subscription.getPeriodicityMonthDay(), 1)
self.tic()
subscription.HostingSubscription_requestUpdateOpenSaleOrder()
......@@ -842,10 +850,9 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
# calculate stop date to be after now, begin with start date with precision
# of month
stop_date = request_time
now = DateTime()
while stop_date < now:
stop_date = addToDate(stop_date, to_add={'month': 1})
stop_date = getClosestDate(target_date=now, precision='month')
stop_date = addToDate(stop_date, to_add={'second': -1})
self.assertEqual(stop_date, line.getStopDate())
self.assertEqual(subscription.getRelativeUrl(), line.getAggregate())
......@@ -918,10 +925,7 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.assertEqual(open_sale_order_line_template.getPrice(),
line.getPrice())
self.assertEqual(request_time, archived_line.getStartDate())
now = DateTime()
while stop_date <= destroy_time:
stop_date = addToDate(stop_date, to_add={'month': 1})
self.assertEqual(stop_date, line.getStopDate())
self.assertEqual(DateTime('2112/02/02'), line.getStopDate())
def test_lateAnalysed_HostingSubscription(self):
person = self.portal.person_module.template_member\
......@@ -934,6 +938,7 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
destination_section=person.getRelativeUrl())
self.portal.portal_workflow._jumpToStateFor(subscription, 'validated')
subscription.workflow_history['instance_slap_interface_workflow'] = []
request_time = DateTime('2012/01/01')
subscription.workflow_history['instance_slap_interface_workflow'].append({
'comment':'Simulated request instance',
......@@ -953,6 +958,8 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
'time': destroy_time,
'action': 'request_destroy'
})
subscription.edit(periodicity_month_day_list=[])
subscription.fixConsistency()
self.tic()
subscription.HostingSubscription_requestUpdateOpenSaleOrder()
......@@ -988,10 +995,7 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
line.getPrice())
self.assertEqual(request_time, line.getStartDate())
stop_date = request_time
while stop_date <= destroy_time:
stop_date = addToDate(stop_date, to_add={'month': 1})
self.assertEqual(stop_date, line.getStopDate())
self.assertEqual(DateTime('2012/02/02'), line.getStopDate())
new_open_sale_order = [x for x in open_sale_order_list \
if x.getValidationState() == 'validated'][0].getObject()
......@@ -1012,14 +1016,16 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.portal.portal_workflow._jumpToStateFor(subscription, 'validated')
request_time = DateTime('2012/01/01')
subscription.workflow_history['instance_slap_interface_workflow'].append({
subscription.workflow_history['instance_slap_interface_workflow'] = [{
'comment':'Simulated request instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'start_requested',
'time': request_time,
'action': 'request_instance'
})
}]
subscription.edit(periodicity_month_day_list=[])
subscription.fixConsistency()
self.tic()
subscription.HostingSubscription_requestUpdateOpenSaleOrder()
......@@ -1056,9 +1062,12 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
# calculate stop date to be after now, begin with start date with precision
# of month
stop_date = request_time
next_stop_date = stop_date
now = DateTime()
while stop_date < now:
stop_date = addToDate(stop_date, to_add={'month': 1})
while next_stop_date < now:
stop_date = next_stop_date
next_stop_date = addToDate(stop_date, to_add={'month': 1})
stop_date = addToDate(stop_date, to_add={'second': -1})
self.assertEqual(stop_date, line.getStopDate())
subscription2 = self.portal.hosting_subscription_module\
......@@ -1069,14 +1078,16 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.portal.portal_workflow._jumpToStateFor(subscription2, 'validated')
request_time_2 = DateTime('2012/08/01')
subscription2.workflow_history['instance_slap_interface_workflow'].append({
subscription2.workflow_history['instance_slap_interface_workflow'] = [{
'comment':'Simulated request instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'start_requested',
'time': request_time_2,
'action': 'request_instance'
})
}]
subscription2.edit(periodicity_month_day_list=[])
subscription2.fixConsistency()
self.tic()
subscription2.HostingSubscription_requestUpdateOpenSaleOrder()
......@@ -1106,9 +1117,12 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
line.getPrice())
stop_date_2 = request_time_2
next_stop_date_2 = stop_date_2
now = DateTime()
while stop_date_2 < now:
stop_date_2 = addToDate(stop_date_2, to_add={'month': 1})
while next_stop_date_2 < now:
stop_date_2 = next_stop_date_2
next_stop_date_2 = addToDate(stop_date_2, to_add={'month': 1})
stop_date_2 = addToDate(stop_date_2, to_add={'second': -1})
validated_line_1 = [q for q in validated_line_list if q.getAggregate() == \
subscription.getRelativeUrl()][0]
......@@ -1257,7 +1271,7 @@ class TestHostingSubscription_requestUpdateOpenSaleOrder(testSlapOSMixin):
self.assertEqual(open_sale_order_line_template.getPrice(),
line.getPrice())
self.assertEqual(DateTime().earliestTime(), line.getStartDate())
self.assertEqual(addToDate(line.getStartDate(), to_add={'month': 1}),
self.assertEqual(addToDate(line.getStartDate(), to_add={'day': 1}),
line.getStopDate())
new_open_sale_order = [x for x in open_sale_order_list \
......
......@@ -4,6 +4,7 @@ from Products.SlapOS.tests.testSlapOSMixin import \
import transaction
from Products.ERP5Type.tests.utils import createZODBPythonScript
from DateTime import DateTime
from Products.ERP5Type.DateUtils import addToDate
class TestSlapOSAccountingInteractionWorkflow(testSlapOSMixin):
def beforeTearDown(self):
......@@ -139,6 +140,24 @@ class TestSlapOSAccountingInteractionWorkflow(testSlapOSMixin):
instance.requestStop(**request_kw)
self.assertEqual(instance.getCausalityState(), 'diverged')
def _simulateHostingSubscription_calculateSubscriptionStartDate(self, date):
script_name = 'HostingSubscription_calculateSubscriptionStartDate'
if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom,
script_name,
'*args, **kwargs',
'# Script body\n'
"""from DateTime import DateTime
return DateTime('%s') """ % date.ISO())
transaction.commit()
def _dropHostingSubscription_calculateSubscriptionStartDate(self):
script_name = 'HostingSubscription_calculateSubscriptionStartDate'
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
def test_HostingSubscription_fixConsistency(self,
date=DateTime('2012/01/15'), day=15):
new_id = self.generateNewId()
......@@ -155,23 +174,18 @@ class TestSlapOSAccountingInteractionWorkflow(testSlapOSMixin):
self.assertEqual(item.getPeriodicityMinute(), None)
self.assertEqual(item.getPeriodicityMonthDay(), None)
self._simulateHostingSubscription_calculateSubscriptionStartDate(date)
try:
from Products.ERP5Type.Base import Base
Base.original_getCreationDate = Base.getCreationDate
def getCreationDate(*args, **kwargs):
return date
Base.getCreationDate = getCreationDate
item.fixConsistency()
finally:
Base.getCreationDate = Base.original_getCreationDate
delattr(Base, 'original_getCreationDate')
self._dropHostingSubscription_calculateSubscriptionStartDate()
self.assertEqual(item.getPeriodicityHourList(), [0])
self.assertEqual(item.getPeriodicityMinuteList(), [0])
self.assertEqual(item.getPeriodicityMonthDay(), day)
def test_HostingSubscription_fixConsistency_today_after_28(self):
self.test_HostingSubscription_fixConsistency(DateTime('2012/01/30'), 28)
self.test_HostingSubscription_fixConsistency(DateTime('2012/01/29'), 28)
def test_HostingSubscription_manageAfter(self):
class DummyTestException(Exception):
......
......@@ -7,10 +7,119 @@
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin, withAbort
from zExceptions import Unauthorized
from DateTime import DateTime
class TestSlapOSAccounting(testSlapOSMixin):
def createHostingSubscription(self):
new_id = self.generateNewId()
return self.portal.hosting_subscription_module.newContent(
portal_type='Hosting Subscription',
title="Subscription %s" % new_id,
reference="TESTHS-%s" % new_id,
)
@withAbort
def test_Service_getPriceCalculationOperandDict(self):
service = self.portal.service_module.newContent(portal_type='Service')
self.assertEqual({'price': 0.0},
service.Service_getPriceCalculationOperandDict())
@withAbort
def test_HS_calculateSubscriptionStartDate_REQUEST_disallowed(self):
item = self.createHostingSubscription()
self.assertRaises(
Unauthorized,
item.HostingSubscription_calculateSubscriptionStartDate,
REQUEST={})
@withAbort
def test_HS_calculateSubscriptionStartDate_noWorkflow(self):
item = self.createHostingSubscription()
item.workflow_history['instance_slap_interface_workflow'] = []
date = item.HostingSubscription_calculateSubscriptionStartDate()
self.assertEqual(date, item.getCreationDate().earliestTime())
@withAbort
def test_HS_calculateSubscriptionStartDate_withRequest(self):
item = self.createHostingSubscription()
item.workflow_history['instance_slap_interface_workflow'] = [{
'comment':'Directly request the instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'draft',
'time': DateTime('2012/11/15 11:11'),
'action': 'request_instance'
}]
date = item.HostingSubscription_calculateSubscriptionStartDate()
self.assertEqual(date, DateTime('2012/11/15'))
@withAbort
def test_HS_calculateSubscriptionStartDate_withRequestEndOfMonth(self):
item = self.createHostingSubscription()
item.workflow_history['instance_slap_interface_workflow'] = [{
'comment':'Directly request the instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'draft',
'time': DateTime('2012/11/30 11:11'),
'action': 'request_instance'
}]
date = item.HostingSubscription_calculateSubscriptionStartDate()
self.assertEqual(date, DateTime('2012/11/30'))
@withAbort
def test_HS_calculateSubscriptionStartDate_withRequestAfterDestroy(self):
item = self.createHostingSubscription()
destroy_date = DateTime('2012/10/30 11:11')
request_date = DateTime('2012/11/30 11:11')
item.workflow_history['instance_slap_interface_workflow'] = []
item.workflow_history['instance_slap_interface_workflow'].append({
'comment':'Directly destroy',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'destroy_requested',
'time': destroy_date,
'action': 'request_destroy'
})
item.workflow_history['instance_slap_interface_workflow'].append({
'comment':'Directly request the instance',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'draft',
'time': request_date,
'action': 'request_instance'
})
date = item.HostingSubscription_calculateSubscriptionStartDate()
self.assertEqual(date, DateTime('2012/10/30'))
@withAbort
def test_HS_calculateSubscriptionStopDate_REQUEST_disallowed(self):
item = self.createHostingSubscription()
self.assertRaises(
Unauthorized,
item.HostingSubscription_calculateSubscriptionStopDate,
REQUEST={})
@withAbort
def test_HS_calculateSubscriptionStopDate_withDestroy(self):
item = self.createHostingSubscription()
destroy_date = DateTime('2012/10/30')
item.workflow_history['instance_slap_interface_workflow'].append({
'comment':'Directly destroy',
'error_message': '',
'actor': 'ERP5TypeTestCase',
'slap_state': 'destroy_requested',
'time': destroy_date,
'action': 'request_destroy'
})
date = item.HostingSubscription_calculateSubscriptionStopDate()
self.assertEqual(date, DateTime('2012/10/31'))
@withAbort
def test_HS_calculateSubscriptionStopDate_noDestroy(self):
item = self.createHostingSubscription()
item.workflow_history['instance_slap_interface_workflow'] = []
date = item.HostingSubscription_calculateSubscriptionStopDate()
self.assertEqual(date, None)
......@@ -62,7 +62,7 @@ if hosting_subscription.getPeriodicityHour() is None:\n
if hosting_subscription.getPeriodicityMinute() is None:\n
edit_kw[\'periodicity_minute_list\'] = [0]\n
if hosting_subscription.getPeriodicityMonthDay() is None:\n
start_date = hosting_subscription.getCreationDate()\n
start_date = hosting_subscription.HostingSubscription_calculateSubscriptionStartDate()\n
start_date = getClosestDate(target_date=start_date, precision=\'day\')\n
while start_date.day() >= 29:\n
start_date = addToDate(start_date, to_add={\'day\': -1})\n
......
238
\ No newline at end of file
239
\ No newline at end of file
......@@ -108,25 +108,31 @@
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple>
<int>0</int>
</tuple>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple>
<int>0</int>
</tuple>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple>
<int>28</int>
</tuple>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
......
263
\ No newline at end of file
264
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment