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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Romain Courteaud
erp5
Commits
8080c57b
Commit
8080c57b
authored
Feb 11, 2020
by
Romain Courteaud
🐸
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "ZODB Components: Preparation of erp5_base migration from FS: One Mixin per source file."
This reverts commit
66f30ebb
.
parent
0cec7b82
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
434 additions
and
629 deletions
+434
-629
bt5/erp5_mrp/DocumentTemplateItem/portal_components/document.erp5.ProductionSimulationRule.py
...rtal_components/document.erp5.ProductionSimulationRule.py
+1
-1
bt5/erp5_web/DocumentTemplateItem/portal_components/document.erp5.StaticWebSection.py
...eItem/portal_components/document.erp5.StaticWebSection.py
+1
-1
product/ERP5/Document/AcceptSolver.py
product/ERP5/Document/AcceptSolver.py
+1
-1
product/ERP5/Document/AdoptSolver.py
product/ERP5/Document/AdoptSolver.py
+1
-1
product/ERP5/Document/Delivery.py
product/ERP5/Document/Delivery.py
+1
-1
product/ERP5/Document/DeliveryRootSimulationRule.py
product/ERP5/Document/DeliveryRootSimulationRule.py
+1
-2
product/ERP5/Document/DeliverySimulationRule.py
product/ERP5/Document/DeliverySimulationRule.py
+1
-2
product/ERP5/Document/Document.py
product/ERP5/Document/Document.py
+1
-1
product/ERP5/Document/InvoiceSimulationRule.py
product/ERP5/Document/InvoiceSimulationRule.py
+1
-2
product/ERP5/Document/InvoiceTransactionSimulationRule.py
product/ERP5/Document/InvoiceTransactionSimulationRule.py
+1
-2
product/ERP5/Document/OrderRootSimulationRule.py
product/ERP5/Document/OrderRootSimulationRule.py
+1
-2
product/ERP5/Document/PaymentSimulationRule.py
product/ERP5/Document/PaymentSimulationRule.py
+1
-2
product/ERP5/Document/SubscriptionItem.py
product/ERP5/Document/SubscriptionItem.py
+1
-2
product/ERP5/Document/TradeModelSimulationRule.py
product/ERP5/Document/TradeModelSimulationRule.py
+1
-2
product/ERP5/Document/TransformationSimulationRule.py
product/ERP5/Document/TransformationSimulationRule.py
+1
-2
product/ERP5/Document/TransformationSourcingSimulationRule.py
...uct/ERP5/Document/TransformationSourcingSimulationRule.py
+1
-2
product/ERP5/Document/WebSection.py
product/ERP5/Document/WebSection.py
+1
-1
product/ERP5/mixin/configurable_property_solver.py
product/ERP5/mixin/configurable_property_solver.py
+0
-86
product/ERP5/mixin/document_extensible_traversable.py
product/ERP5/mixin/document_extensible_traversable.py
+0
-63
product/ERP5/mixin/extensible_traversable.py
product/ERP5/mixin/extensible_traversable.py
+70
-8
product/ERP5/mixin/movement_generator.py
product/ERP5/mixin/movement_generator.py
+0
-119
product/ERP5/mixin/ooo_document_extensible_traversable.py
product/ERP5/mixin/ooo_document_extensible_traversable.py
+0
-67
product/ERP5/mixin/rule.py
product/ERP5/mixin/rule.py
+240
-0
product/ERP5/mixin/simulable.py
product/ERP5/mixin/simulable.py
+0
-175
product/ERP5/mixin/solver.py
product/ERP5/mixin/solver.py
+53
-1
product/ERP5Configurator/Document/SecurityCategoryMappingConfiguratorItem.py
...rator/Document/SecurityCategoryMappingConfiguratorItem.py
+1
-1
product/ERP5Configurator/mixin/configurator_item.py
product/ERP5Configurator/mixin/configurator_item.py
+52
-0
product/ERP5Configurator/mixin/skin_configurator_item.py
product/ERP5Configurator/mixin/skin_configurator_item.py
+0
-81
product/ERP5OOo/Document/OOoDocument.py
product/ERP5OOo/Document/OOoDocument.py
+1
-1
No files found.
bt5/erp5_mrp/DocumentTemplateItem/portal_components/document.erp5.ProductionSimulationRule.py
View file @
8080c57b
from
Products.ERP5.Document.DeliverySimulationRule
import
DeliverySimulationRule
from
Products.ERP5.mixin.
movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.
rule
import
MovementGeneratorMixin
class
ProductionSimulationRule
(
DeliverySimulationRule
):
"""
...
...
bt5/erp5_web/DocumentTemplateItem/portal_components/document.erp5.StaticWebSection.py
View file @
8080c57b
...
...
@@ -31,7 +31,7 @@ from AccessControl import ClassSecurityInfo
from
Acquisition
import
aq_base
from
OFS.Traversable
import
NotFound
from
Products.ERP5.mixin.
document_
extensible_traversable
import
DocumentExtensibleTraversableMixin
from
Products.ERP5.mixin.extensible_traversable
import
DocumentExtensibleTraversableMixin
from
Products.ERP5.Document.WebSection
import
WebSection
from
Products.ERP5Type
import
Permissions
...
...
product/ERP5/Document/AcceptSolver.py
View file @
8080c57b
...
...
@@ -29,7 +29,7 @@
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
from
Products.ERP5.mixin.
configurable_property_
solver
import
ConfigurablePropertySolverMixin
from
Products.ERP5.mixin.solver
import
ConfigurablePropertySolverMixin
class
AcceptSolver
(
ConfigurablePropertySolverMixin
):
"""Target solver that accepts the values from the decision on the prevision.
...
...
product/ERP5/Document/AdoptSolver.py
View file @
8080c57b
...
...
@@ -29,7 +29,7 @@
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
from
Products.ERP5.mixin.
configurable_property_
solver
import
ConfigurablePropertySolverMixin
from
Products.ERP5.mixin.solver
import
ConfigurablePropertySolverMixin
class
AdoptSolver
(
ConfigurablePropertySolverMixin
):
"""Target solver that adopts the values from the prevision on the decision.
...
...
product/ERP5/Document/Delivery.py
View file @
8080c57b
...
...
@@ -41,7 +41,7 @@ from Products.ERP5Type.XMLObject import XMLObject
from
Products.ERP5.Document.ImmobilisationDelivery
import
ImmobilisationDelivery
from
Products.ERP5.mixin.amount_generator
import
AmountGeneratorMixin
from
Products.ERP5.mixin.composition
import
CompositionMixin
from
Products.ERP5.mixin.
simulab
le
import
SimulableMixin
from
Products.ERP5.mixin.
ru
le
import
SimulableMixin
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
,
\
unrestricted_apply
from
zLOG
import
LOG
,
PROBLEM
...
...
product/ERP5/Document/DeliveryRootSimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/DeliverySimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/Document.py
View file @
8080c57b
...
...
@@ -206,7 +206,7 @@ class DocumentConversionServerProxy():
def
__getattr__
(
self
,
attr
):
return
partial
(
self
.
_proxy_function
,
attr
)
from
Products.ERP5.mixin.
document_
extensible_traversable
import
DocumentExtensibleTraversableMixin
from
Products.ERP5.mixin.extensible_traversable
import
DocumentExtensibleTraversableMixin
class
Document
(
DocumentExtensibleTraversableMixin
,
XMLObject
,
UrlMixin
,
CachedConvertableMixin
,
CrawlableMixin
,
TextConvertableMixin
,
...
...
product/ERP5/Document/InvoiceSimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/InvoiceTransactionSimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
from
Products.ERP5.Document.PredicateMatrix
import
PredicateMatrix
...
...
product/ERP5/Document/OrderRootSimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/PaymentSimulationRule.py
View file @
8080c57b
...
...
@@ -29,8 +29,7 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/SubscriptionItem.py
View file @
8080c57b
...
...
@@ -33,8 +33,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.Document.Item
import
Item
from
Products.ERP5.mixin.composition
import
CompositionMixin
from
Products.ERP5.mixin.simulable
import
SimulableMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
MovementGeneratorMixin
,
SimulableMixin
from
Products.ERP5.mixin.periodicity
import
PeriodicityMixin
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
from
Products.ERP5Type.Base
import
Base
...
...
product/ERP5/Document/TradeModelSimulationRule.py
View file @
8080c57b
...
...
@@ -30,8 +30,7 @@ import zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_base
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/TransformationSimulationRule.py
View file @
8080c57b
...
...
@@ -31,8 +31,7 @@ from AccessControl import ClassSecurityInfo
from
Acquisition
import
aq_base
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/TransformationSourcingSimulationRule.py
View file @
8080c57b
...
...
@@ -30,8 +30,7 @@ import zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_base
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.mixin.rule
import
RuleMixin
from
Products.ERP5.mixin.movement_generator
import
MovementGeneratorMixin
from
Products.ERP5.mixin.rule
import
RuleMixin
,
MovementGeneratorMixin
from
Products.ERP5.mixin.movement_collection_updater
import
\
MovementCollectionUpdaterMixin
...
...
product/ERP5/Document/WebSection.py
View file @
8080c57b
...
...
@@ -30,7 +30,7 @@
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.Document.Domain
import
Domain
from
Products.ERP5.mixin.
document_
extensible_traversable
import
DocumentExtensibleTraversableMixin
from
Products.ERP5.mixin.extensible_traversable
import
DocumentExtensibleTraversableMixin
from
Acquisition
import
aq_base
,
aq_inner
from
Products.ERP5Type.UnrestrictedMethod
import
unrestricted_apply
from
AccessControl
import
Unauthorized
...
...
product/ERP5/mixin/configurable_property_solver.py
deleted
100644 → 0
View file @
0cec7b82
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5.mixin.solver
import
SolverMixin
from
Products.ERP5.mixin.configurable
import
ConfigurableMixin
class
ConfigurablePropertySolverMixin
(
SolverMixin
,
ConfigurableMixin
,
XMLObject
):
"""
Base class for Target Solvers that can be applied to many
solver-decisions of a solver process, and need to accumulate the
tested_property_list configuration among all solver-decisions
"""
add_permission
=
Permissions
.
AddPortalContent
isIndexable
=
0
# We do not want to fill the catalog with objects on which we need no reporting
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
zope
.
interface
.
implements
(
interfaces
.
ISolver
,
interfaces
.
IConfigurable
,)
# Default Properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
TargetSolver
)
def
updateConfiguration
(
self
,
**
kw
):
# This method is called once for each 'Solver Decision' of a
# 'Solver Process' that maps into this solver for the same
# Simulation Movement, so we need to take care not to lose
# information by overwriting.
configuration
=
self
.
_getConfigurationPropertyDict
()
tested_property_list
=
configuration
.
get
(
'tested_property_list'
)
if
tested_property_list
is
not
None
:
tested_property_set
=
set
(
tested_property_list
)
tested_property_set
.
update
(
kw
.
get
(
'tested_property_list'
,
()))
kw
[
'tested_property_list'
]
=
list
(
tested_property_set
)
super
(
ConfigurablePropertySolverMixin
,
self
).
updateConfiguration
(
**
kw
)
def
getTestedPropertyList
(
self
):
configuration_dict
=
self
.
getConfigurationPropertyDict
()
tested_property_list
=
configuration_dict
.
get
(
'tested_property_list'
)
if
tested_property_list
is
None
:
portal_type
=
self
.
getPortalObject
().
portal_types
.
getTypeInfo
(
self
)
tested_property_list
=
portal_type
.
getTestedPropertyList
()
return
tested_property_list
InitializeClass
(
ConfigurablePropertySolverMixin
)
product/ERP5/mixin/document_extensible_traversable.py
deleted
100644 → 0
View file @
0cec7b82
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Ivan Tyagov <ivan@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
Acquisition
import
aq_base
from
AccessControl
import
Unauthorized
from
AccessControl.SecurityManagement
import
setSecurityManager
from
Products.ERP5.mixin.base_extensible_traversable
import
BaseExtensibleTraversableMixin
from
Products.ERP5Type.UnrestrictedMethod
import
unrestricted_apply
class
DocumentExtensibleTraversableMixin
(
BaseExtensibleTraversableMixin
):
"""
This class provides a implementation of IExtensibleTraversable for Document classed based documents.
"""
def
getExtensibleContent
(
self
,
request
,
name
):
old_manager
,
user
=
self
.
_forceIdentification
(
request
)
# Next get the document per name
portal
=
self
.
getPortalObject
()
document
=
self
.
getDocumentValue
(
name
=
name
,
portal
=
portal
)
# restore original security context if there's a logged in user
if
user
is
not
None
:
setSecurityManager
(
old_manager
)
if
document
is
not
None
:
document
=
aq_base
(
document
.
asContext
(
id
=
name
,
# Hide some properties to permit locating the original
original_container
=
document
.
getParentValue
(),
original_id
=
document
.
getId
(),
editable_absolute_url
=
document
.
absolute_url
()))
return
document
.
__of__
(
self
)
# no document found for current user, still such document may exists
# in some cases user (like Anonymous) can not view document according to portal catalog
# but we may ask him to login if such a document exists
isAuthorizationForced
=
getattr
(
self
,
'isAuthorizationForced'
,
None
)
if
isAuthorizationForced
is
not
None
and
isAuthorizationForced
():
if
unrestricted_apply
(
self
.
getDocumentValue
,
(
name
,
portal
))
is
not
None
:
# force user to login as specified in Web Section
raise
Unauthorized
product/ERP5/mixin/
base_
extensible_traversable.py
→
product/ERP5/mixin/extensible_traversable.py
View file @
8080c57b
...
...
@@ -27,22 +27,26 @@
#
##############################################################################
from
warnings
import
warn
from
base64
import
decodestring
from
zLOG
import
LOG
from
AccessControl
import
ClassSecurityInfo
,
getSecurityManager
from
AccessControl.SecurityManagement
import
newSecurityManager
,
setSecurityManager
from
Products.CMFCore.utils
import
getToolByName
from
Acquisition
import
aq_base
from
Products.ERP5Type.Globals
import
get_request
from
AccessControl
import
Unauthorized
from
Products.ERP5Type.ExtensibleTraversable
import
ExtensibleTraversableMixIn
from
Products.ERP5Type.Cache
import
getReadOnlyTransactionCache
from
AccessControl
import
ClassSecurityInfo
,
getSecurityManager
from
AccessControl.SecurityManagement
import
newSecurityManager
,
setSecurityManager
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.Globals
import
get_request
from
Products.CMFCore.utils
import
getToolByName
,
_checkConditionalGET
,
_setCacheHeaders
,
_ViewEmulator
from
OFS.Image
import
File
as
OFSFile
from
warnings
import
warn
from
base64
import
decodestring
from
Products.ERP5Type.UnrestrictedMethod
import
unrestricted_apply
from
Products.ERP5.Document.Document
import
ConversionError
,
NotConvertedError
# XXX: these duplicate ones in ERP5.Document
_MARKER
=
[]
EMBEDDED_FORMAT
=
'_embedded'
class
BaseExtensibleTraversableMixin
(
ExtensibleTraversableMixIn
):
"""
...
...
@@ -166,3 +170,61 @@ class BaseExtensibleTraversableMixin(ExtensibleTraversableMixIn):
return
document
.
__of__
(
self
)
InitializeClass
(
BaseExtensibleTraversableMixin
)
class
DocumentExtensibleTraversableMixin
(
BaseExtensibleTraversableMixin
):
"""
This class provides a implementation of IExtensibleTraversable for Document classed based documents.
"""
def
getExtensibleContent
(
self
,
request
,
name
):
old_manager
,
user
=
self
.
_forceIdentification
(
request
)
# Next get the document per name
portal
=
self
.
getPortalObject
()
document
=
self
.
getDocumentValue
(
name
=
name
,
portal
=
portal
)
# restore original security context if there's a logged in user
if
user
is
not
None
:
setSecurityManager
(
old_manager
)
if
document
is
not
None
:
document
=
aq_base
(
document
.
asContext
(
id
=
name
,
# Hide some properties to permit locating the original
original_container
=
document
.
getParentValue
(),
original_id
=
document
.
getId
(),
editable_absolute_url
=
document
.
absolute_url
()))
return
document
.
__of__
(
self
)
# no document found for current user, still such document may exists
# in some cases user (like Anonymous) can not view document according to portal catalog
# but we may ask him to login if such a document exists
isAuthorizationForced
=
getattr
(
self
,
'isAuthorizationForced'
,
None
)
if
isAuthorizationForced
is
not
None
and
isAuthorizationForced
():
if
unrestricted_apply
(
self
.
getDocumentValue
,
(
name
,
portal
))
is
not
None
:
# force user to login as specified in Web Section
raise
Unauthorized
class
OOoDocumentExtensibleTraversableMixin
(
BaseExtensibleTraversableMixin
):
"""
This class provides a implementation of IExtensibleTraversable for OOoDocument classed based documents.
"""
def
getExtensibleContent
(
self
,
request
,
name
):
# Be sure that html conversion is done,
# as it is required to extract extensible content
old_manager
,
user
=
self
.
_forceIdentification
(
request
)
web_cache_kw
=
{
'name'
:
name
,
'format'
:
EMBEDDED_FORMAT
}
try
:
self
.
_convert
(
format
=
'html'
)
view
=
_ViewEmulator
().
__of__
(
self
)
# If we have a conditional get, set status 304 and return
# no content
if
_checkConditionalGET
(
view
,
web_cache_kw
):
return
''
# call caching policy manager.
_setCacheHeaders
(
view
,
web_cache_kw
)
mime
,
data
=
self
.
getConversion
(
format
=
EMBEDDED_FORMAT
,
filename
=
name
)
document
=
OFSFile
(
name
,
name
,
data
,
content_type
=
mime
).
__of__
(
self
.
aq_parent
)
except
(
NotConvertedError
,
ConversionError
,
KeyError
):
document
=
DocumentExtensibleTraversableMixin
.
getExtensibleContent
(
self
,
request
,
name
)
# restore original security context if there's a logged in user
if
user
is
not
None
:
setSecurityManager
(
old_manager
)
return
document
product/ERP5/mixin/movement_generator.py
deleted
100644 → 0
View file @
0cec7b82
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
class
MovementGeneratorMixin
(
object
):
"""
This class provides a generic implementation of IMovementGenerator
which can be used together the Rule mixin class bellow. It does not
have any pretention to provide more than that.
TODO:
- _getInputMovementList is still not well defined. Should input
be an amount (_getInputAmountList) or a movement? This
requires careful thiking.
"""
# Default values
_applied_rule
=
None
_rule
=
None
_trade_phase_list
=
None
_explanation
=
None
def
__init__
(
self
,
applied_rule
,
explanation
=
None
,
rule
=
None
,
trade_phase_list
=
None
):
self
.
_trade_phase_list
=
trade_phase_list
# XXX-JPS Why a list ?
self
.
_applied_rule
=
applied_rule
if
rule
is
None
and
applied_rule
is
not
None
:
self
.
_rule
=
applied_rule
.
getSpecialiseValue
()
else
:
self
.
_rule
=
rule
# for rule specific stuff
if
explanation
is
None
:
self
.
_explanation
=
applied_rule
else
:
# A good example of explicit explanation can be getRootExplanationLineValue
# since different lines could have different dates
# such an explicit root explanation only works if
# indexing of simulation has already happened
self
.
_explanation
=
explanation
# XXX-JPS handle delay_mode
# Implementation of IMovementGenerator
def
getGeneratedMovementList
(
self
,
movement_list
=
None
,
rounding
=
False
):
"""
Returns a list of movements generated by that rule.
movement_list - optional IMovementList which can be passed explicitely
rounding - boolean argument, which controls if rounding shall be applied on
generated movements or not
NOTE:
- implement rounding appropriately (True or False seems
simplistic)
"""
# Default implementation below can be overriden by subclasses
# however it should be generic enough not to be overriden
# by most classes
# Results will be appended to result
result
=
[]
# Build a list of movement and business path
input_movement_list
=
self
.
_getInputMovementList
(
movement_list
=
movement_list
,
rounding
=
rounding
)
for
input_movement
in
input_movement_list
:
# Merge movement and business path properties (core implementation)
# Lookup Business Process through composition (NOT UNION)
business_process
=
input_movement
.
asComposedDocument
()
explanation
=
self
.
_applied_rule
# We use applied rule as local explanation
trade_phase
=
self
.
_getTradePhaseList
(
input_movement
,
business_process
)
# XXX-JPS not convenient to handle
update_property_dict
=
self
.
_getUpdatePropertyDict
(
input_movement
)
result
.
extend
(
business_process
.
getTradePhaseMovementList
(
explanation
,
input_movement
,
trade_phase
=
trade_phase
,
delay_mode
=
None
,
update_property_dict
=
update_property_dict
))
# And return list of generated movements
return
result
def
_getUpdatePropertyDict
(
self
,
input_movement
):
# XXX Wouldn't it better to return {} or {'delivery': None} ?
# Below code is mainly for root applied rules.
# Other movement generators usually want to reset delivery.
return
{
'delivery'
:
input_movement
.
getRelativeUrl
()}
def
_getTradePhaseList
(
self
,
input_movement
,
business_process
):
# XXX-JPS WEIRD
if
self
.
_trade_phase_list
:
return
self
.
_trade_phase_list
if
self
.
_rule
is
not
None
:
trade_phase_list
=
self
.
_rule
.
getTradePhaseList
()
if
trade_phase_list
:
return
trade_phase_list
return
input_movement
.
getTradePhaseList
()
or
\
business_process
.
getTradePhaseList
()
def
_getInputMovementList
(
self
,
movement_list
=
None
,
rounding
=
None
):
#XXX-JPS should it be amount or movement ?
raise
NotImplementedError
# Default implementation takes amounts ?
# Use TradeModelRuleMovementGenerator._getInputMovementList as default implementation
# and potentially use trade phase for that.... as a way to filter out
product/ERP5/mixin/ooo_document_extensible_traversable.py
deleted
100644 → 0
View file @
0cec7b82
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Ivan Tyagov <ivan@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
AccessControl.SecurityManagement
import
setSecurityManager
from
Products.CMFCore.utils
import
_checkConditionalGET
,
_setCacheHeaders
,
_ViewEmulator
from
OFS.Image
import
File
as
OFSFile
from
Products.ERP5.Document.Document
import
ConversionError
,
NotConvertedError
from
Products.ERP5.mixin.base_extensible_traversable
import
BaseExtensibleTraversableMixin
from
Products.ERP5.mixin.document_extensible_traversable
import
DocumentExtensibleTraversableMixin
# XXX: these duplicate ones in ERP5.Document
EMBEDDED_FORMAT
=
'_embedded'
class
OOoDocumentExtensibleTraversableMixin
(
BaseExtensibleTraversableMixin
):
"""
This class provides a implementation of IExtensibleTraversable for OOoDocument classed based documents.
"""
def
getExtensibleContent
(
self
,
request
,
name
):
# Be sure that html conversion is done,
# as it is required to extract extensible content
old_manager
,
user
=
self
.
_forceIdentification
(
request
)
web_cache_kw
=
{
'name'
:
name
,
'format'
:
EMBEDDED_FORMAT
}
try
:
self
.
_convert
(
format
=
'html'
)
view
=
_ViewEmulator
().
__of__
(
self
)
# If we have a conditional get, set status 304 and return
# no content
if
_checkConditionalGET
(
view
,
web_cache_kw
):
return
''
# call caching policy manager.
_setCacheHeaders
(
view
,
web_cache_kw
)
mime
,
data
=
self
.
getConversion
(
format
=
EMBEDDED_FORMAT
,
filename
=
name
)
document
=
OFSFile
(
name
,
name
,
data
,
content_type
=
mime
).
__of__
(
self
.
aq_parent
)
except
(
NotConvertedError
,
ConversionError
,
KeyError
):
document
=
DocumentExtensibleTraversableMixin
.
getExtensibleContent
(
self
,
request
,
name
)
# restore original security context if there's a logged in user
if
user
is
not
None
:
setSecurityManager
(
old_manager
)
return
document
product/ERP5/mixin/rule.py
View file @
8080c57b
...
...
@@ -26,12 +26,20 @@
#
##############################################################################
import
transaction
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type.Globals
import
InitializeClass
from
Acquisition
import
aq_base
from
Products.ERP5Type
import
Permissions
,
interfaces
from
Products.ERP5Type.Base
import
Base
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5Type.Errors
import
SimulationError
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5.ExpandPolicy
import
policy_dict
from
Products.ERP5.MovementCollectionDiff
import
_getPropertyAndCategoryList
from
zLOG
import
LOG
def
_compare
(
tester_list
,
prevision_movement
,
decision_movement
):
for
tester
in
tester_list
:
...
...
@@ -39,6 +47,99 @@ def _compare(tester_list, prevision_movement, decision_movement):
return
False
return
True
class
MovementGeneratorMixin
(
object
):
"""
This class provides a generic implementation of IMovementGenerator
which can be used together the Rule mixin class bellow. It does not
have any pretention to provide more than that.
TODO:
- _getInputMovementList is still not well defined. Should input
be an amount (_getInputAmountList) or a movement? This
requires careful thiking.
"""
# Default values
_applied_rule
=
None
_rule
=
None
_trade_phase_list
=
None
_explanation
=
None
def
__init__
(
self
,
applied_rule
,
explanation
=
None
,
rule
=
None
,
trade_phase_list
=
None
):
self
.
_trade_phase_list
=
trade_phase_list
# XXX-JPS Why a list ?
self
.
_applied_rule
=
applied_rule
if
rule
is
None
and
applied_rule
is
not
None
:
self
.
_rule
=
applied_rule
.
getSpecialiseValue
()
else
:
self
.
_rule
=
rule
# for rule specific stuff
if
explanation
is
None
:
self
.
_explanation
=
applied_rule
else
:
# A good example of explicit explanation can be getRootExplanationLineValue
# since different lines could have different dates
# such an explicit root explanation only works if
# indexing of simulation has already happened
self
.
_explanation
=
explanation
# XXX-JPS handle delay_mode
# Implementation of IMovementGenerator
def
getGeneratedMovementList
(
self
,
movement_list
=
None
,
rounding
=
False
):
"""
Returns a list of movements generated by that rule.
movement_list - optional IMovementList which can be passed explicitely
rounding - boolean argument, which controls if rounding shall be applied on
generated movements or not
NOTE:
- implement rounding appropriately (True or False seems
simplistic)
"""
# Default implementation below can be overriden by subclasses
# however it should be generic enough not to be overriden
# by most classes
# Results will be appended to result
result
=
[]
# Build a list of movement and business path
input_movement_list
=
self
.
_getInputMovementList
(
movement_list
=
movement_list
,
rounding
=
rounding
)
for
input_movement
in
input_movement_list
:
# Merge movement and business path properties (core implementation)
# Lookup Business Process through composition (NOT UNION)
business_process
=
input_movement
.
asComposedDocument
()
explanation
=
self
.
_applied_rule
# We use applied rule as local explanation
trade_phase
=
self
.
_getTradePhaseList
(
input_movement
,
business_process
)
# XXX-JPS not convenient to handle
update_property_dict
=
self
.
_getUpdatePropertyDict
(
input_movement
)
result
.
extend
(
business_process
.
getTradePhaseMovementList
(
explanation
,
input_movement
,
trade_phase
=
trade_phase
,
delay_mode
=
None
,
update_property_dict
=
update_property_dict
))
# And return list of generated movements
return
result
def
_getUpdatePropertyDict
(
self
,
input_movement
):
# XXX Wouldn't it better to return {} or {'delivery': None} ?
# Below code is mainly for root applied rules.
# Other movement generators usually want to reset delivery.
return
{
'delivery'
:
input_movement
.
getRelativeUrl
()}
def
_getTradePhaseList
(
self
,
input_movement
,
business_process
):
# XXX-JPS WEIRD
if
self
.
_trade_phase_list
:
return
self
.
_trade_phase_list
if
self
.
_rule
is
not
None
:
trade_phase_list
=
self
.
_rule
.
getTradePhaseList
()
if
trade_phase_list
:
return
trade_phase_list
return
input_movement
.
getTradePhaseList
()
or
\
business_process
.
getTradePhaseList
()
def
_getInputMovementList
(
self
,
movement_list
=
None
,
rounding
=
None
):
#XXX-JPS should it be amount or movement ?
raise
NotImplementedError
# Default implementation takes amounts ?
# Use TradeModelRuleMovementGenerator._getInputMovementList as default implementation
# and potentially use trade phase for that.... as a way to filter out
class
RuleMixin
(
Predicate
):
"""
Provides generic methods and helper methods to implement
...
...
@@ -378,3 +479,142 @@ class RuleMixin(Predicate):
movement_collection_diff
.
addNewMovement
(
new_movement
)
InitializeClass
(
RuleMixin
)
class
SimulableMixin
(
Base
):
security
=
ClassSecurityInfo
()
def
updateSimulation
(
self
,
**
kw
):
"""Create/update related simulation trees by activity
This method is used to maintain related objects in simulation trees:
- hiding complexity of activity dependencies
- avoiding duplicate work
Repeated calls of this method for the same delivery will result in a single
call to _updateSimulation. Grouping may happen at the end of the transaction
or by the grouping method.
See _updateSimulation for accepted parameters.
"""
tv
=
getTransactionalVariable
()
key
=
'SimulableMixin.updateSimulation'
,
self
.
getUid
()
item_list
=
kw
.
items
()
try
:
kw
,
ignore
=
tv
[
key
]
kw
.
update
(
item_list
)
except
KeyError
:
ignore_key
=
key
+
(
'ignore'
,)
ignore
=
tv
.
pop
(
ignore_key
,
set
())
tv
[
key
]
=
kw
,
ignore
def
before_commit
():
if
kw
:
path
=
self
.
getPath
()
if
aq_base
(
self
.
unrestrictedTraverse
(
path
,
None
))
is
aq_base
(
self
):
self
.
activate
(
activity
=
'SQLQueue'
,
group_method_id
=
'portal_rules/updateSimulation'
,
tag
=
'build:'
+
path
,
priority
=
3
,
).
_updateSimulation
(
**
kw
)
del
tv
[
key
]
ignore
.
update
(
kw
)
tv
[
ignore_key
]
=
ignore
transaction
.
get
().
addBeforeCommitHook
(
before_commit
)
for
k
,
v
in
item_list
:
if
not
v
:
ignore
.
add
(
k
)
elif
k
not
in
ignore
:
continue
del
kw
[
k
]
def
_updateSimulation
(
self
,
create_root
=
0
,
expand_root
=
0
,
expand_related
=
0
,
index_related
=
0
):
"""
Depending on set parameters, this method will:
create_root -- if a root applied rule is missing, create and expand it
expand_root -- expand related root applied rule,
create it before if missing
expand_related -- expand related simulation movements
index_related -- reindex related simulation movements (recursively)
"""
if
create_root
or
expand_root
:
applied_rule
=
self
.
_getRootAppliedRule
()
if
applied_rule
is
None
:
applied_rule
=
self
.
_createRootAppliedRule
()
expand_root
=
applied_rule
is
not
None
activate_kw
=
{
'tag'
:
'build:'
+
self
.
getPath
()}
if
expand_root
:
applied_rule
.
expand
(
activate_kw
=
activate_kw
)
else
:
applied_rule
=
None
if
expand_related
:
for
movement
in
self
.
_getAllRelatedSimulationMovementList
():
movement
=
movement
.
getObject
()
if
not
movement
.
aq_inContextOf
(
applied_rule
):
# XXX: make sure this will also reindex of all sub-objects recursively
movement
.
expand
(
activate_kw
=
activate_kw
)
elif
index_related
:
for
movement
in
self
.
_getAllRelatedSimulationMovementList
():
movement
=
movement
.
getObject
()
if
not
movement
.
aq_inContextOf
(
applied_rule
):
movement
.
recursiveReindexObject
(
activate_kw
=
activate_kw
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getRuleReference'
)
def
getRuleReference
(
self
):
"""Returns an appropriate rule reference
XXX: Using reference to select a rule (for a root applied rule) is wrong
and should be replaced by predicate and workflow state.
"""
method
=
self
.
_getTypeBasedMethod
(
'getRuleReference'
)
if
method
is
None
:
raise
SimulationError
(
"Missing type-based 'getRuleReference' script for "
+
repr
(
self
))
return
method
()
def
_getRootAppliedRule
(
self
):
"""Get related root applied rule if it exists"""
applied_rule_list
=
self
.
getCausalityRelatedValueList
(
portal_type
=
'Applied Rule'
)
if
len
(
applied_rule_list
)
==
1
:
return
applied_rule_list
[
0
]
elif
applied_rule_list
:
raise
SimulationError
(
'%r has more than one applied rule.'
%
self
)
def
_createRootAppliedRule
(
self
):
"""Create a root applied rule"""
# XXX: Consider moving this first test to Delivery
if
self
.
isSimulated
():
# No need to have a root applied rule
# if we are already in the simulation process
return
rule_reference
=
self
.
getRuleReference
()
if
rule_reference
:
portal
=
self
.
getPortalObject
()
rule_list
=
portal
.
portal_catalog
.
unrestrictedSearchResults
(
portal_type
=
portal
.
getPortalRuleTypeList
(),
validation_state
=
"validated"
,
reference
=
rule_reference
,
sort_on
=
'version'
,
sort_order
=
'descending'
)
if
rule_list
:
applied_rule
=
rule_list
[
0
].
constructNewAppliedRule
(
portal
.
portal_simulation
,
is_indexable
=
False
)
applied_rule
.
_setCausalityValue
(
self
)
del
applied_rule
.
isIndexable
# To prevent duplicate root Applied Rule, we reindex immediately and
# lock ZODB, and we rely on the fact that ZODB is committed after
# catalog. This way, we guarantee the catalog is up-to-date as soon as
# ZODB is unlocked.
applied_rule
.
immediateReindexObject
()
self
.
serialize
()
# prevent duplicate root Applied Rule
return
applied_rule
raise
SimulationError
(
"No such rule as %r is found"
%
rule_reference
)
security
.
declarePrivate
(
'manage_beforeDelete'
)
def
manage_beforeDelete
(
self
,
item
,
container
):
"""Delete related Applied Rule"""
for
o
in
self
.
getCausalityRelatedValueList
(
portal_type
=
'Applied Rule'
):
o
.
getParentValue
().
deleteContent
(
o
.
getId
())
super
(
SimulableMixin
,
self
).
manage_beforeDelete
(
item
,
container
)
InitializeClass
(
SimulableMixin
)
product/ERP5/mixin/simulable.py
deleted
100644 → 0
View file @
0cec7b82
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
import
transaction
from
Acquisition
import
aq_base
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type.Base
import
Base
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.Errors
import
SimulationError
class
SimulableMixin
(
Base
):
security
=
ClassSecurityInfo
()
def
updateSimulation
(
self
,
**
kw
):
"""Create/update related simulation trees by activity
This method is used to maintain related objects in simulation trees:
- hiding complexity of activity dependencies
- avoiding duplicate work
Repeated calls of this method for the same delivery will result in a single
call to _updateSimulation. Grouping may happen at the end of the transaction
or by the grouping method.
See _updateSimulation for accepted parameters.
"""
tv
=
getTransactionalVariable
()
key
=
'SimulableMixin.updateSimulation'
,
self
.
getUid
()
item_list
=
kw
.
items
()
try
:
kw
,
ignore
=
tv
[
key
]
kw
.
update
(
item_list
)
except
KeyError
:
ignore_key
=
key
+
(
'ignore'
,)
ignore
=
tv
.
pop
(
ignore_key
,
set
())
tv
[
key
]
=
kw
,
ignore
def
before_commit
():
if
kw
:
path
=
self
.
getPath
()
if
aq_base
(
self
.
unrestrictedTraverse
(
path
,
None
))
is
aq_base
(
self
):
self
.
activate
(
activity
=
'SQLQueue'
,
group_method_id
=
'portal_rules/updateSimulation'
,
tag
=
'build:'
+
path
,
priority
=
3
,
).
_updateSimulation
(
**
kw
)
del
tv
[
key
]
ignore
.
update
(
kw
)
tv
[
ignore_key
]
=
ignore
transaction
.
get
().
addBeforeCommitHook
(
before_commit
)
for
k
,
v
in
item_list
:
if
not
v
:
ignore
.
add
(
k
)
elif
k
not
in
ignore
:
continue
del
kw
[
k
]
def
_updateSimulation
(
self
,
create_root
=
0
,
expand_root
=
0
,
expand_related
=
0
,
index_related
=
0
):
"""
Depending on set parameters, this method will:
create_root -- if a root applied rule is missing, create and expand it
expand_root -- expand related root applied rule,
create it before if missing
expand_related -- expand related simulation movements
index_related -- reindex related simulation movements (recursively)
"""
if
create_root
or
expand_root
:
applied_rule
=
self
.
_getRootAppliedRule
()
if
applied_rule
is
None
:
applied_rule
=
self
.
_createRootAppliedRule
()
expand_root
=
applied_rule
is
not
None
activate_kw
=
{
'tag'
:
'build:'
+
self
.
getPath
()}
if
expand_root
:
applied_rule
.
expand
(
activate_kw
=
activate_kw
)
else
:
applied_rule
=
None
if
expand_related
:
for
movement
in
self
.
_getAllRelatedSimulationMovementList
():
movement
=
movement
.
getObject
()
if
not
movement
.
aq_inContextOf
(
applied_rule
):
# XXX: make sure this will also reindex of all sub-objects recursively
movement
.
expand
(
activate_kw
=
activate_kw
)
elif
index_related
:
for
movement
in
self
.
_getAllRelatedSimulationMovementList
():
movement
=
movement
.
getObject
()
if
not
movement
.
aq_inContextOf
(
applied_rule
):
movement
.
recursiveReindexObject
(
activate_kw
=
activate_kw
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getRuleReference'
)
def
getRuleReference
(
self
):
"""Returns an appropriate rule reference
XXX: Using reference to select a rule (for a root applied rule) is wrong
and should be replaced by predicate and workflow state.
"""
method
=
self
.
_getTypeBasedMethod
(
'getRuleReference'
)
if
method
is
None
:
raise
SimulationError
(
"Missing type-based 'getRuleReference' script for "
+
repr
(
self
))
return
method
()
def
_getRootAppliedRule
(
self
):
"""Get related root applied rule if it exists"""
applied_rule_list
=
self
.
getCausalityRelatedValueList
(
portal_type
=
'Applied Rule'
)
if
len
(
applied_rule_list
)
==
1
:
return
applied_rule_list
[
0
]
elif
applied_rule_list
:
raise
SimulationError
(
'%r has more than one applied rule.'
%
self
)
def
_createRootAppliedRule
(
self
):
"""Create a root applied rule"""
# XXX: Consider moving this first test to Delivery
if
self
.
isSimulated
():
# No need to have a root applied rule
# if we are already in the simulation process
return
rule_reference
=
self
.
getRuleReference
()
if
rule_reference
:
portal
=
self
.
getPortalObject
()
rule_list
=
portal
.
portal_catalog
.
unrestrictedSearchResults
(
portal_type
=
portal
.
getPortalRuleTypeList
(),
validation_state
=
"validated"
,
reference
=
rule_reference
,
sort_on
=
'version'
,
sort_order
=
'descending'
)
if
rule_list
:
applied_rule
=
rule_list
[
0
].
constructNewAppliedRule
(
portal
.
portal_simulation
,
is_indexable
=
False
)
applied_rule
.
_setCausalityValue
(
self
)
del
applied_rule
.
isIndexable
# To prevent duplicate root Applied Rule, we reindex immediately and
# lock ZODB, and we rely on the fact that ZODB is committed after
# catalog. This way, we guarantee the catalog is up-to-date as soon as
# ZODB is unlocked.
applied_rule
.
immediateReindexObject
()
self
.
serialize
()
# prevent duplicate root Applied Rule
return
applied_rule
raise
SimulationError
(
"No such rule as %r is found"
%
rule_reference
)
security
.
declarePrivate
(
'manage_beforeDelete'
)
def
manage_beforeDelete
(
self
,
item
,
container
):
"""Delete related Applied Rule"""
for
o
in
self
.
getCausalityRelatedValueList
(
portal_type
=
'Applied Rule'
):
o
.
getParentValue
().
deleteContent
(
o
.
getId
())
super
(
SimulableMixin
,
self
).
manage_beforeDelete
(
item
,
container
)
InitializeClass
(
SimulableMixin
)
product/ERP5/mixin/solver.py
View file @
8080c57b
...
...
@@ -30,8 +30,10 @@
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type
import
Permissions
,
interfaces
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.UnrestrictedMethod
import
super_user
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5.mixin.configurable
import
ConfigurableMixin
class
SolverMixin
(
object
):
"""
...
...
@@ -71,3 +73,53 @@ class SolverMixin(object):
return
solver_list
InitializeClass
(
SolverMixin
)
class
ConfigurablePropertySolverMixin
(
SolverMixin
,
ConfigurableMixin
,
XMLObject
):
"""
Base class for Target Solvers that can be applied to many
solver-decisions of a solver process, and need to accumulate the
tested_property_list configuration among all solver-decisions
"""
add_permission
=
Permissions
.
AddPortalContent
isIndexable
=
0
# We do not want to fill the catalog with objects on which we need no reporting
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
zope
.
interface
.
implements
(
interfaces
.
ISolver
,
interfaces
.
IConfigurable
,)
# Default Properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
TargetSolver
)
def
updateConfiguration
(
self
,
**
kw
):
# This method is called once for each 'Solver Decision' of a
# 'Solver Process' that maps into this solver for the same
# Simulation Movement, so we need to take care not to lose
# information by overwriting.
configuration
=
self
.
_getConfigurationPropertyDict
()
tested_property_list
=
configuration
.
get
(
'tested_property_list'
)
if
tested_property_list
is
not
None
:
tested_property_set
=
set
(
tested_property_list
)
tested_property_set
.
update
(
kw
.
get
(
'tested_property_list'
,
()))
kw
[
'tested_property_list'
]
=
list
(
tested_property_set
)
super
(
ConfigurablePropertySolverMixin
,
self
).
updateConfiguration
(
**
kw
)
def
getTestedPropertyList
(
self
):
configuration_dict
=
self
.
getConfigurationPropertyDict
()
tested_property_list
=
configuration_dict
.
get
(
'tested_property_list'
)
if
tested_property_list
is
None
:
portal_type
=
self
.
getPortalObject
().
portal_types
.
getTypeInfo
(
self
)
tested_property_list
=
portal_type
.
getTestedPropertyList
()
return
tested_property_list
InitializeClass
(
ConfigurablePropertySolverMixin
)
product/ERP5Configurator/Document/SecurityCategoryMappingConfiguratorItem.py
View file @
8080c57b
...
...
@@ -30,7 +30,7 @@ import zope.interface
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Configurator.mixin.
skin_
configurator_item
import
\
from
Products.ERP5Configurator.mixin.configurator_item
import
\
SkinConfiguratorItemMixin
class
SecurityCategoryMappingConfiguratorItem
(
SkinConfiguratorItemMixin
,
...
...
product/ERP5Configurator/mixin/configurator_item.py
View file @
8080c57b
...
...
@@ -29,7 +29,9 @@
##############################################################################
from
Products.ERP5Type.ConsistencyMessage
import
ConsistencyMessage
from
Products.ERP5Type.Base
import
Base
from
zLOG
import
LOG
,
INFO
import
time
class
ConfiguratorItemMixin
:
""" This is the base class for all configurator item. """
...
...
@@ -62,3 +64,53 @@ class ConfiguratorItemMixin:
current_template_path_list
=
list
(
bt5_obj
.
getTemplatePathList
())
current_template_path_list
.
extend
(
template_path_list
)
bt5_obj
.
edit
(
template_path_list
=
current_template_path_list
)
class
SkinConfiguratorItemMixin
(
ConfiguratorItemMixin
):
""" Mixin which allows to create python scripts and/or skin
elements during the configuration.
"""
def
install
(
self
,
skinfolder
,
business_configuration
):
"""
"""
bt5_obj
=
business_configuration
.
getSpecialiseValue
()
if
bt5_obj
is
None
:
LOG
(
'ConfiguratorItem'
,
INFO
,
'Unable to find related business template to %s'
%
\
business_configuration
.
getRelativeUrl
())
return
template_skin_id_list
=
list
(
bt5_obj
.
getTemplateSkinIdList
())
if
skinfolder
.
getId
()
not
in
template_skin_id_list
:
template_skin_id_list
.
append
(
skinfolder
.
getId
())
bt5_obj
.
edit
(
template_skin_id_list
=
template_skin_id_list
)
def
_createSkinFolder
(
self
,
folder_id
=
"custom"
):
""" Creates a new skin folder id if it do not exists and
update Skin information """
folder
=
getattr
(
self
.
portal_skins
,
folder_id
,
None
)
if
folder
is
not
None
:
return
folder
folder
=
self
.
portal_skins
.
manage_addProduct
[
'OFSP'
].
manage_addFolder
(
folder_id
)
# Register on all skin selections.
raise
NotImplementedError
def
_createZODBPythonScript
(
self
,
container
,
script_id
,
script_params
,
script_content
):
"""Creates a Python script `script_id` in the given `container`, with
`script_params` and `script_content`.
If the container already contains an object with id `script_id`, this
object is removed first.
"""
if
script_id
in
container
.
objectIds
():
container
.
manage_delObjects
([
script_id
])
container
.
manage_addProduct
[
'PythonScripts'
]
\
.
manage_addPythonScript
(
id
=
script_id
)
script
=
container
.
_getOb
(
script_id
)
script
.
ZPythonScript_edit
(
script_params
,
script_content
)
container
.
portal_url
.
getPortalObject
().
changeSkin
(
None
)
return
script
product/ERP5Configurator/mixin/skin_configurator_item.py
deleted
100644 → 0
View file @
0cec7b82
##############################################################################
#
# Copyright (c) 2006-2012 Nexedi SARL and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com>
# Ivan Tyagov <ivan@nexedi.com>
# Rafael Monnerat <rafael@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
zLOG
import
LOG
,
INFO
from
Products.ERP5Configurator.mixin.configurator_item
import
ConfiguratorItemMixin
class
SkinConfiguratorItemMixin
(
ConfiguratorItemMixin
):
""" Mixin which allows to create python scripts and/or skin
elements during the configuration.
"""
def
install
(
self
,
skinfolder
,
business_configuration
):
"""
"""
bt5_obj
=
business_configuration
.
getSpecialiseValue
()
if
bt5_obj
is
None
:
LOG
(
'ConfiguratorItem'
,
INFO
,
'Unable to find related business template to %s'
%
\
business_configuration
.
getRelativeUrl
())
return
template_skin_id_list
=
list
(
bt5_obj
.
getTemplateSkinIdList
())
if
skinfolder
.
getId
()
not
in
template_skin_id_list
:
template_skin_id_list
.
append
(
skinfolder
.
getId
())
bt5_obj
.
edit
(
template_skin_id_list
=
template_skin_id_list
)
def
_createSkinFolder
(
self
,
folder_id
=
"custom"
):
""" Creates a new skin folder id if it do not exists and
update Skin information """
folder
=
getattr
(
self
.
portal_skins
,
folder_id
,
None
)
if
folder
is
not
None
:
return
folder
folder
=
self
.
portal_skins
.
manage_addProduct
[
'OFSP'
].
manage_addFolder
(
folder_id
)
# Register on all skin selections.
raise
NotImplementedError
def
_createZODBPythonScript
(
self
,
container
,
script_id
,
script_params
,
script_content
):
"""Creates a Python script `script_id` in the given `container`, with
`script_params` and `script_content`.
If the container already contains an object with id `script_id`, this
object is removed first.
"""
if
script_id
in
container
.
objectIds
():
container
.
manage_delObjects
([
script_id
])
container
.
manage_addProduct
[
'PythonScripts'
]
\
.
manage_addPythonScript
(
id
=
script_id
)
script
=
container
.
_getOb
(
script_id
)
script
.
ZPythonScript_edit
(
script_params
,
script_content
)
container
.
portal_url
.
getPortalObject
().
changeSkin
(
None
)
return
script
product/ERP5OOo/Document/OOoDocument.py
View file @
8080c57b
...
...
@@ -43,7 +43,7 @@ from Products.ERP5Type.Utils import fill_args_from_request
# Mixin Import
from
Products.ERP5.mixin.base_convertable
import
BaseConvertableFileMixin
from
Products.ERP5.mixin.text_convertable
import
TextConvertableMixin
from
Products.ERP5.mixin.
ooo_document_
extensible_traversable
import
OOoDocumentExtensibleTraversableMixin
from
Products.ERP5.mixin.extensible_traversable
import
OOoDocumentExtensibleTraversableMixin
EMBEDDED_FORMAT
=
'_embedded'
...
...
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