Commit 576c3235 authored by Ayush Tiwari's avatar Ayush Tiwari

bt5_config: Update functions for BusinessItem and BusinessTemplate class

parent e4f2c009
...@@ -27,41 +27,230 @@ ...@@ -27,41 +27,230 @@
# #
############################################################################## ##############################################################################
import hashlib
import fnmatch
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.Globals import Persistent from Products.ERP5Type.Globals import Persistent
from Acquisition import Implicit, aq_base, aq_inner, aq_parent from Acquisition import Implicit, aq_base, aq_inner, aq_parent
_MARKER = []
def _recursiveRemoveUid(obj):
"""Recusivly set uid to None, to prevent (un)indexing.
This is used to prevent unindexing real objects when we delete subobjects on
a copy of this object.
"""
if getattr(aq_base(obj), 'uid', _MARKER) is not _MARKER:
obj.uid = None
for subobj in obj.objectValues():
_recursiveRemoveUid(subobj)
class BusinessTemplate(XMLObject): class BusinessTemplate(XMLObject):
"""Business Template is responsible for saving objects and properties in
an ERP5Site. Everything will be saved just via path"""
meta_type = 'ERP5 Business Template'
portal_type = 'Business Template'
allowed_content_types = ('BusinessItem', )
add_permission = Permissions.AddPortalContent
_properties = (
{ 'id' : 'template_path',
'type': 'lines',
'default': 'python: ()',
'acquisition_base_category' : (),
'acquisition_portal_type' : (),
'acquisition_depends' : None,
'acquisition_accessor_id' : 'getTempaltePathList',
'override' : 1,
'mode' : 'w' },
)
template_path_list = ()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.SimpleItem
, PropertySheet.CategoryCore
, PropertySheet.Version
)
def getStatus(self):
""" """
Business Template is responsible for saving objects and properties in Installed: BI(s) are installed in OFS.
an ERP5Site. Everything will be saved just via path Uninstalled: Values for BI(s) at the current version removed from OFS.
Reduced: No two BI of same path exist at different layers.
Flatenned: BI(s) should be at the zeroth layer.
Build: BI(s) do have values from the OS DB.
""" """
meta_type = 'ERP5 Business Template' pass
portal_type = 'Business Template'
allowed_content_types = ('BusinessItem', )
add_permission = Permissions.AddPortalContent
# Declarative security def applytoERP5(self, DB):
security = ClassSecurityInfo() """Apply the flattened/reduced business template to the DB"""
security.declareObjectProtected(Permissions.AccessContentsInformation) portal = self.getPortalObject()
security.declareProtected(Permissions.ManagePortal, 'storeTemplateData')
def storeTemplateData(self):
"""
Store data for objects in the ERP5
"""
self._path_item_list = []
path_item_list = self.getTemplatePathList()
if not path_item_list:
path_item_list = [l.split(' | ') for l in path_item_list]
for path_item in path_list:
self._path_item_list.append(BusinessItem(path[0], path[1], path[2]))
def __init__(self, *args, **kw): def build(self, no_action=False, **kw):
pass """Creates new values for business configuration from the values from
OFS Database"""
if not no_action:
self.storeTemplateData()
for path_item in self._path_item_list:
path_item.build(self, **kw)
def getTemplatePathList(self):
return self.template_path_list
security.declareProtected(Permissions.ManagePortal, 'getTemplatePathList')
def _getTemplatePathList(self):
result = self.getTemplatePathList()
if not isinstance(result, tuple):
result = tuple(result)
return result
def install(self):
"""Install the business template"""
pass
def upgrade(self):
"""Upgrade the business template"""
pass
def flatten(self):
"""
Flattening a reduced business template with two path p1 and p2 where p1 <> p2:
flatten([(p1, s1, l1, v1), (p2, s2, l2, v2)]) = [(p1, s1, 0, v1), (p2, s2, 0, v2)]
A reduced business template BT is said to be flattened if and only if:
flatten(BT) = BT
"""
pass
def reduceBT(self):
"""
Reduce the current Business Template
"""
pass
class BusinessItem(Implicit, Persistent): class BusinessItem(Implicit, Persistent):
"""Saves the path and values for objects, properties, etc, the
attributes for a path configuration being:
- path (similar to an xpath expression)
- sign (+1/-1)
- layer (0, 1, 2, 3, etc.)
- value (a set of pickable value in python)
- hash of the value"""
def __init__(self, path, sign=1, layer=0, value=None, *args, **kw):
"""
Initialize/update the attributes
"""
self.__dict__.update(kw)
self._path = path
self._sign = int(sign)
self._layer = int(layer)
self._value = value
# Generate hash of from the value
self._sha = self._generateHash()
def _generateHash(self):
"""
Generate hash based on value for the object.
Initially, for simplicity, we go on with SHA1 values only
"""
if not self._value:
# Raise in case there is no value for the BusinessItem object
raise ValueError, "Value not defined for the %s BusinessItem" %self._path
else:
# Expects to raise error on case the value for the object is not
# picklable
sha1 = hashlib.sha1(self._value).hexdigest()
def build(self, context, **kw):
"""
Extract value for the given path from the OFS
""" """
Saves the path and values for objects, properties, etc, the p = context.getPortalObject()
attributes for a path configuration being: path = self._path
include_subobjects = 0
if path.endswith("**"):
include_subobjects = 1
for relative_url in self._resolvePath(p, [], path.split('/')):
obj = p.unrestrictedTraverse(relative_url)
obj = obj._getCopy(context)
obj = obj.__of__(context)
_recursiveRemoveUid(obj)
self._value = obj
- path (similar to an xpath expression) def _resolvePath(self, folder, relative_url_list, id_list):
- sign (+1/-1)
- layer (0, 1, 2, 3, etc.)
- value (a set of pickable value in python)
""" """
This method calls itself recursively.
def __init__(self, *args, **kw): The folder is the current object which contains sub-objects.
self.path = path The list of ids are path components. If the list is empty,
self.sign = 1 # should be int or bool ?? the current folder is valid.
self.layer = layer # should be int """
self.value = value # should be hash of value at the path if len(id_list) == 0:
return ['/'.join(relative_url_list)]
id = id_list[0]
if re.search('[\*\?\[\]]', id) is None:
# If the id has no meta character, do not have to check all objects.
obj = folder._getOb(id, None)
if obj is None:
raise AttributeError, "Could not resolve '%s' during Business Item processing." % id
return self._resolvePath(obj, relative_url_list + [id], id_list[1:])
path_list = []
for object_id in fnmatch.filter(folder.objectIds(), id):
if object_id != "":
path_list.extend(self._resolvePath(
folder._getOb(object_id),
relative_url_list + [object_id], id_list[1:]))
return path_list
def getBusinessPath(self):
return self._path
def getBusinessPathSign(self):
return self._sign
def getBusinessPathLayer(self):
return self._layer
def getBusinessPathValue(self):
return self._value
def getBusinessPathSha(self):
return self._sha
def getParentBusinessTemplate(self):
return self.aq_parent
def generateXML(self):
"""
Generate XML for different objects/type/properties differently.
1. Objects: Use XMLImportExport from ERP5Type
2. For properties, first get the property type, then create XML object
for the different property differenty(Use ObjectPropertyItem from BT5)
3. For attributes, we can export part of the object, rather than exporting
whole of the object
"""
pass
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