Commit 1ff851b1 authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: Preparation of erp5_base migration from FS: Fix pylint bad-indentation warnings.

parent 187c6554
......@@ -32,22 +32,22 @@ from Products.ERP5Type.XMLObject import XMLObject
class AgentPrivilege(XMLObject):
"""
An Agent Privilege allow the Bank Account owner to give permissions to an Agent for a given period of time, for a maximum amount of money.
"""
# CMF Type Definition
meta_type = 'ERP5 Agent Privilege'
portal_type = 'Agent Privilege'
"""
An Agent Privilege allow the Bank Account owner to give permissions to an Agent for a given period of time, for a maximum amount of money.
"""
# CMF Type Definition
meta_type = 'ERP5 Agent Privilege'
portal_type = 'Agent Privilege'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.AgentPrivilege
)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.AgentPrivilege
)
......@@ -33,22 +33,22 @@ from Products.ERP5.Document.Path import Path
class Assignment(Path):
# CMF Type Definition
meta_type = 'ERP5 Assignment'
portal_type = 'Assignment'
add_permission = Permissions.AddPortalContent
# CMF Type Definition
meta_type = 'ERP5 Assignment'
portal_type = 'Assignment'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Path
, PropertySheet.Assignment
)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Path
, PropertySheet.Assignment
)
......@@ -34,43 +34,43 @@ from Products.ERP5.Document.Node import Node
from Products.ERP5.Document.Coordinate import Coordinate
class BankAccount(Node, Coordinate):
"""
"""
A bank account number holds a collection of numbers and codes
(ex. SWIFT, RIB, etc.) which may be used to identify a bank account.
A Bank Account is owned by a Person or an Organisation. A Bank Account
contain Agents with Agent Privileges used by the owner to delegate the
management of the bank account to trusted third-party Persons.
"""
"""
meta_type = 'ERP5 Bank Account'
portal_type = 'Bank Account'
add_permission = Permissions.AddPortalContent
meta_type = 'ERP5 Bank Account'
portal_type = 'Bank Account'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.CategoryCore
, PropertySheet.Task
, PropertySheet.Resource
, PropertySheet.Reference
, PropertySheet.BankAccount
)
# Declarative properties
property_sheets = ( PropertySheet.CategoryCore
, PropertySheet.Task
, PropertySheet.Resource
, PropertySheet.Reference
, PropertySheet.BankAccount
)
security.declareProtected(Permissions.AccessContentsInformation, 'getReference')
def getReference(self, *args, **kw):
"""reference depends on the site configuration.
"""
value = self._baseGetReference(*args, **kw)
if value in (None, ''):
# Try to get a skin from type name
method = self._getTypeBasedMethod('getReference')
if method is not None:
return method(*args, **kw)
return value
security.declareProtected(Permissions.AccessContentsInformation, 'getReference')
def getReference(self, *args, **kw):
"""reference depends on the site configuration.
"""
value = self._baseGetReference(*args, **kw)
if value in (None, ''):
# Try to get a skin from type name
method = self._getTypeBasedMethod('getReference')
if method is not None:
return method(*args, **kw)
return value
# XXX The following "helper methods" have been commented out, and kept in the
# code as an example.
......
......@@ -33,27 +33,27 @@ from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Path import Path
class Career(Path):
"""
"""
Contains information about abilities, salary, grade, role... of a
Person at a certain career step.
"""
# CMF Type Definition
meta_type = 'ERP5 Career'
portal_type = 'Career'
add_permission = Permissions.AddPortalContent
"""
# CMF Type Definition
meta_type = 'ERP5 Career'
portal_type = 'Career'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Path
, PropertySheet.Reference
, PropertySheet.Assignment
)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Path
, PropertySheet.Reference
, PropertySheet.Assignment
)
......@@ -38,7 +38,7 @@ import re
_marker = object()
class Coordinate(Base):
"""
"""
Coordinates is a mix-in class which is used to store elementary
coordinates of an Entity (ex. Person, Organisation)
......@@ -75,179 +75,177 @@ class Coordinate(Base):
In order to be able to list all coordinates of an Entity,
a list of Coordinate metatypes has to be defined and
stored somewhere. (TODO)
"""
meta_type = 'ERP5 Coordinate'
portal_type = 'Coordinate'
add_permission = Permissions.AddPortalContent
# Declarative interface
zope.interface.implements(interfaces.ICoordinate, )
# Declarative security (replaces __ac_permissions__)
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.SimpleItem
, PropertySheet.Coordinate
)
### helper methods
security.declareProtected( Permissions.AccessContentsInformation,
'getRegularExpressionFindAll')
def getRegularExpressionFindAll(self, regular_expression, string):
"""
allows call of re.findall in a python script used for Coordinate
"""
return re.findall(regular_expression, string)
security.declareProtected( Permissions.AccessContentsInformation,
'getRegularExpressionGroups')
def getRegularExpressionGroups(self, regular_expression, string):
"""
allows call of re.search.groups in a python script used for Coordinate
"""
match = re.search(regular_expression, string)
if match is None:
return ()
return re.search(regular_expression, string).groups()
### Mix-in methods
security.declareProtected( Permissions.AccessContentsInformation,
'asText' )
def asText(self):
"""
returns the coordinate as a text string
"""
script = self._getTypeBasedMethod('asText')
if script is not None:
return script()
security.declareProtected( Permissions.AccessContentsInformation,
'getText')
def getText(self):
"""
calls asText
"""
return self.asText()
security.declareProtected( Permissions.AccessContentsInformation,
'hasText')
def hasText(self):
"""
calls asText
"""
return bool(self.asText())
security.declareProtected(Permissions.AccessContentsInformation, 'getCoordinateText')
def getCoordinateText(self, default=_marker):
"""Fallback on splitted values (old API)
"""
if not self.hasCoordinateText() and self.isDetailed():
# Display old values (parsed ones)
# empty value is None, not ''
value = self.asText()
if value:
return value
if default is _marker:
return None
else:
return default
"""
meta_type = 'ERP5 Coordinate'
portal_type = 'Coordinate'
add_permission = Permissions.AddPortalContent
# Declarative interface
zope.interface.implements(interfaces.ICoordinate, )
# Declarative security (replaces __ac_permissions__)
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.SimpleItem
, PropertySheet.Coordinate
)
### helper methods
security.declareProtected( Permissions.AccessContentsInformation,
'getRegularExpressionFindAll')
def getRegularExpressionFindAll(self, regular_expression, string):
"""
allows call of re.findall in a python script used for Coordinate
"""
return re.findall(regular_expression, string)
security.declareProtected( Permissions.AccessContentsInformation,
'getRegularExpressionGroups')
def getRegularExpressionGroups(self, regular_expression, string):
"""
allows call of re.search.groups in a python script used for Coordinate
"""
match = re.search(regular_expression, string)
if match is None:
return ()
return re.search(regular_expression, string).groups()
### Mix-in methods
security.declareProtected( Permissions.AccessContentsInformation,
'asText' )
def asText(self):
"""
returns the coordinate as a text string
"""
script = self._getTypeBasedMethod('asText')
if script is not None:
return script()
security.declareProtected( Permissions.AccessContentsInformation,
'getText')
def getText(self):
"""
calls asText
"""
return self.asText()
security.declareProtected( Permissions.AccessContentsInformation,
'hasText')
def hasText(self):
"""
calls asText
"""
return bool(self.asText())
security.declareProtected(Permissions.AccessContentsInformation, 'getCoordinateText')
def getCoordinateText(self, default=_marker):
"""Fallback on splitted values (old API)
"""
if not self.hasCoordinateText() and self.isDetailed():
# Display old values (parsed ones)
# empty value is None, not ''
value = self.asText()
if value:
return value
if default is _marker:
return self._baseGetCoordinateText()
return self._baseGetCoordinateText(default)
security.declareProtected( Permissions.ModifyPortalContent, 'fromText' )
@deprecated
def fromText(self, coordinate_text):
"""
modifies the coordinate according to the input text
must be implemented by subclasses
"""
script = self._getTypeBasedMethod('fromText')
if script is not None:
return script(text=coordinate_text)
security.declareProtected(Permissions.ModifyPortalContent, '_setText')
def _setText(self, value):
"""
calls fromText
"""
return self.fromText(value)
security.declareProtected( Permissions.AccessContentsInformation,
'standardTextFormat')
def standardTextFormat(self):
"""
Returns the standard text formats for telephone numbers
"""
pass
security.declareProtected(Permissions.AccessContentsInformation, 'isDetailed')
def isDetailed(self):
return False
security.declarePrivate( '_writeFromPUT' )
def _writeFromPUT( self, body ):
headers = {}
headers, body = parseHeadersBody(body, headers)
lines = body.split( '\n' )
self.edit( lines[0] )
headers['Format'] = self.COORDINATE_FORMAT
new_subject = keywordsplitter(headers)
headers['Subject'] = new_subject or self.Subject()
haveheader = headers.has_key
for key, value in self.getMetadataHeaders():
if key != 'Format' and not haveheader(key):
headers[key] = value
self._editMetadata(title=headers['Title'],
subject=headers['Subject'],
description=headers['Description'],
contributors=headers['Contributors'],
effective_date=headers['Effective_date'],
expiration_date=headers['Expiration_date'],
format=headers['Format'],
language=headers['Language'],
rights=headers['Rights'],
)
## FTP handlers
security.declareProtected( Permissions.ModifyPortalContent, 'PUT')
def PUT(self, REQUEST, RESPONSE):
"""
Handle HTTP / WebDAV / FTP PUT requests.
"""
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
if REQUEST.environ['REQUEST_METHOD'] != 'PUT':
raise Forbidden, 'REQUEST_METHOD should be PUT.'
body = REQUEST.get('BODY', '')
try:
self._writeFromPUT( body )
RESPONSE.setStatus(204)
return RESPONSE
except ResourceLockedError:
get_transaction().abort()
RESPONSE.setStatus(423)
return RESPONSE
security.declareProtected( Permissions.View, 'manage_FTPget' )
def manage_FTPget(self):
"""
Get the coordinate as text for WebDAV src / FTP download.
"""
hdrlist = self.getMetadataHeaders()
hdrtext = formatRFC822Headers( hdrlist )
bodytext = '%s\n\n%s' % ( hdrtext, self.asText() )
return bodytext
security.declareProtected( Permissions.View, 'get_size' )
def get_size( self ):
"""
Used for FTP and apparently the ZMI now too
"""
return len(self.manage_FTPget())
return None
else:
return default
if default is _marker:
return self._baseGetCoordinateText()
return self._baseGetCoordinateText(default)
security.declareProtected( Permissions.ModifyPortalContent, 'fromText' )
@deprecated
def fromText(self, coordinate_text):
"""
modifies the coordinate according to the input text
must be implemented by subclasses
"""
script = self._getTypeBasedMethod('fromText')
if script is not None:
return script(text=coordinate_text)
security.declareProtected(Permissions.ModifyPortalContent, '_setText')
def _setText(self, value):
"""
calls fromText
"""
return self.fromText(value)
security.declareProtected( Permissions.AccessContentsInformation,
'standardTextFormat')
def standardTextFormat(self):
"""
Returns the standard text formats for telephone numbers
"""
pass
security.declareProtected(Permissions.AccessContentsInformation, 'isDetailed')
def isDetailed(self):
return False
security.declarePrivate( '_writeFromPUT' )
def _writeFromPUT( self, body ):
headers, body = parseHeadersBody(body, headers)
lines = body.split( '\n' )
self.edit( lines[0] )
headers['Format'] = self.COORDINATE_FORMAT
new_subject = keywordsplitter(headers)
headers['Subject'] = new_subject or self.Subject()
haveheader = headers.has_key
for key, value in self.getMetadataHeaders():
if key != 'Format' and not haveheader(key):
headers[key] = value
self._editMetadata(title=headers['Title'],
subject=headers['Subject'],
description=headers['Description'],
contributors=headers['Contributors'],
effective_date=headers['Effective_date'],
expiration_date=headers['Expiration_date'],
format=headers['Format'],
language=headers['Language'],
rights=headers['Rights'],
)
## FTP handlers
security.declareProtected( Permissions.ModifyPortalContent, 'PUT')
def PUT(self, REQUEST, RESPONSE):
"""
Handle HTTP / WebDAV / FTP PUT requests.
"""
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
if REQUEST.environ['REQUEST_METHOD'] != 'PUT':
raise Forbidden, 'REQUEST_METHOD should be PUT.'
body = REQUEST.get('BODY', '')
try:
self._writeFromPUT( body )
RESPONSE.setStatus(204)
return RESPONSE
except ResourceLockedError:
get_transaction().abort()
RESPONSE.setStatus(423)
return RESPONSE
security.declareProtected( Permissions.View, 'manage_FTPget' )
def manage_FTPget(self):
"""
Get the coordinate as text for WebDAV src / FTP download.
"""
hdrlist = self.getMetadataHeaders()
hdrtext = formatRFC822Headers( hdrlist )
bodytext = '%s\n\n%s' % ( hdrtext, self.asText() )
return bodytext
security.declareProtected( Permissions.View, 'get_size' )
def get_size( self ):
"""
Used for FTP and apparently the ZMI now too
"""
return len(self.manage_FTPget())
......@@ -204,7 +204,7 @@ class Image(TextConvertableMixin, File, OFSImage):
"""Return list of HTML <a> tags for displays."""
links = []
for display in self.displayIds(exclude):
links.append('<a href="%s?display=%s">%s</a>' % (self.REQUEST['URL'], display, display))
links.append('<a href="%s?display=%s">%s</a>' % (self.REQUEST['URL'], display, display))
return links
security.declareProtected(Permissions.AccessContentsInformation, 'displayMap')
......@@ -367,11 +367,11 @@ class Image(TextConvertableMixin, File, OFSImage):
cwd='/',
close_fds=True)
try:
# XXX: The only portable way is to pass what stdin.write can accept,
# which is a string for PIPE.
image, err = process.communicate(data)
# XXX: The only portable way is to pass what stdin.write can accept,
# which is a string for PIPE.
image, err = process.communicate(data)
finally:
del process
del process
if image:
return StringIO(image)
raise ConversionError('Image conversion failed (%s).' % err)
......
......@@ -33,7 +33,7 @@ from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5.Document.Node import Node
class Organisation(Node):
"""
"""
An Organisation object holds the information about
an organisation (ex. a division in a company, a company,
a service in a public administration).
......@@ -46,27 +46,27 @@ class Organisation(Node):
Organisation objects inherit from the MetaNode base class
(one of the 5 base classes in the ERP5 universal business model)
"""
"""
meta_type = 'ERP5 Organisation'
portal_type = 'Organisation'
add_permission = Permissions.AddPortalContent
meta_type = 'ERP5 Organisation'
portal_type = 'Organisation'
add_permission = Permissions.AddPortalContent
zope.interface.implements(interfaces.INode)
zope.interface.implements(interfaces.INode)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Organisation
, PropertySheet.Mapping
, PropertySheet.Task
, PropertySheet.Reference
)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Organisation
, PropertySheet.Mapping
, PropertySheet.Task
, PropertySheet.Reference
)
......@@ -50,7 +50,7 @@ class UserExistsError(ValidationFailed):
super(UserExistsError, self).__init__('user id %s already exists' % (user_id, ))
class Person(Node, LoginAccountProviderMixin, EncryptedPasswordMixin, ERP5UserMixin):
"""
"""
An Person object holds the information about
an person (ex. you, me, someone in the company,
someone outside of the company, a member of the portal,
......@@ -64,194 +64,194 @@ class Person(Node, LoginAccountProviderMixin, EncryptedPasswordMixin, ERP5UserMi
Person objects inherit from the Node base class
(one of the 5 base classes in the ERP5 universal business model)
"""
"""
meta_type = 'ERP5 Person'
portal_type = 'Person'
add_permission = Permissions.AddPortalContent
meta_type = 'ERP5 Person'
portal_type = 'Person'
add_permission = Permissions.AddPortalContent
zope.interface.implements(interfaces.INode)
zope.interface.implements(interfaces.INode)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Reference
, PropertySheet.Person
, PropertySheet.Login
, PropertySheet.Mapping
, PropertySheet.Task
)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Reference
, PropertySheet.Person
, PropertySheet.Login
, PropertySheet.Mapping
, PropertySheet.Task
)
security.declareProtected(Permissions.AccessContentsInformation,
'getTitle')
def getTitle(self, **kw):
"""
Returns the title if it exists or a combination of
first name, middle name and last name
"""
title = ' '.join([x for x in (self.getFirstName(),
self.getMiddleName(),
self.getLastName()) if x])
if title:
return title
return super(Person, self).getTitle(**kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getTitle')
def getTitle(self, **kw):
"""
Returns the title if it exists or a combination of
first name, middle name and last name
"""
title = ' '.join([x for x in (self.getFirstName(),
self.getMiddleName(),
self.getLastName()) if x])
if title:
return title
return super(Person, self).getTitle(**kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getTranslatedTitle')
def getTranslatedTitle(self, **kw):
"""
Returns the title if it exists or a combination of
first name, middle name and last name
"""
title = ' '.join([x for x in (self.getTranslatedFirstName(**kw),
self.getTranslatedMiddleName(**kw),
self.getTranslatedLastName(**kw)) if x])
if title:
return title
return super(Person, self).getTranslatedTitle(**kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getTranslatedTitle')
def getTranslatedTitle(self, **kw):
"""
Returns the title if it exists or a combination of
first name, middle name and last name
"""
title = ' '.join([x for x in (self.getTranslatedFirstName(**kw),
self.getTranslatedMiddleName(**kw),
self.getTranslatedLastName(**kw)) if x])
if title:
return title
return super(Person, self).getTranslatedTitle(**kw)
security.declareProtected(Permissions.AccessContentsInformation,
'title_or_id')
def title_or_id(self):
return self.getTitleOrId()
security.declareProtected(Permissions.AccessContentsInformation,
'title_or_id')
def title_or_id(self):
return self.getTitleOrId()
security.declareProtected(Permissions.AccessContentsInformation,
'hasTitle')
def hasTitle(self):
return self.hasFirstName() or \
self.hasLastName() or \
self.hasMiddleName() or \
self._baseHasTitle()
security.declareProtected(Permissions.AccessContentsInformation,
'hasTitle')
def hasTitle(self):
return self.hasFirstName() or \
self.hasLastName() or \
self.hasMiddleName() or \
self._baseHasTitle()
def __checkUserIdAvailability(self, pas_plugin_class, user_id=None, login=None):
# Encode reference to hex to prevent uppercase/lowercase conflict in
# activity table (when calling countMessageWithTag)
if user_id:
tag = 'set_userid_' + user_id.encode('hex')
def __checkUserIdAvailability(self, pas_plugin_class, user_id=None, login=None):
# Encode reference to hex to prevent uppercase/lowercase conflict in
# activity table (when calling countMessageWithTag)
if user_id:
tag = 'set_userid_' + user_id.encode('hex')
else:
tag = 'set_login_' + login.encode('hex')
# Check that there no existing user
acl_users = getattr(self, 'acl_users', None)
if PluggableAuthService is not None and isinstance(acl_users,
PluggableAuthService.PluggableAuthService.PluggableAuthService):
plugin_name_set = {
plugin_name for plugin_name, plugin_value in acl_users.plugins.listPlugins(
PluggableAuthService.interfaces.plugins.IUserEnumerationPlugin,
) if isinstance(plugin_value, pas_plugin_class)
}
if plugin_name_set:
if any(
user['pluginid'] in plugin_name_set
for user in acl_users.searchUsers(
id=user_id,
login=login,
exact_match=True,
)
):
raise UserExistsError(user_id)
else:
tag = 'set_login_' + login.encode('hex')
# Check that there no existing user
acl_users = getattr(self, 'acl_users', None)
if PluggableAuthService is not None and isinstance(acl_users,
PluggableAuthService.PluggableAuthService.PluggableAuthService):
plugin_name_set = {
plugin_name for plugin_name, plugin_value in acl_users.plugins.listPlugins(
PluggableAuthService.interfaces.plugins.IUserEnumerationPlugin,
) if isinstance(plugin_value, pas_plugin_class)
}
if plugin_name_set:
if any(
user['pluginid'] in plugin_name_set
for user in acl_users.searchUsers(
id=user_id,
login=login,
exact_match=True,
)
):
raise UserExistsError(user_id)
else:
# PAS is used, without expected enumeration plugin: property has no
# effect on user enumeration, skip checks.
# XXX: what if desired plugin becomes active later ?
return
# Check that there is no reindexation related to reference indexation
if self.getPortalObject().portal_activities.countMessageWithTag(tag):
raise UserExistsError(user_id)
# PAS is used, without expected enumeration plugin: property has no
# effect on user enumeration, skip checks.
# XXX: what if desired plugin becomes active later ?
return
# Check that there is no reindexation related to reference indexation
if self.getPortalObject().portal_activities.countMessageWithTag(tag):
raise UserExistsError(user_id)
# Prevent concurrent transaction to set the same reference on 2
# different persons
# XXX: person_module is rather large because of all permission
# declarations, it would be better to find a smaller document to use
# here.
self.getParentValue().serialize()
# Prevent to set the same reference on 2 different persons during the
# same transaction
transactional_variable = getTransactionalVariable()
if tag in transactional_variable:
raise UserExistsError(user_id)
else:
transactional_variable[tag] = None
self.reindexObject(activate_kw={'tag': tag})
# Prevent concurrent transaction to set the same reference on 2
# different persons
# XXX: person_module is rather large because of all permission
# declarations, it would be better to find a smaller document to use
# here.
self.getParentValue().serialize()
# Prevent to set the same reference on 2 different persons during the
# same transaction
transactional_variable = getTransactionalVariable()
if tag in transactional_variable:
raise UserExistsError(user_id)
else:
transactional_variable[tag] = None
self.reindexObject(activate_kw={'tag': tag})
def _setReference(self, value):
"""
Set the user id. This method is defined explicitly, because
we want to prevent duplicated user ids, but only when
PAS _AND_ ERP5UserManager are used
"""
if value != self.getReference():
if value:
self.__checkUserIdAvailability(
pas_plugin_class=ERP5UserManager,
login=value,
)
self._baseSetReference(value)
# invalid the cache for ERP5Security
self.getPortalObject().portal_caches.clearCache(cache_factory_list=('erp5_content_short', ))
def _setReference(self, value):
"""
Set the user id. This method is defined explicitly, because
we want to prevent duplicated user ids, but only when
PAS _AND_ ERP5UserManager are used
"""
if value != self.getReference():
if value:
self.__checkUserIdAvailability(
pas_plugin_class=ERP5UserManager,
login=value,
)
self._baseSetReference(value)
# invalid the cache for ERP5Security
self.getPortalObject().portal_caches.clearCache(cache_factory_list=('erp5_content_short', ))
def _setUserId(self, value):
"""
Set the user id. This method is defined explicitly, because:
def _setUserId(self, value):
"""
Set the user id. This method is defined explicitly, because:
- we want to apply a different permission
- we want to apply a different permission
- we want to prevent duplicated user ids, but only when
PAS _AND_ ERP5LoginUserManager are used
"""
if value != self.getUserId():
if value:
self.__checkUserIdAvailability(
pas_plugin_class=ERP5LoginUserManager,
user_id=value,
)
self._baseSetUserId(value)
- we want to prevent duplicated user ids, but only when
PAS _AND_ ERP5LoginUserManager are used
"""
if value != self.getUserId():
if value:
self.__checkUserIdAvailability(
pas_plugin_class=ERP5LoginUserManager,
user_id=value,
)
self._baseSetUserId(value)
# Time management
security.declareProtected(Permissions.AccessContentsInformation,
'getAvailableTime')
def getAvailableTime(self, *args, **kw):
"""
Calculate available time for a person
# Time management
security.declareProtected(Permissions.AccessContentsInformation,
'getAvailableTime')
def getAvailableTime(self, *args, **kw):
"""
Calculate available time for a person
See SimulationTool.getAvailableTime
"""
kw['node'] = [self.getUid()]
See SimulationTool.getAvailableTime
"""
kw['node'] = [self.getUid()]
portal_simulation = self.getPortalObject().portal_simulation
return portal_simulation.getAvailableTime(*args, **kw)
portal_simulation = self.getPortalObject().portal_simulation
return portal_simulation.getAvailableTime(*args, **kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getAvailableTimeSequence')
def getAvailableTimeSequence(self, *args, **kw):
"""
Calculate available time for a person in a sequence
security.declareProtected(Permissions.AccessContentsInformation,
'getAvailableTimeSequence')
def getAvailableTimeSequence(self, *args, **kw):
"""
Calculate available time for a person in a sequence
See SimulationTool.getAvailableTimeSequence
"""
kw['node'] = [self.getUid()]
See SimulationTool.getAvailableTimeSequence
"""
kw['node'] = [self.getUid()]
portal_simulation = self.getPortalObject().portal_simulation
return portal_simulation.getAvailableTimeSequence(*args, **kw)
portal_simulation = self.getPortalObject().portal_simulation
return portal_simulation.getAvailableTimeSequence(*args, **kw)
# Notifiation API
security.declareProtected(Permissions.AccessContentsInformation,
'notifyMessage')
def notifyMessage(self, message):
"""
This method can only be called with proxy roles.
# Notifiation API
security.declareProtected(Permissions.AccessContentsInformation,
'notifyMessage')
def notifyMessage(self, message):
"""
This method can only be called with proxy roles.
A per user preference allows for deciding how to be notified.
- by email
- by SMS (if meaningful)
- daily
- weekly
- instantly
A per user preference allows for deciding how to be notified.
- by email
- by SMS (if meaningful)
- daily
- weekly
- instantly
notification is handled as an activity
"""
notification is handled as an activity
"""
......@@ -33,36 +33,36 @@ from Products.ERP5Type.ERP5Type \
import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
class RoleDefinition(XMLObject):
# CMF Type Definition
meta_type = 'ERP5 Role Definition'
portal_type = 'Role Definition'
add_permission = Permissions.ChangeLocalRoles
# CMF Type Definition
meta_type = 'ERP5 Role Definition'
portal_type = 'Role Definition'
add_permission = Permissions.ChangeLocalRoles
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
zope.interface.implements(interfaces.ILocalRoleGenerator)
zope.interface.implements(interfaces.ILocalRoleGenerator)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.RoleDefinition
)
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.RoleDefinition
)
def _setRoleName(self, value):
if value and value not in \
zip(*self.RoleDefinition_getRoleNameItemList())[1]:
raise Unauthorized("You are not allowed to give %s role" % value)
self._baseSetRoleName(value)
def _setRoleName(self, value):
if value and value not in \
zip(*self.RoleDefinition_getRoleNameItemList())[1]:
raise Unauthorized("You are not allowed to give %s role" % value)
self._baseSetRoleName(value)
security.declarePrivate("getLocalRolesFor")
def getLocalRolesFor(self, ob, user_name=None):
group_id_generator = getattr(ob,
ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT)
role_list = self.getRoleName(),
return {group_id: role_list
for group_id in group_id_generator(category_order=('agent',),
agent=self.getAgentList())}
security.declarePrivate("getLocalRolesFor")
def getLocalRolesFor(self, ob, user_name=None):
group_id_generator = getattr(ob,
ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT)
role_list = self.getRoleName(),
return {group_id: role_list
for group_id in group_id_generator(category_order=('agent',),
agent=self.getAgentList())}
......@@ -32,49 +32,49 @@ from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Path import Path
class SupplyCell(Path):
"""A Supply Cell is used for different variations in a supply line.
"""
"""A Supply Cell is used for different variations in a supply line.
"""
meta_type = 'ERP5 Supply Cell'
portal_type = 'Supply Cell'
add_permission = Permissions.AddPortalContent
meta_type = 'ERP5 Supply Cell'
portal_type = 'Supply Cell'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.CategoryCore
, PropertySheet.Amount
, PropertySheet.Task
, PropertySheet.Movement
, PropertySheet.Price
, PropertySheet.SupplyLine
, PropertySheet.Discount
, PropertySheet.Path
, PropertySheet.FlowCapacity
, PropertySheet.Predicate
, PropertySheet.MappedValue
, PropertySheet.Reference
)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.CategoryCore
, PropertySheet.Amount
, PropertySheet.Task
, PropertySheet.Movement
, PropertySheet.Price
, PropertySheet.SupplyLine
, PropertySheet.Discount
, PropertySheet.Path
, PropertySheet.FlowCapacity
, PropertySheet.Predicate
, PropertySheet.MappedValue
, PropertySheet.Reference
)
security.declareProtected( Permissions.AccessContentsInformation,
'hasCellContent' )
def hasCellContent(self, base_id='movement'):
"""A cell cannot have cell content itself.
"""
return 0
security.declareProtected( Permissions.AccessContentsInformation,
'hasCellContent' )
def hasCellContent(self, base_id='movement'):
"""A cell cannot have cell content itself.
"""
return 0
# Override getQuantityUnitXXX to negate same methods defined in
# Amount class. Because cell must acquire quantity unit from line
# not from resource.
security.declareProtected( Permissions.AccessContentsInformation,
'getQuantityUnitValue')
def getQuantityUnitValue(self):
return self.getParentValue().getQuantityUnitValue()
# Override getQuantityUnitXXX to negate same methods defined in
# Amount class. Because cell must acquire quantity unit from line
# not from resource.
security.declareProtected( Permissions.AccessContentsInformation,
'getQuantityUnitValue')
def getQuantityUnitValue(self):
return self.getParentValue().getQuantityUnitValue()
security.declareProtected( Permissions.AccessContentsInformation,
'getQuantityUnit')
def getQuantityUnit(self, checked_permission=None):
return self.getParentValue().getQuantityUnit(checked_permission=checked_permission)
security.declareProtected( Permissions.AccessContentsInformation,
'getQuantityUnit')
def getQuantityUnit(self, checked_permission=None):
return self.getParentValue().getQuantityUnit(checked_permission=checked_permission)
......@@ -37,208 +37,208 @@ from Products.ERP5Type.Utils import convertToUpperCase
class SupplyLine(Path, Amount, XMLMatrix):
"""A Supply Line is a path to define price
"""
meta_type = 'ERP5 Supply Line'
portal_type = 'Supply Line'
add_permission = Permissions.AddPortalContent
isPredicate = ConstantGetter('isPredicate', value=True)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.Amount
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Movement
, PropertySheet.Price
, PropertySheet.SupplyLine
, PropertySheet.VariationRange
, PropertySheet.Path
, PropertySheet.FlowCapacity
, PropertySheet.Predicate
, PropertySheet.Comment
, PropertySheet.Reference
)
#############################################
# Pricing methods
#############################################
security.declareProtected(Permissions.AccessContentsInformation,
'getPrice')
def getPrice(self):
# FIXME: this have to be done in an interaction wf
if getattr(self, 'price', None) is None:
self.price = 0.0
# Return the price
return self.price
security.declareProtected(Permissions.AccessContentsInformation,
'getTotalPrice')
def getTotalPrice(self):
"""
Returns the totals price for this line
"""
quantity = self.getQuantity() or 0.0
price = self.getPrice() or 0.0
return quantity * price
def _getPrice(self, context):
return 0.0
def _getTotalPrice(self, context):
return 0.0
security.declareProtected(Permissions.AccessContentsInformation,
'isAccountable')
def isAccountable(self):
"""Supply Line are not accounted.
"""
return 0
#############################################
# Predicate method
#############################################
asPredicate = Path.asPredicate
#############################################
# XMLMatrix methods
# XXX to be removed if possible
#############################################
security.declareProtected(Permissions.AccessContentsInformation,
'hasCellContent')
def hasCellContent(self, base_id='path'):
"""
This method can be overriden
"""
return XMLMatrix.hasCellContent(self, base_id=base_id)
security.declareProtected(Permissions.AccessContentsInformation,
'getCellValueList' )
def getCellValueList(self, base_id='path'):
"""
This method can be overriden
"""
return XMLMatrix.getCellValueList(self, base_id=base_id)
security.declareProtected(Permissions.AccessContentsInformation, 'getCell')
def getCell(self, *kw , **kwd):
"""
This method can be overriden
"""
kwd.setdefault('base_id', 'path')
return XMLMatrix.getCell(self, *kw, **kwd)
security.declareProtected(Permissions.ModifyPortalContent, 'newCell')
def newCell(self, *kw, **kwd):
"""
This method creates a new cell
"""
kwd.setdefault('base_id', 'path')
return XMLMatrix.newCell(self, *kw, **kwd)
############################################################
# Quantity predicate API
############################################################
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityPredicateIdList')
def getQuantityPredicateIdList(self, price_parameter):
"""
Return predicate id related to a price parameter.
"""
predicate_id_start_with = "quantity_range_"
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % \
(price_parameter, predicate_id_start_with)
# XXX Hardcoded portal type name
predicate_list = self.objectValues(portal_type='Predicate',
sort_on=('int_index', 'id'))
predicate_list.sort(key=lambda p: p.getIntIndex() or p.getId())
predicate_id_list = [x.getId() for x in predicate_list]
result = [x for x in predicate_id_list \
"""A Supply Line is a path to define price
"""
meta_type = 'ERP5 Supply Line'
portal_type = 'Supply Line'
add_permission = Permissions.AddPortalContent
isPredicate = ConstantGetter('isPredicate', value=True)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.Amount
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Movement
, PropertySheet.Price
, PropertySheet.SupplyLine
, PropertySheet.VariationRange
, PropertySheet.Path
, PropertySheet.FlowCapacity
, PropertySheet.Predicate
, PropertySheet.Comment
, PropertySheet.Reference
)
#############################################
# Pricing methods
#############################################
security.declareProtected(Permissions.AccessContentsInformation,
'getPrice')
def getPrice(self):
# FIXME: this have to be done in an interaction wf
if getattr(self, 'price', None) is None:
self.price = 0.0
# Return the price
return self.price
security.declareProtected(Permissions.AccessContentsInformation,
'getTotalPrice')
def getTotalPrice(self):
"""
Returns the totals price for this line
"""
quantity = self.getQuantity() or 0.0
price = self.getPrice() or 0.0
return quantity * price
def _getPrice(self, context):
return 0.0
def _getTotalPrice(self, context):
return 0.0
security.declareProtected(Permissions.AccessContentsInformation,
'isAccountable')
def isAccountable(self):
"""Supply Line are not accounted.
"""
return 0
#############################################
# Predicate method
#############################################
asPredicate = Path.asPredicate
#############################################
# XMLMatrix methods
# XXX to be removed if possible
#############################################
security.declareProtected(Permissions.AccessContentsInformation,
'hasCellContent')
def hasCellContent(self, base_id='path'):
"""
This method can be overriden
"""
return XMLMatrix.hasCellContent(self, base_id=base_id)
security.declareProtected(Permissions.AccessContentsInformation,
'getCellValueList' )
def getCellValueList(self, base_id='path'):
"""
This method can be overriden
"""
return XMLMatrix.getCellValueList(self, base_id=base_id)
security.declareProtected(Permissions.AccessContentsInformation, 'getCell')
def getCell(self, *kw , **kwd):
"""
This method can be overriden
"""
kwd.setdefault('base_id', 'path')
return XMLMatrix.getCell(self, *kw, **kwd)
security.declareProtected(Permissions.ModifyPortalContent, 'newCell')
def newCell(self, *kw, **kwd):
"""
This method creates a new cell
"""
kwd.setdefault('base_id', 'path')
return XMLMatrix.newCell(self, *kw, **kwd)
############################################################
# Quantity predicate API
############################################################
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityPredicateIdList')
def getQuantityPredicateIdList(self, price_parameter):
"""
Return predicate id related to a price parameter.
"""
predicate_id_start_with = "quantity_range_"
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % \
(price_parameter, predicate_id_start_with)
# XXX Hardcoded portal type name
predicate_list = self.objectValues(portal_type='Predicate',
sort_on=('int_index', 'id'))
predicate_list.sort(key=lambda p: p.getIntIndex() or p.getId())
predicate_id_list = [x.getId() for x in predicate_list]
result = [x for x in predicate_id_list \
if x.startswith(predicate_id_start_with)]
return result
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityPredicateValueList')
def getQuantityPredicateValueList(self, price_parameter):
"""
Return predicate related to a price parameter.
"""
result = [self[x] for x in \
self.getQuantityPredicateIdList(price_parameter)]
return result
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityStepList')
def getQuantityStepList(self, *args, **kw):
"""
Return predicate step related to a price_parameter
"""
# We need to keep compatibility with generated accessor
price_parameter = kw.get('price_parameter', "base_price")
if price_parameter in ("base_price", "slice_base_price"):
method_name = "_baseGetQuantityStepList"
else:
method_name = 'get%sList' % \
convertToUpperCase("%s_quantity_step" % price_parameter)
return getattr(self, method_name)() or []
security.declareProtected(Permissions.ModifyPortalContent,
'updateQuantityPredicate')
def updateQuantityPredicate(self, price_parameter):
"""
Update the quantity predicate for this price parameter
"""
quantity_step_list = self.getQuantityStepList(price_parameter=price_parameter)
unused_predicate_id_set = self.getQuantityPredicateIdList(price_parameter)
if quantity_step_list:
quantity_step_list.sort()
quantity_step_list = [None] + quantity_step_list + [None]
getTitle = getattr(
self,
'SupplyLine_getTitle',
lambda min, max: (
(
'' if min is None else '%s <= ' % (min, )
) + 'quantity' + (
'' if max is None else ' < %s' % (max, )
)
),
)
predicate_id_start_with = "quantity_range"
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % (
price_parameter,
predicate_id_start_with,
return result
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityPredicateValueList')
def getQuantityPredicateValueList(self, price_parameter):
"""
Return predicate related to a price parameter.
"""
result = [self[x] for x in \
self.getQuantityPredicateIdList(price_parameter)]
return result
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantityStepList')
def getQuantityStepList(self, *args, **kw):
"""
Return predicate step related to a price_parameter
"""
# We need to keep compatibility with generated accessor
price_parameter = kw.get('price_parameter', "base_price")
if price_parameter in ("base_price", "slice_base_price"):
method_name = "_baseGetQuantityStepList"
else:
method_name = 'get%sList' % \
convertToUpperCase("%s_quantity_step" % price_parameter)
return getattr(self, method_name)() or []
security.declareProtected(Permissions.ModifyPortalContent,
'updateQuantityPredicate')
def updateQuantityPredicate(self, price_parameter):
"""
Update the quantity predicate for this price parameter
"""
quantity_step_list = self.getQuantityStepList(price_parameter=price_parameter)
unused_predicate_id_set = self.getQuantityPredicateIdList(price_parameter)
if quantity_step_list:
quantity_step_list.sort()
quantity_step_list = [None] + quantity_step_list + [None]
getTitle = getattr(
self,
'SupplyLine_getTitle',
lambda min, max: (
(
'' if min is None else '%s <= ' % (min, )
) + 'quantity' + (
'' if max is None else ' < %s' % (max, )
)
for i in range(len(quantity_step_list) - 1):
min_quantity = quantity_step_list[i]
max_quantity = quantity_step_list[i + 1]
predicate_id = '%s_%s' % (predicate_id_start_with, i)
try:
predicate_value = self[predicate_id]
except KeyError:
# XXX Hardcoded portal type name
predicate_value = self.newContent(
id='%s_%s' % (predicate_id_start_with, i),
portal_type='Predicate',
int_index=i + 1,
)
else:
unused_predicate_id_set.remove(predicate_id)
predicate_value.setTitle(getTitle(min=min_quantity, max=max_quantity))
predicate_value.setCriterionPropertyList(('quantity', ))
predicate_value.setCriterion(
'quantity',
min=min_quantity,
max=(None if price_parameter == 'slice_base_price' else max_quantity),
),
)
predicate_id_start_with = "quantity_range"
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % (
price_parameter,
predicate_id_start_with,
)
for i in range(len(quantity_step_list) - 1):
min_quantity = quantity_step_list[i]
max_quantity = quantity_step_list[i + 1]
predicate_id = '%s_%s' % (predicate_id_start_with, i)
try:
predicate_value = self[predicate_id]
except KeyError:
# XXX Hardcoded portal type name
predicate_value = self.newContent(
id='%s_%s' % (predicate_id_start_with, i),
portal_type='Predicate',
int_index=i + 1,
)
if unused_predicate_id_set:
self.deleteContent(unused_predicate_id_set)
else:
unused_predicate_id_set.remove(predicate_id)
predicate_value.setTitle(getTitle(min=min_quantity, max=max_quantity))
predicate_value.setCriterionPropertyList(('quantity', ))
predicate_value.setCriterion(
'quantity',
min=min_quantity,
max=(None if price_parameter == 'slice_base_price' else max_quantity),
)
if unused_predicate_id_set:
self.deleteContent(unused_predicate_id_set)
......@@ -791,9 +791,9 @@ class BuilderMixin(XMLObject, Amount, Predicate):
category_index_dict[i.getId()] = i.getIntIndex()
def sort_movement_group(a, b):
return cmp(category_index_dict.get(a.getCollectOrderGroup()),
category_index_dict.get(b.getCollectOrderGroup())) or \
cmp(a.getIntIndex(), b.getIntIndex())
return cmp(category_index_dict.get(a.getCollectOrderGroup()),
category_index_dict.get(b.getCollectOrderGroup())) or \
cmp(a.getIntIndex(), b.getIntIndex())
if portal_type is None:
portal_type = self.getPortalMovementGroupTypeList()
movement_group_list = [x for x in self.contentValues(filter={'portal_type': portal_type}) \
......
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