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