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