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