Commit c615bc62 authored by Gabriel Monnerat's avatar Gabriel Monnerat

[ERP5 Configurator] Rename _build to _checkConsistency to follow Constraint API

The logic of all Configuration Items was not changed, but now the
changes are applied only if fixit is True and the constraints are
filtered by constraint type equal configuration.

Cosmetic: Trailing whitespaces were removed in the same commit
parent 91ef6772
......@@ -56,42 +56,53 @@ class AccountConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.DublinCore
, PropertySheet.Account )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
account_module = self.getPortalObject().account_module
account = None
account_id = getattr(self, 'account_id', None)
error_list = []
error_list_append = lambda msg: error_list.append(
self._createConstraintMessage(msg))
extra_kw = {}
if account_id:
extra_kw['id'] = account_id
account = getattr(account_module, account_id, None)
if account is None:
account = account_module.newContent(
portal_type='Account',
title=self.getTitle(),
account_type=self.getAccountType(),
gap=self.getGap(),
financial_section=self.getFinancialSection(),
credit_account=self.isCreditAccount(),
description=self.getDescription(),
**extra_kw)
error_list_append("Account %s should be created" % self.getTitle())
if fixit:
account = account_module.newContent(
portal_type='Account',
title=self.getTitle(),
account_type=self.getAccountType(),
gap=self.getGap(),
financial_section=self.getFinancialSection(),
credit_account=self.isCreditAccount(),
description=self.getDescription(),
**extra_kw)
else:
# Update existing account
if (self.getAccountType() != account.getAccountType()) and \
(self.getFinancialSection() != account.getFinancialSection()):
raise ValueError("The Configurator is trying to overwrite previous configuration information (%s)" % account.getRelativeUrl())
error_list_append("Account %s should be updated" % account.getRelativeUrl())
if fixit:
# Update existing account
if (self.getAccountType() != account.getAccountType()) and \
(self.getFinancialSection() != account.getFinancialSection()):
raise ValueError("The Configurator is trying to overwrite previous configuration information (%s)" % account.getRelativeUrl())
account.edit(title=self.getTitle(), description=self.getDescription())
gap_list = account.getGapList()
# Only include only the additional gap that do not collide.
if self.getGap() not in gap_list:
gap_list.append(self.getGap())
account.setGapList(gap_list)
account.setCreditAccount(self.isCreditAccount())
account.edit(title=self.getTitle(), description=self.getDescription())
gap_list = account.getGapList()
# Only include only the additional gap that do not collide.
if self.getGap() not in gap_list:
gap_list.append(self.getGap())
account.setGapList(gap_list)
account.setCreditAccount(self.isCreditAccount())
if self.portal_workflow.isTransitionPossible(account, 'validate'):
account.validate(comment=translateString("Validated by Configurator"))
if account and fixit:
if self.portal_workflow.isTransitionPossible(account, 'validate'):
account.validate(comment=translateString("Validated by Configurator"))
## add to customer template
self.install(account, business_configuration)
## add to customer template
business_configuration = self.getBusinessConfigurationValue()
self.install(account, business_configuration)
return error_list
......@@ -55,20 +55,23 @@ class AccountingPeriodConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.DublinCore
, PropertySheet.Task )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
portal = self.getPortalObject()
business_configuration = self.getBusinessConfigurationValue()
organisation_id = business_configuration.\
getGlobalConfigurationAttr('organisation_id')
organisation = portal.organisation_module._getOb(organisation_id)
period = organisation.newContent(
portal_type='Accounting Period',
start_date=self.getStartDate(),
stop_date=self.getStopDate(),
short_title=self.getShortTitle(),
title=self.getTitle())
if fixit:
period = organisation.newContent(
portal_type='Accounting Period',
start_date=self.getStartDate(),
stop_date=self.getStopDate(),
short_title=self.getShortTitle(),
title=self.getTitle())
if self.portal_workflow.isTransitionPossible(period, 'start'):
period.start(comment="Started by Configurator")
if self.portal_workflow.isTransitionPossible(period, 'start'):
period.start(comment="Started by Configurator")
# no need to 'install' in the business template, because it's contain as
# subobject of an organisation we already added.
return ['Accounting Period %s should be created' % self.getTitle()]
......@@ -58,8 +58,9 @@ class AlarmConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.Periodicity
)
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
portal_alarms = self.getPortalObject().portal_alarms
error_list = []
property_dict = {
"active_sense_method_id" : self.getActiveSenseMethodId(),
"periodicity_hour_list" : self.getPeriodicityHourList(),
......@@ -72,14 +73,22 @@ class AlarmConfiguratorItem(ConfiguratorItemMixin, XMLObject):
"periodicity_week_list": self.getPeriodicityWeekList(),
}
alarm = getattr(portal_alarms, self.getId(), None)
alarm_id = self.getId()
alarm = getattr(portal_alarms, alarm_id, None)
if alarm is None:
alarm = portal_alarms.newContent(id=self.getId(),
title=self.getTitle())
alarm.edit(**property_dict)
error_list.append(self._createConstraintMessage(
"Alarm %s should be created" % alarm_id))
if fixit:
alarm = portal_alarms.newContent(id=alarm_id,
title=self.getTitle())
alarm.edit(**property_dict)
# Always enabled
alarm.setEnabled(True)
# Always enabled
alarm.setEnabled(True)
## add to customer template
self.install(alarm, business_configuration)
if alarm and fixit:
## add to customer template
business_configuration = self.getBusinessConfigurationValue()
self.install(alarm, business_configuration)
return error_list
......@@ -42,7 +42,7 @@ END_STATE_TITLE = 'End'
class BusinessConfiguration(Item):
"""
BusinessConfiguration store the values enter by the wizard.
BusinessConfiguration store the values enter by the wizard.
"""
meta_type = 'ERP5 Business Configuration'
......@@ -79,7 +79,7 @@ class BusinessConfiguration(Item):
def isDownloadConfigurationState(self):
""" Check if the Business Configuration is on Download State
"""
return self.getCurrentStateTitle() == DOWNLOAD_STATE_TITLE
return self.getCurrentStateTitle() == DOWNLOAD_STATE_TITLE
security.declareProtected(Permissions.View, 'isEndConfigurationState')
def isEndConfigurationState(self):
......@@ -126,12 +126,12 @@ class BusinessConfiguration(Item):
form_kw = {}
current_state = self.getCurrentStateValue()
transition = self.getNextTransition()
## it's possible that we have already saved a configuration save object
## it's possible that we have already saved a configuration save object
## in workflow_history for this state so we use it
configuration_save = self._getConfSaveForStateFromWorkflowHistory()
if configuration_save is None:
## we haven't saved any configuration save for this state so create new one
configuration_save = self.newContent(portal_type='Configuration Save',
configuration_save = self.newContent(portal_type='Configuration Save',
title=current_state.getTitle())
else:
## we have already created configuration save for this state
......@@ -145,7 +145,7 @@ class BusinessConfiguration(Item):
for k in form_kw.keys():
if form_kw[k].__class__.__name__ != 'FileUpload':
modified_form_kw[k] = form_kw[k]
configuration_save.edit(**modified_form_kw)
configuration_save.edit(**modified_form_kw)
## Add some variables so we can get use them in workflow after scripts
form_kw['configuration_save_url'] = configuration_save.getRelativeUrl()
form_kw['transition'] = transition.getRelativeUrl()
......@@ -162,7 +162,7 @@ class BusinessConfiguration(Item):
while transition is not None:
form_id = transition.getTransitionFormId()
if self.isDownloadConfigurationState():
## exec next transition for this business configuration
## exec next transition for this business configuration
self._executeTransition()
transition = self.getNextTransition()
return None, None, None, None
......@@ -172,7 +172,7 @@ class BusinessConfiguration(Item):
transition = self.getNextTransition()
else:
if context is None:
## examine workflow_history for already saved
## examine workflow_history for already saved
## 'Configuration Save' objects for this state
context = self._getConfSaveForStateFromWorkflowHistory()
## get form object in a proper context
......@@ -203,7 +203,7 @@ class BusinessConfiguration(Item):
form_html = self.Base_mainConfiguratorFormTemplate(
current_form_number=form_counter + 1,
max_form_numbers=forms_number,
form_title=form.title,
form_title=form.title,
form_html=template_html)
html_forms.append(form_html)
else:
......@@ -233,14 +233,14 @@ class BusinessConfiguration(Item):
html_forms.append(form_html)
if html_forms != []:
html = "\n".join(html_forms)
title = form.title
title = form.title
return html, title
security.declarePrivate('_displayPreviousForm')
def _displayPreviousForm(self):
""" Render previous form using workflow history. """
workflow_history = self.getCurrentStateValue().getWorkflowHistory(self, remove_undo=1)
workflow_history.reverse()
workflow_history.reverse()
for wh in workflow_history:
## go one step back
current_state = self.getCurrentStateValue()
......@@ -303,7 +303,7 @@ class BusinessConfiguration(Item):
security.declareProtected(Permissions.ModifyPortalContent, 'setMultiEntryTransition')
def setMultiEntryTransition(self, transition_url, max_entry_number):
""" Set a transition as multiple - i.e max_entry_number of forms
""" Set a transition as multiple - i.e max_entry_number of forms
which will be rendered. This method is called in after scripts
and usually this number is set by user in a web form. """
if getattr(aq_base(self), '_multi_entry_transitions', None) is None:
......@@ -327,13 +327,13 @@ class BusinessConfiguration(Item):
############# Instance and Business Configuration ########################
security.declareProtected(Permissions.ModifyPortalContent, 'buildConfiguration')
def buildConfiguration(self):
"""
Build list of business templates according to already saved
"""
Build list of business templates according to already saved
Configuration Saves (i.e. user input).
This is the actual implementation which can be used from workflow
This is the actual implementation which can be used from workflow
actions and Configurator requets
"""
kw = dict(tag="start_configuration_%s" % self.getId(),
kw = dict(tag="start_configuration_%s" % self.getId(),
after_method_id=["updateBusinessTemplateFromUrl",
"recursiveImmediateReindexObject",
"immediateReindexObject"])
......@@ -346,13 +346,14 @@ class BusinessConfiguration(Item):
configuration_item_list = configuration_save.contentValues()
configuration_item_list.sort(lambda x, y: cmp(x.getIntId(), y.getIntId()))
for configurator_item in configuration_item_list:
configurator_item.activate(**kw).build(self.getRelativeUrl())
configurator_item.activate(**kw).fixConsistency(
filter={"constraint_type":"configuration"})
kw["after_tag"] = kw["tag"]
kw["tag"] = "configurator_item_%s_%s" % (configurator_item.getId(),
configurator_item.getUid())
kw["tag"] = "final_configuration_step_%s" % self.getId()
kw["after_method_id"] = ["build", 'immediateReindexObject', \
kw["after_method_id"] = ["fixConsistency", 'immediateReindexObject', \
"recursiveImmediateReindexObject"]
self.activate(**kw).ERP5Site_afterConfigurationSetup()
......
......@@ -58,57 +58,61 @@ class BusinessProcessConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.Reference
)
def _build(self, business_configuration):
portal = self.getPortalObject()
business_process = portal.business_process_module.newContent(
portal_type="Business Process",
reference=self.getReference(),
title=self.getTitle())
business_configuration.setGlobalConfigurationAttr(\
business_process_id=business_process.getId())
business_process_dict = self._getBusinessProcessDict()
int_index = 0
for path_dict in business_process_dict["Trade Model Path"]:
int_index += 1
path_dict.setdefault("int_index", int_index)
title = path_dict.pop('title')
trade_phase = path_dict.pop('trade_phase')
trade_date = path_dict.pop('trade_date')
for key in path_dict:
if path_dict[key] is None:
path_dict.pop(key)
self._addTradeModelPath(business_process=business_process,
def _checkConsistency(self, fixit=False, filter=None, **kw):
error_list = ["Business Process %s should be created" % self.getReference(),]
if fixit:
portal = self.getPortalObject()
business_process = portal.business_process_module.newContent(
portal_type="Business Process",
reference=self.getReference(),
title=self.getTitle())
business_configuration = self.getBusinessConfigurationValue()
business_configuration.setGlobalConfigurationAttr(\
business_process_id=business_process.getId())
business_process_dict = self._getBusinessProcessDict()
int_index = 0
for path_dict in business_process_dict["Trade Model Path"]:
int_index += 1
path_dict.setdefault("int_index", int_index)
title = path_dict.pop('title')
trade_phase = path_dict.pop('trade_phase')
trade_date = path_dict.pop('trade_date')
for key in path_dict:
if path_dict[key] is None:
path_dict.pop(key)
self._addTradeModelPath(business_process=business_process,
title=title,
trade_phase=trade_phase,
trade_date=trade_date,
**path_dict)
int_index = 0
for link_dict in business_process_dict["Business Link"]:
int_index += 1
link_dict.setdefault("int_index", int_index)
title = link_dict.pop('title')
trade_phase = link_dict.pop('trade_phase')
delivery_builder = link_dict.pop('delivery_builder', None)
predecessor = link_dict.pop('predecessor', None)
successor = link_dict.pop('successor', None)
for key in path_dict:
if path_dict[key] is None:
path_dict.pop(key)
self._addBusinessLink(business_process=business_process,
title=title,
trade_phase=trade_phase,
trade_date=trade_date,
**path_dict)
int_index = 0
for link_dict in business_process_dict["Business Link"]:
int_index += 1
link_dict.setdefault("int_index", int_index)
title = link_dict.pop('title')
trade_phase = link_dict.pop('trade_phase')
delivery_builder = link_dict.pop('delivery_builder', None)
predecessor = link_dict.pop('predecessor', None)
successor = link_dict.pop('successor', None)
for key in path_dict:
if path_dict[key] is None:
path_dict.pop(key)
self._addBusinessLink(business_process=business_process,
title=title,
trade_phase = trade_phase,
predecessor = predecessor,
successor = successor,
delivery_builder = delivery_builder,
**link_dict)
business_process.validate(comment=translateString('Validated by configurator'))
self.install(business_process, business_configuration)
trade_phase = trade_phase,
predecessor = predecessor,
successor = successor,
delivery_builder = delivery_builder,
**link_dict)
business_process.validate(comment=translateString('Validated by configurator'))
self.install(business_process, business_configuration)
return error_list
def _getBusinessProcessDict(self):
""" Read the spreadsheet and return the configuration for
......
......@@ -55,15 +55,21 @@ class CatalogKeywordKeyConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.CategoryCore
, PropertySheet.DublinCore )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
error_list = []
portal = self.getPortalObject()
catalog = portal.portal_catalog.getSQLCatalog()
key_list = list(catalog.getProperty('sql_catalog_keyword_search_keys', ()))
for k in self.key_list:
if k not in key_list:
error_list.append(self._createConstraintMessage(
"%s should be in sql_catalog_keyword_search_keys" % k))
key_list.append(k)
key_list = tuple(key_list)
catalog._setPropValue('sql_catalog_keyword_search_keys', key_list)
bt = business_configuration.getSpecialiseValue()
bt.edit(template_catalog_keyword_key_list=key_list)
if fixit:
catalog._setPropValue('sql_catalog_keyword_search_keys', key_list)
business_configuration = self.getBusinessConfigurationValue()
bt = business_configuration.getSpecialiseValue()
bt.edit(template_catalog_keyword_key_list=key_list)
return error_list
......@@ -64,37 +64,49 @@ class CategoriesSpreadsheetConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.ConfiguratorItem
)
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
portal = self.getPortalObject()
ctool = portal.portal_categories
self._readSpreadSheet()
cache = self._category_cache
object_id_list = ctool.objectIds()
error_list = []
for bc_id, category_list in cache.items():
if bc_id in ctool.objectIds():
if bc_id in object_id_list:
bc = ctool._getOb(bc_id)
else:
# TODO: test bc creation
# the bc should be added as base category in bt5 ?
bc = ctool.newContent(id=bc_id)
for category_info in category_list:
path = bc
for cat in category_info['path'].split("/")[1:]:
if not cat in path.objectIds():
path = path.newContent(
portal_type='Category',
id=cat,)
else:
path = path[cat]
edit_dict = category_info.copy()
edit_dict.pop('path')
if 'id' in edit_dict.keys():
edit_dict.pop('id')
path.edit(**edit_dict)
## add to customer template
self.install(path, business_configuration)
error_list.append(self._createConstraintMessage(
"Base Category %s should be created" % bc_id))
if fixit:
bc = ctool.newContent(id=bc_id)
if fixit:
for category_info in category_list:
path = bc
for cat in category_info['path'].split("/")[1:]:
if not cat in path.objectIds():
path = path.newContent(
portal_type='Category',
id=cat,)
else:
path = path[cat]
edit_dict = category_info.copy()
edit_dict.pop('path')
if 'id' in edit_dict.keys():
edit_dict.pop('id')
path.edit(**edit_dict)
## add to customer template
business_configuration = self.getBusinessConfigurationValue()
self.install(path, business_configuration)
else:
error_list.extend(["%s should be created" % category['path'] \
for category in category_list])
return error_list
def _readSpreadSheet(self):
"""Read the spreadsheet and prepare internal category cache.
......
......@@ -54,14 +54,17 @@ class CategoryConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.CategoryCore
, PropertySheet.DublinCore)
def _build(self, business_configuration):
portal = self.getPortalObject()
category_root = portal.portal_categories[self.category_root]
object_id = self.object_id
if object_id in category_root.objectIds():
category_root.manage_delObjects(object_id)
category = category_root.newContent(portal_type='Category',
id = object_id,
title = self.getTitle())
## add to customer template
self.install(category, business_configuration)
def _checkConsistency(self, fixit=False, filter=None, **kw):
if fixit:
portal = self.getPortalObject()
category_root = portal.portal_categories[self.category_root]
object_id = self.object_id
if object_id in category_root.objectIds():
category_root.manage_delObjects(object_id)
category = category_root.newContent(portal_type='Category',
id = object_id,
title = self.getTitle())
## add to customer template
business_configuration = self.getBusinessConfigurationValue()
self.install(category, business_configuration)
return ['Category %s should be created' % self.getTitle(),]
......@@ -58,22 +58,29 @@ class CurrencyConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.Resource
, PropertySheet.Reference )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
currency_module = self.getPortalObject().currency_module
error_list = []
title = self.getTitle()
reference = self.getReference()
base_unit_quantity = self.getBaseUnitQuantity()
# XXX FIXME This is not exactly desired behaviour
currency = self.portal_catalog.getResultValue(id=reference,
portal_type="Currency")
if currency is None:
currency = currency_module.newContent(portal_type = "Currency",
id = reference,
title = title,
reference = reference,
base_unit_quantity = base_unit_quantity)
currency.validate(comment=translateString("Validated by Configurator"))
business_configuration.setGlobalConfigurationAttr(currency_id=currency.getId())
## add to customer template
self.install(currency, business_configuration)
error_list.append(self._createConstraintMessage(
"Currency %s should be created" % reference))
if fixit:
currency = currency_module.newContent(portal_type = "Currency",
id = reference,
title = title,
reference = reference,
base_unit_quantity=self.getBaseUnitQuantity())
currency.validate(comment=translateString("Validated by Configurator"))
if currency:
business_configuration = self.getBusinessConfigurationValue()
business_configuration.setGlobalConfigurationAttr(currency_id=currency.getId())
## add to customer template
self.install(currency, business_configuration)
return error_list
......@@ -57,9 +57,17 @@ class CustomerBT5ConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.CategoryCore
, PropertySheet.DublinCore )
def _build(self, business_configuration):
bt5 = self.getPortalObject().portal_templates.newContent(
portal_type="Business Template", title=self.bt5_title)
def _checkConsistency(self, fixit=False, filter=None, **kw):
template_tool = self.getPortalObject().portal_templates
error_list = []
if self.bt5_title not in template_tool.getBuiltBusinessTemplateList():
error_list.append(self._createConstraintMessage(
'%s should be created' % self.bt5_title))
## ..and set it as current
business_configuration.setSpecialise(bt5.getRelativeUrl())
if fixit:
bt5 = template_tool.newContent(portal_type="Business Template",
title=self.bt5_title)
business_configuration = self.getBusinessConfigurationValue()
business_configuration.setSpecialise(bt5.getRelativeUrl())
return error_list
......@@ -56,30 +56,33 @@ class OrganisationConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.DublinCore
, PropertySheet.Organisation )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
""" Setup organisation. """
portal = self.getPortalObject()
organisation = portal.organisation_module.newContent(portal_type="Organisation")
if fixit:
portal = self.getPortalObject()
organisation = portal.organisation_module.newContent(portal_type="Organisation")
org_dict = {'price_currency': 'currency_module/%s' % self.getPriceCurrency(),
'group': self.getGroup(),
'title': self.getTitle(),
'corporate_name': self.getCorporateName(),
'default_address_city': self.getDefaultAddressCity(),
'default_email_text': self.getDefaultEmailText(),
'default_telephone_text': self.getDefaultTelephoneText(),
'default_address_zip_code': self.getDefaultAddressZipCode(),
'default_address_region': self.getDefaultAddressRegion(),
'default_address_street_address': self.getDefaultAddressStreetAddress(),
'site':'main', # First customer's organisation is always main site.
}
organisation.edit(**org_dict)
# store globally organization_id
business_configuration.setGlobalConfigurationAttr(organisation_id=organisation.getId())
org_dict = {'price_currency': 'currency_module/%s' % self.getPriceCurrency(),
'group': self.getGroup(),
'title': self.getTitle(),
'corporate_name': self.getCorporateName(),
'default_address_city': self.getDefaultAddressCity(),
'default_email_text': self.getDefaultEmailText(),
'default_telephone_text': self.getDefaultTelephoneText(),
'default_address_zip_code': self.getDefaultAddressZipCode(),
'default_address_region': self.getDefaultAddressRegion(),
'default_address_street_address': self.getDefaultAddressStreetAddress(),
'site':'main', # First customer's organisation is always main site.
}
organisation.edit(**org_dict)
if self.portal_workflow.isTransitionPossible(organisation, 'validate'):
organisation.validate(comment=translateString("Validated by Configurator"))
business_configuration = self.getBusinessConfigurationValue()
# store globally organization_id
business_configuration.setGlobalConfigurationAttr(organisation_id=organisation.getId())
## add to customer template
self.install(organisation, business_configuration)
if self.portal_workflow.isTransitionPossible(organisation, 'validate'):
organisation.validate(comment=translateString("Validated by Configurator"))
## add to customer template
self.install(organisation, business_configuration)
return ['Organisation should be created',]
......@@ -54,9 +54,11 @@ class PermissionConfiguratorItem(ConfiguratorItemMixin, XMLObject):
, PropertySheet.CategoryCore
, PropertySheet.DublinCore )
def _build(self, business_configuration):
def _checkConsistency(self, fixit=False, filter=None, **kw):
template_module_id_list = []
error_list = []
module_permissions_map = {}
business_configuration = self.getBusinessConfigurationValue()
sheets_dict = business_configuration.ConfigurationTemplate_readOOCalcFile(\
self.filename)
for module_id, permissions in sheets_dict.items():
......@@ -79,9 +81,14 @@ class PermissionConfiguratorItem(ConfiguratorItemMixin, XMLObject):
for permission_name, roles in permissions_map.items():
# we must alway include additionally 'Manager' and 'Owner'
roles.extend(['Manager', 'Owner'])
module.manage_permission(permission_name, tuple(roles), 0)
if fixit:
module.manage_permission(permission_name, tuple(roles), 0)
error_list.append(self._createConstraintMessage(