Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Titouan Soulard
erp5
Commits
1ff851b1
Commit
1ff851b1
authored
Dec 24, 2019
by
Arnaud Fontaine
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ZODB Components: Preparation of erp5_base migration from FS: Fix pylint bad-indentation warnings.
parent
187c6554
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
719 additions
and
721 deletions
+719
-721
product/ERP5/Document/AgentPrivilege.py
product/ERP5/Document/AgentPrivilege.py
+17
-17
product/ERP5/Document/Assignment.py
product/ERP5/Document/Assignment.py
+17
-17
product/ERP5/Document/BankAccount.py
product/ERP5/Document/BankAccount.py
+26
-26
product/ERP5/Document/Career.py
product/ERP5/Document/Career.py
+20
-20
product/ERP5/Document/Coordinate.py
product/ERP5/Document/Coordinate.py
+174
-176
product/ERP5/Document/Image.py
product/ERP5/Document/Image.py
+5
-5
product/ERP5/Document/Organisation.py
product/ERP5/Document/Organisation.py
+19
-19
product/ERP5/Document/Person.py
product/ERP5/Document/Person.py
+168
-168
product/ERP5/Document/RoleDefinition.py
product/ERP5/Document/RoleDefinition.py
+28
-28
product/ERP5/Document/SupplyCell.py
product/ERP5/Document/SupplyCell.py
+40
-40
product/ERP5/Document/SupplyLine.py
product/ERP5/Document/SupplyLine.py
+202
-202
product/ERP5/mixin/builder.py
product/ERP5/mixin/builder.py
+3
-3
No files found.
product/ERP5/Document/AgentPrivilege.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/Document/Assignment.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/Document/BankAccount.py
View file @
1ff851b1
...
...
@@ -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.
...
...
product/ERP5/Document/Career.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/Document/Coordinate.py
View file @
1ff851b1
...
...
@@ -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
())
product/ERP5/Document/Image.py
View file @
1ff851b1
...
...
@@ -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
)
...
...
product/ERP5/Document/Organisation.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/Document/Person.py
View file @
1ff851b1
...
...
@@ -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
"""
product/ERP5/Document/RoleDefinition.py
View file @
1ff851b1
...
...
@@ -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
())}
product/ERP5/Document/SupplyCell.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/Document/SupplyLine.py
View file @
1ff851b1
...
...
@@ -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
)
product/ERP5/mixin/builder.py
View file @
1ff851b1
...
...
@@ -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
})
\
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment