1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
from DateTime import DateTime
from Products.ERP5Type.Base import WorkflowMethod
@WorkflowMethod.disable
def DeliveryLineSetZeroPriceAndOrUpdateAppliedRule(self):
portal_type = self.getPortalType()
assert( portal_type in self.getPortalDeliveryMovementTypeList())
common_specialise = 'sale_trade_condition_module/vifib_simple_trade_condition'
delivery = self.getParentValue()
price_currency = 'currency_module/EUR'
if delivery.getPortalType() in ['Purchase Packing List', 'Sale Packing List']:
specialise = delivery.getSpecialise()
if common_specialise != specialise:
delivery.setSpecialise(common_specialise)
delivery.SalePackingList_setArrow()
if delivery.getPriceCurrency() != price_currency:
delivery.setPriceCurrency(price_currency)
self.setPrice(0.0)
if self.getSimulationState() == 'cancelled':
# force no simulation
self.setQuantity(0.0)
else:
self.setQuantity(1.0)
@WorkflowMethod.disable
def OpenSaleOrder_migrate(self):
if self.getSpecialise() != 'sale_trade_condition_module/vifib_simple_trade_condition':
self.setSpecialise('sale_trade_condition_module/vifib_simple_trade_condition')
destination = self.getDestination() or self.getDestinationDecision() or self.getDestinationSection()
assert destination is not None
if self.getDestinationDecision() != destination:
self.setDestinationDecision(destination)
if self.getDestinationSection() != destination:
self.setDestinationSection(destination)
if self.getDestination() != destination:
self.setDestination(destination)
if self.getSource() != 'organisation_module/vifib_internet':
self.setSource('organisation_module/vifib_internet')
if self.getSourceSection() != 'organisation_module/vifib_internet':
self.setSourceSection('organisation_module/vifib_internet')
if self.getPriceCurrency() != 'currency_module/EUR':
self.setPriceCurrency('currency_module/EUR')
@WorkflowMethod.disable
def OpenSaleOrderLine_migrate(self):
now = DateTime().earliestTime()
self.setStartDate(now)
self.setStopDate(now)
self.setPrice(0.0)
self.setQuantity(1.0)
self.setResource(self.getPortalObject().portal_preferences.getPreferredInstanceSubscriptionResource())
resource_value = self.getResourceValue()
self.setBaseContributionList(resource_value.getBaseContributionList())
self.setUseList(resource_value.getUseList())
self.setQuantityUnit(resource_value.getQuantityUnit())
self.setSpecialise(None)
self.setDestination(None)
self.setDestinationSection(None)
self.setDestinationDecision(None)
self.setPriceCurrency(None)
self.setSource(None)
self.setSourceSection(None)
self.setSourceDecision(None)
@WorkflowMethod.disable
def VifibSaleInvoiceBuilder_buildAndPlan(self, movement_list):
delivery_list = self.build(movement_list=movement_list)
wf = self.getPortalObject().portal_workflow.accounting_workflow
plan_tdef = wf.transitions.get("plan")
for delivery in delivery_list:
if delivery.getSimulationState() == 'draft':
wf._changeStateOf(delivery, plan_tdef, dict(comment="Generated by the upgrade"))
def fixSaleOrder(slap_document):
sale_order_line_list = slap_document.getAggregateRelatedValueList(
portal_type='Sale Order Line')
assert(len(sale_order_line_list) == 1)
sale_order = sale_order_line_list[0].getParentValue()
sale_packing_list_line_list = slap_document.getAggregateRelatedValueList(
portal_type='Sale Packing List Line')
if len(sale_packing_list_line_list) == 0:
return sale_order.contentValues(portal_type='Sale Order Line')[0]
assert(len(sale_packing_list_line_list) == 1)
sale_packing_list = sale_packing_list_line_list[0].getParentValue()
new_sale_order = sale_order.Base_createCloneDocument(batch_mode=1)
slap_document.getPortalObject().portal_workflow.\
_jumpToStateFor(new_sale_order, 'ordered', 'order_workflow')
applied_rule = sale_order.getCausalityRelatedValue(portal_type='Applied Rule')
applied_rule.getParentValue().deleteContent(applied_rule.getId())
sale_order.getParentValue().deleteContent(sale_order.getId())
sale_packing_list.getParentValue().deleteContent(sale_packing_list.getId())
return new_sale_order.contentValues(portal_type='Sale Order Line')[0]
def SlapDocument_migrateSlapState(self):
@WorkflowMethod.disable
def real(self):
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
def setUpPeriodicity(hosting_subscription):
from Products.ERP5Type.DateUtils import addToDate, getClosestDate
start_date = hosting_subscription.getCreationDate()
start_date = getClosestDate(target_date=start_date, precision='day')
while start_date.day() >= 29:
start_date = addToDate(start_date, to_add={'day': -1})
periodicity_month_day_list = [start_date.day()]
periodicity_hour_list=[0]
periodicity_minute_list=[0]
hosting_subscription.edit(
periodicity_month_day_list=periodicity_month_day_list,
periodicity_hour_list=periodicity_hour_list,
periodicity_minute_list=periodicity_minute_list
)
slap_document = self
portal = self.getPortalObject()
portal_type_list = ('Hosting Subscription', 'Software Instance', 'Slave Instance')
portal_type = slap_document.getPortalType()
if portal_type not in portal_type_list:
raise TypeError('%s is not %s' % (slap_document.getPath(), portal_type_list))
explanation_delivery_line = portal.portal_catalog.getResultValue(
portal_type='Sale Packing List Line',
simulation_state=['ready', 'confirmed', 'started', 'stopped', 'delivered'],
query=ComplexQuery(
Query(default_aggregate_uid=slap_document.getUid()),
Query(default_resource_uid=[
portal.restrictedTraverse(portal.portal_preferences.getPreferredInstanceSetupResource()).getUid(),
portal.restrictedTraverse(portal.portal_preferences.getPreferredInstanceHostingResource()).getUid(),
portal.restrictedTraverse(portal.portal_preferences.getPreferredInstanceCleanupResource()).getUid(),
]),
operator='AND',
),
sort_on=(('movement.start_date', 'DESC'),)
)
if explanation_delivery_line is None:
explanation_delivery_line = slap_document.getAggregateRelatedValue(portal_type='Sale Order Line')
if slap_document.getRelativeUrl() == 'hosting_subscription_module/20120521-C46CA2':
# special case of destroyed data
explanation_delivery_line = fixSaleOrder(slap_document)
if portal_type == 'Hosting Subscription':
current_periodicity = slap_document.getPeriodicityMonthDayList()
if current_periodicity is None or len(current_periodicity) == 0:
setUpPeriodicity(slap_document)
# Person is now directly associated on the HS
slap_document.edit(
destination_section_value=explanation_delivery_line.getDestinationSectionValue(portal_type="Person"),
)
assert(slap_document.getDestinationSection() == explanation_delivery_line.getDestinationSectionValue().getRelativeUrl())
else:
hosting_subscription = explanation_delivery_line.getAggregateValue(portal_type='Hosting Subscription')
slap_document.edit(
specialise_value=hosting_subscription,
root_software_release_url=explanation_delivery_line.getAggregateValue(portal_type='Software Release').getUrlString()
)
assert(slap_document.getSpecialise() == hosting_subscription.getRelativeUrl())
# Migrate slap state
if portal_type == 'Hosting Subscription':
state = slap_document.getRootState()
promise_kw = {
'instance_xml': slap_document.getTextContent(),
'software_type': slap_document.getSourceReference(),
'sla_xml': slap_document.getSlaXml(),
'software_release': slap_document.getRootSoftwareReleaseUrl(),
'shared': slap_document.isRootSlave()
}
else:
if explanation_delivery_line.getPortalType() == 'Sale Packing List Line':
resource = explanation_delivery_line.getResource()
if resource == portal.portal_preferences.getPreferredInstanceSetupResource():
state = 'stopped'
elif resource == portal.portal_preferences.getPreferredInstanceCleanupResource():
state = 'destroyed'
elif resource == portal.portal_preferences.getPreferredInstanceHostingResource():
if explanation_delivery_line.getSimulationState() in ('confirmed', 'started'):
state = 'started'
else:
state = 'stopped'
pass
else:
raise TypeError('Bad resource %s' % resource)
pass
else:
if explanation_delivery_line.getSimulationState() == 'cancelled':
state = 'destroyed'
else:
assert(explanation_delivery_line.getSimulationState() in ['ordered', 'confirmed'])
previous_workflow_state = self.workflow_history[
'software_instance_slap_interface_workflow'][-1]['slap_state']
if previous_workflow_state == 'start_requested':
state = 'started'
elif previous_workflow_state == 'stop_requested':
state = 'stopped'
else:
raise NotImplementedError("Previous state %r not supported" % previous_workflow_state)
promise_kw = {
'instance_xml': slap_document.getTextContent(),
'software_type': slap_document.getSourceReference(),
'sla_xml': slap_document.getSlaXml(),
'software_release': slap_document.getRootSoftwareReleaseUrl(),
'shared': slap_document.getPortalType() == 'Slave Instance'
}
slap_document.setCausalityValue(explanation_delivery_line.getParentValue())
if state != 'destroyed' or explanation_delivery_line.getSimulationState() != 'delivered':
slap_document.setAggregateValue(explanation_delivery_line.getAggregateValue(portal_type='Computer Partition'))
assert(slap_document.getAggregate() == explanation_delivery_line.getAggregate(portal_type='Computer Partition'))
state_map = {
'started': 'start_requested',
'stopped': 'stop_requested',
'destroyed': 'destroy_requested'
}
required_state = state_map[state]
_jumpToStateFor = portal.portal_workflow._jumpToStateFor
if slap_document.getSlapState() != required_state:
_jumpToStateFor(slap_document, required_state, 'instance_slap_interface_workflow')
if not(slap_document.getSlapState() == required_state):
raise ValueError('%s: %s != %s' % (state, slap_document.getSlapState(), required_state))
# Migrate validation state
if portal_type == 'Hosting Subscription':
if state == 'destroyed':
_jumpToStateFor(slap_document, 'archived', 'hosting_subscription_workflow')
assert(slap_document.getValidationState() == 'archived')
else:
_jumpToStateFor(slap_document, 'validated', 'hosting_subscription_workflow')
assert(slap_document.getValidationState() == 'validated')
else:
if state == 'destroyed' and \
(explanation_delivery_line.getPortalType() == 'Sale Order Line' or \
explanation_delivery_line.getSimulationState() == 'delivered'):
_jumpToStateFor(slap_document, 'invalidated', 'item_workflow')
else:
if not(slap_document.getValidationState() == 'validated'):
raise ValueError('%s != %s' % (slap_document.getValidationState(), 'validated'))
# Update Local Roles
slap_document.updateLocalRolesOnSecurityGroups()
real(self)
def HostingSubscription_garbageCollectForMigration(self):
@WorkflowMethod.disable
def real(self):
slap_document = self
portal = self.getPortalObject()
title = slap_document.getTitle()
instance_state = 'destroy_requested'
for software_instance in slap_document.getPredecessorValueList():
if software_instance.getTitle() == title:
if software_instance.getSlapState() != 'destroy_requested':
instance_state = software_instance.getSlapState()
break
if instance_state == 'destroy_requested':
_jumpToStateFor = portal.portal_workflow._jumpToStateFor
_jumpToStateFor(slap_document, instance_state, 'instance_slap_interface_workflow')
assert(slap_document.getSlapState() == instance_state)
_jumpToStateFor(slap_document, 'archived', 'hosting_subscription_workflow')
assert(slap_document.getValidationState() == 'archived')
# Update Local Roles
slap_document.updateLocalRolesOnSecurityGroups()
real(self)
def SalePackingListLine_deliver(self):
@WorkflowMethod.disable
def real(self):
portal = self.getPortalObject()
assert(self.getResource() in [portal.portal_preferences.getPreferredInstanceSetupResource(),
portal.portal_preferences.getPreferredInstanceUpdateResource()])
if self.getSimulationState() != 'delivered':
portal.portal_workflow._jumpToStateFor(self.getParentValue(), 'delivered')
self.recursiveReindexObject()
real(self)
def Computer_updateLocalRoles(self):
self.updateLocalRolesOnSecurityGroups(reindex=False)
for partition in self.contentValues(portal_type='Computer Partition'):
partition.updateLocalRolesOnSecurityGroups(reindex=False)
def Instance_migrateRootSoftwareReleaseUrl(self):
@WorkflowMethod.disable
def real(self):
if self.getPortalType() not in ('Hosting Subscription', 'Software Instance', 'Slave Instance'):
raise TypeError('%s type is not supported' % self.getPortalType())
if 'root_software_release_url' in self.__dict__:
self.url_string = self.root_software_release_url
delattr(self, 'root_software_release_url')
real(self)