Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5_fork
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eteri
erp5_fork
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