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
Ekaterina
erp5
Commits
96bbfad2
Commit
96bbfad2
authored
Jun 29, 2020
by
Arnaud Fontaine
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ZODB Components: More Documents to migrate from Products.ERP5.Document.
parent
1266c706
Changes
50
Show whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1717 additions
and
525 deletions
+1717
-525
bt5/erp5_accounting/DocumentTemplateItem/portal_components/document.erp5.AccountingTransactionLine.py
...tal_components/document.erp5.AccountingTransactionLine.py
+1
-1
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Assignment.py
...emplateItem/portal_components/document.erp5.Assignment.py
+1
-1
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Career.py
...entTemplateItem/portal_components/document.erp5.Career.py
+1
-1
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Supply.py
...entTemplateItem/portal_components/document.erp5.Supply.py
+1
-1
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.SupplyCell.py
...emplateItem/portal_components/document.erp5.SupplyCell.py
+1
-1
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.SupplyLine.py
...emplateItem/portal_components/document.erp5.SupplyLine.py
+2
-2
bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py
...TemplateItem/portal_components/mixin.erp5.BuilderMixin.py
+1
-1
bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.ConfigurationSave.py
...Item/portal_components/document.erp5.ConfigurationSave.py
+1
-1
bt5/erp5_interface_post/DocumentTemplateItem/portal_components/document.erp5.InternetMessagePost.py
...em/portal_components/document.erp5.InternetMessagePost.py
+1
-1
bt5/erp5_invoicing/DocumentTemplateItem/portal_components/document.erp5.InvoiceTransactionSimulationRule.py
...ponents/document.erp5.InvoiceTransactionSimulationRule.py
+1
-1
bt5/erp5_open_trade_periodicity_line/DocumentTemplateItem/portal_components/document.erp5.PeriodicityLine.py
...teItem/portal_components/document.erp5.PeriodicityLine.py
+1
-1
bt5/erp5_pdm/DocumentTemplateItem/portal_components/document.erp5.Transformation.py
...ateItem/portal_components/document.erp5.Transformation.py
+2
-2
bt5/erp5_software_pdm/DocumentTemplateItem/portal_components/document.erp5.SoftwareLicence.py
...teItem/portal_components/document.erp5.SoftwareLicence.py
+1
-1
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.BusinessLink.py
...plateItem/portal_components/document.erp5.BusinessLink.py
+1
-1
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.BusinessProcess.py
...teItem/portal_components/document.erp5.BusinessProcess.py
+1
-1
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.TradeCondition.py
...ateItem/portal_components/document.erp5.TradeCondition.py
+1
-1
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.TradeModelPath.py
...ateItem/portal_components/document.erp5.TradeModelPath.py
+1
-1
product/ERP5/Document/TextDocument.py
product/ERP5/Document/TextDocument.py
+0
-432
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Amount.py
...entTemplateItem/portal_components/document.erp5.Amount.py
+7
-7
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Amount.xml
...ntTemplateItem/portal_components/document.erp5.Amount.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.AmountGeneratorLine.py
...em/portal_components/document.erp5.AmountGeneratorLine.py
+2
-2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.BaseDomain.py
...emplateItem/portal_components/document.erp5.BaseDomain.py
+0
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.BaseDomain.xml
...mplateItem/portal_components/document.erp5.BaseDomain.xml
+104
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.ContributionPredicate.py
.../portal_components/document.erp5.ContributionPredicate.py
+8
-8
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.ContributionPredicate.xml
...portal_components/document.erp5.ContributionPredicate.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.DeliveryCell.py
...plateItem/portal_components/document.erp5.DeliveryCell.py
+1
-1
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.DomainGenerator.py
...teItem/portal_components/document.erp5.DomainGenerator.py
+29
-29
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.DomainGenerator.xml
...eItem/portal_components/document.erp5.DomainGenerator.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.EmailDocument.py
...lateItem/portal_components/document.erp5.EmailDocument.py
+2
-2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.ImmobilisableItem.py
...Item/portal_components/document.erp5.ImmobilisableItem.py
+1
-1
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Item.py
...umentTemplateItem/portal_components/document.erp5.Item.py
+1
-1
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.MappedValue.py
...mplateItem/portal_components/document.erp5.MappedValue.py
+1
-2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.MappedValue.xml
...plateItem/portal_components/document.erp5.MappedValue.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Movement.py
...tTemplateItem/portal_components/document.erp5.Movement.py
+1
-1
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Path.py
...umentTemplateItem/portal_components/document.erp5.Path.py
+2
-2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Path.xml
...mentTemplateItem/portal_components/document.erp5.Path.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateGroup.py
...ateItem/portal_components/document.erp5.PredicateGroup.py
+0
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateGroup.xml
...teItem/portal_components/document.erp5.PredicateGroup.xml
+104
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateMatrix.py
...teItem/portal_components/document.erp5.PredicateMatrix.py
+2
-2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateMatrix.xml
...eItem/portal_components/document.erp5.PredicateMatrix.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.TextDocument.py
...plateItem/portal_components/document.erp5.TextDocument.py
+418
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.TextDocument.xml
...lateItem/portal_components/document.erp5.TextDocument.xml
+110
-0
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Transition.py
...emplateItem/portal_components/document.erp5.Transition.py
+5
-5
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Transition.xml
...mplateItem/portal_components/document.erp5.Transition.xml
+110
-0
product/ERP5/bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.AmountGeneratorMixin.py
...Item/portal_components/mixin.erp5.AmountGeneratorMixin.py
+1
-1
product/ERP5/bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.MailMessageMixin.py
...lateItem/portal_components/mixin.erp5.MailMessageMixin.py
+6
-8
product/ERP5/bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.MailMessageMixin.xml
...ateItem/portal_components/mixin.erp5.MailMessageMixin.xml
+110
-0
product/ERP5/bootstrap/erp5_core/bt/template_document_id_list
...uct/ERP5/bootstrap/erp5_core/bt/template_document_id_list
+11
-1
product/ERP5/bootstrap/erp5_core/bt/template_mixin_id_list
product/ERP5/bootstrap/erp5_core/bt/template_mixin_id_list
+1
-0
product/ERP5/tests/testERP5Interfaces.py
product/ERP5/tests/testERP5Interfaces.py
+1
-1
No files found.
bt5/erp5_accounting/DocumentTemplateItem/portal_components/document.erp5.AccountingTransactionLine.py
View file @
96bbfad2
...
@@ -30,7 +30,7 @@ from AccessControl import ClassSecurityInfo
...
@@ -30,7 +30,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
erp5.component.document.DeliveryLine
import
DeliveryLine
from
erp5.component.document.DeliveryLine
import
DeliveryLine
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
class
AccountingTransactionLine
(
DeliveryLine
):
class
AccountingTransactionLine
(
DeliveryLine
):
...
...
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Assignment.py
View file @
96bbfad2
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
class
Assignment
(
Path
):
class
Assignment
(
Path
):
...
...
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Career.py
View file @
96bbfad2
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
class
Career
(
Path
):
class
Career
(
Path
):
"""
"""
...
...
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.Supply.py
View file @
96bbfad2
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
class
Supply
(
Path
,
XMLObject
):
class
Supply
(
Path
,
XMLObject
):
"""A Supply defines precise pricing and shipping conditions between
"""A Supply defines precise pricing and shipping conditions between
...
...
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.SupplyCell.py
View file @
96bbfad2
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
class
SupplyCell
(
Path
):
class
SupplyCell
(
Path
):
"""A Supply Cell is used for different variations in a supply line.
"""A Supply Cell is used for different variations in a supply line.
...
...
bt5/erp5_base/DocumentTemplateItem/portal_components/document.erp5.SupplyLine.py
View file @
96bbfad2
...
@@ -32,8 +32,8 @@ from AccessControl import ClassSecurityInfo
...
@@ -32,8 +32,8 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.Accessor.Constant
import
PropertyGetter
as
ConstantGetter
from
Products.ERP5Type.Accessor.Constant
import
PropertyGetter
as
ConstantGetter
from
Products.ERP5Type.XMLMatrix
import
XMLMatrix
from
Products.ERP5Type.XMLMatrix
import
XMLMatrix
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
from
Products.ERP5Type.Utils
import
convertToUpperCase
from
Products.ERP5Type.Utils
import
convertToUpperCase
...
...
bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py
View file @
96bbfad2
...
@@ -32,7 +32,7 @@ from Products.ERP5Type.Globals import InitializeClass
...
@@ -32,7 +32,7 @@ from Products.ERP5Type.Globals import InitializeClass
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
erp5.component.module.MovementGroup
import
MovementGroupNode
from
erp5.component.module.MovementGroup
import
MovementGroupNode
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
from
Products.ERP5Type.UnrestrictedMethod
import
UnrestrictedMethod
...
...
bt5/erp5_configurator/DocumentTemplateItem/portal_components/document.erp5.ConfigurationSave.py
View file @
96bbfad2
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
class
ConfigurationSave
(
Path
):
class
ConfigurationSave
(
Path
):
""" This class is the base class for all template items. """
""" This class is the base class for all template items. """
...
...
bt5/erp5_interface_post/DocumentTemplateItem/portal_components/document.erp5.InternetMessagePost.py
View file @
96bbfad2
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type
import
Permissions
from
erp5.component.document.Item
import
Item
from
erp5.component.document.Item
import
Item
from
Products.ERP5.mixin.mail_message
import
MailMessageMixin
from
erp5.component.mixin.MailMessageMixin
import
MailMessageMixin
import
email
import
email
...
...
bt5/erp5_invoicing/DocumentTemplateItem/portal_components/document.erp5.InvoiceTransactionSimulationRule.py
View file @
96bbfad2
...
@@ -33,7 +33,7 @@ from erp5.component.mixin.RuleMixin import RuleMixin
...
@@ -33,7 +33,7 @@ from erp5.component.mixin.RuleMixin import RuleMixin
from
erp5.component.mixin.MovementGeneratorMixin
import
MovementGeneratorMixin
from
erp5.component.mixin.MovementGeneratorMixin
import
MovementGeneratorMixin
from
erp5.component.mixin.MovementCollectionUpdaterMixin
import
\
from
erp5.component.mixin.MovementCollectionUpdaterMixin
import
\
MovementCollectionUpdaterMixin
MovementCollectionUpdaterMixin
from
Products.ERP5.D
ocument.PredicateMatrix
import
PredicateMatrix
from
erp5.component.d
ocument.PredicateMatrix
import
PredicateMatrix
from
erp5.component.interface.IRule
import
IRule
from
erp5.component.interface.IRule
import
IRule
from
erp5.component.interface.IDivergenceController
import
IDivergenceController
from
erp5.component.interface.IDivergenceController
import
IDivergenceController
from
erp5.component.interface.IMovementCollectionUpdater
import
IMovementCollectionUpdater
from
erp5.component.interface.IMovementCollectionUpdater
import
IMovementCollectionUpdater
...
...
bt5/erp5_open_trade_periodicity_line/DocumentTemplateItem/portal_components/document.erp5.PeriodicityLine.py
View file @
96bbfad2
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
from
Products.ERP5.mixin.periodicity
import
PeriodicityMixin
from
Products.ERP5.mixin.periodicity
import
PeriodicityMixin
class
PeriodicityLineMixin
(
PeriodicityMixin
):
class
PeriodicityLineMixin
(
PeriodicityMixin
):
...
...
bt5/erp5_pdm/DocumentTemplateItem/portal_components/document.erp5.Transformation.py
View file @
96bbfad2
...
@@ -35,8 +35,8 @@ from AccessControl import ClassSecurityInfo
...
@@ -35,8 +35,8 @@ from AccessControl import ClassSecurityInfo
from
Products.CMFCategory.Renderer
import
Renderer
from
Products.CMFCategory.Renderer
import
Renderer
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
Products.ERP5.mixin.variated
import
VariatedMixin
from
Products.ERP5.mixin.variated
import
VariatedMixin
...
...
bt5/erp5_software_pdm/DocumentTemplateItem/portal_components/document.erp5.SoftwareLicence.py
View file @
96bbfad2
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
erp5.component.document.Item
import
Item
from
erp5.component.document.Item
import
Item
from
Products.ERP5.D
ocument.TextDocument
import
TextDocument
from
erp5.component.d
ocument.TextDocument
import
TextDocument
class
SoftwareLicence
(
TextDocument
,
Item
):
class
SoftwareLicence
(
TextDocument
,
Item
):
"""
"""
...
...
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.BusinessLink.py
View file @
96bbfad2
...
@@ -32,7 +32,7 @@
...
@@ -32,7 +32,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
from
erp5.component.interface.IBusinessLink
import
IBusinessLink
from
erp5.component.interface.IBusinessLink
import
IBusinessLink
...
...
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.BusinessProcess.py
View file @
96bbfad2
...
@@ -33,7 +33,7 @@ from AccessControl import ClassSecurityInfo
...
@@ -33,7 +33,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
,
_getBusinessLinkClosure
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
,
_getBusinessLinkClosure
from
erp5.component.module.MovementCollectionDiff
import
_getPropertyAndCategoryList
from
erp5.component.module.MovementCollectionDiff
import
_getPropertyAndCategoryList
from
erp5.component.interface.IBusinessProcess
import
IBusinessProcess
from
erp5.component.interface.IBusinessProcess
import
IBusinessProcess
...
...
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.TradeCondition.py
View file @
96bbfad2
...
@@ -37,7 +37,7 @@ from AccessControl import ClassSecurityInfo
...
@@ -37,7 +37,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.mixin.composition
import
_getEffectiveModel
from
Products.ERP5.mixin.composition
import
_getEffectiveModel
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
Products.ERP5.mixin.variated
import
VariatedMixin
from
Products.ERP5.mixin.variated
import
VariatedMixin
from
erp5.component.interface.IMovementCollectionUpdater
import
IMovementCollectionUpdater
from
erp5.component.interface.IMovementCollectionUpdater
import
IMovementCollectionUpdater
...
...
bt5/erp5_trade/DocumentTemplateItem/portal_components/document.erp5.TradeModelPath.py
View file @
96bbfad2
...
@@ -32,7 +32,7 @@
...
@@ -32,7 +32,7 @@
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5.D
ocument.Path
import
Path
from
erp5.component.d
ocument.Path
import
Path
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
from
Products.ERP5.ExplanationCache
import
_getExplanationCache
from
erp5.component.interface.ITradeModelPath
import
ITradeModelPath
from
erp5.component.interface.ITradeModelPath
import
ITradeModelPath
...
...
product/ERP5/Document/TextDocument.py
deleted
100644 → 0
View file @
1266c706
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL 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 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.ZopeGuards
import
guarded_getattr
from
AccessControl
import
ClassSecurityInfo
from
zLOG
import
LOG
,
WARNING
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.Document.Document
import
Document
,
ConversionError
,
_MARKER
,
DEFAULT_CONTENT_TYPE
from
Products.ERP5.Document.File
import
File
from
Products.ERP5Type.WebDAVSupport
import
TextContent
import
re
from
Products.ERP5.Document.Document
import
VALID_IMAGE_FORMAT_LIST
,
VALID_TEXT_FORMAT_LIST
import
cStringIO
from
string
import
Template
# Mixin Import
from
Products.ERP5.mixin.cached_convertable
import
CachedConvertableMixin
from
Products.ERP5.mixin.base_convertable
import
BaseConvertableFileMixin
from
Products.ERP5Type.mixin.text_content_history
import
TextContentHistoryMixin
from
Products.ERP5Type.Utils
import
guessEncodingFromText
from
lxml
import
html
as
etree_html
from
lxml
import
etree
from
Products.ERP5Type.ImageUtil
import
transformUrlToDataURI
class
TextDocument
(
CachedConvertableMixin
,
BaseConvertableFileMixin
,
TextContentHistoryMixin
,
TextContent
,
File
):
"""A TextDocument impletents IDocument, IFile, IBaseConvertable, ICachedconvertable
and ITextConvertable
"""
meta_type
=
'ERP5 Text Document'
portal_type
=
'Text Document'
add_permission
=
Permissions
.
AddPortalContent
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# Declarative properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
Version
,
PropertySheet
.
Document
,
PropertySheet
.
ExternalDocument
,
PropertySheet
.
Url
,
PropertySheet
.
TextDocument
,
PropertySheet
.
Data
,
PropertySheet
.
Reference
)
def
_substituteTextContent
(
self
,
text
,
safe_substitute
=
True
,
**
kw
):
# If a method for string substitutions of the text content, perform it.
# Decode everything into unicode before the substitutions, in order to
# avoid encoding errors.
method_id
=
self
.
getTextContentSubstitutionMappingMethodId
()
if
method_id
:
try
:
method
=
guarded_getattr
(
self
,
method_id
)
except
AttributeError
:
LOG
(
'TextDocument'
,
WARNING
,
'could not get the substitution'
' mapping method %s from %r, so the content will not be'
' substituted.'
%
(
method_id
,
self
.
getRelativeUrl
()))
return
text
mapping
=
method
(
**
kw
)
is_str
=
isinstance
(
text
,
str
)
if
is_str
:
text
=
text
.
decode
(
'utf-8'
)
class
UnicodeMapping
:
def
__getitem__
(
self
,
item
):
v
=
mapping
[
item
]
if
isinstance
(
v
,
str
):
v
=
v
.
decode
(
'utf-8'
)
elif
not
isinstance
(
v
,
unicode
):
v
=
str
(
v
).
decode
(
'utf-8'
)
return
v
unicode_mapping
=
UnicodeMapping
()
if
safe_substitute
:
text
=
Template
(
text
).
safe_substitute
(
unicode_mapping
)
else
:
text
=
Template
(
text
).
substitute
(
unicode_mapping
)
# If the original was a str, convert it back to str.
if
is_str
:
text
=
text
.
encode
(
'utf-8'
)
return
text
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'asSubjectText'
)
def
asSubjectText
(
self
,
substitution_method_parameter_dict
=
None
,
safe_substitute
=
True
,
**
kw
):
"""
Converts the subject of the document to a textual representation.
"""
subject
=
TextDocument
.
inheritedAttribute
(
'asSubjectText'
)(
self
,
**
kw
)
if
substitution_method_parameter_dict
is
None
:
substitution_method_parameter_dict
=
{}
return
self
.
_substituteTextContent
(
subject
,
safe_substitute
=
safe_substitute
,
**
substitution_method_parameter_dict
)
def
_convert
(
self
,
format
,
substitution_method_parameter_dict
=
None
,
safe_substitute
=
True
,
charset
=
None
,
text_content
=
None
,
substitute
=
True
,
**
kw
):
"""
Convert text using portal_transforms or oood
"""
# XXX 'or DEFAULT_CONTENT_TYPE' is compaptibility code used for old
# web_page that have neither content_type nor text_format. Migration
# should be done to make all web page having content_type property
src_mimetype
=
self
.
getContentType
()
or
DEFAULT_CONTENT_TYPE
if
not
format
and
src_mimetype
==
'text/html'
:
format
=
'html'
# Force safe_html
if
not
format
:
# can return document without conversion
return
src_mimetype
,
self
.
getTextContent
()
portal
=
self
.
getPortalObject
()
mime_type
=
portal
.
mimetypes_registry
.
lookupExtension
(
'name.%s'
%
format
)
original_mime_type
=
mime_type
=
str
(
mime_type
)
if
text_content
is
None
:
# check if document has set text_content and convert if necessary
text_content
=
self
.
getTextContent
()
if
text_content
:
kw
[
'format'
]
=
format
convert_kw
=
{}
# PortalTransforms does not accept empty values for 'encoding' parameter
if
charset
:
kw
[
'charset'
]
=
convert_kw
[
'encoding'
]
=
charset
if
not
self
.
hasConversion
(
**
kw
):
portal_transforms
=
portal
.
portal_transforms
filename
=
self
.
getFilename
()
if
mime_type
==
'text/html'
:
mime_type
=
'text/x-html-safe'
if
src_mimetype
!=
"image/svg+xml"
:
result
=
portal_transforms
.
convertToData
(
mime_type
,
text_content
,
object
=
self
,
context
=
self
,
filename
=
filename
,
mimetype
=
src_mimetype
,
**
convert_kw
)
if
result
is
None
:
raise
ConversionError
(
'TextDocument conversion error. '
'portal_transforms failed to convert '
'from %r to %s: %r'
%
(
src_mimetype
,
mime_type
,
self
))
else
:
result
=
text_content
if
format
in
VALID_IMAGE_FORMAT_LIST
:
# Include extra parameter for image conversions
temp_image
=
self
.
portal_contributions
.
newContent
(
portal_type
=
'Image'
,
file
=
cStringIO
.
StringIO
(),
filename
=
self
.
getId
(),
temp_object
=
1
)
temp_image
.
_setData
(
result
)
mime
,
result
=
temp_image
.
convert
(
**
kw
)
self
.
setConversion
(
result
,
original_mime_type
,
**
kw
)
else
:
mime_type
,
result
=
self
.
getConversion
(
**
kw
)
if
substitute
and
format
in
VALID_TEXT_FORMAT_LIST
:
# only textual content can be sustituted
if
substitution_method_parameter_dict
is
None
:
substitution_method_parameter_dict
=
{}
result
=
self
.
_substituteTextContent
(
result
,
safe_substitute
=
safe_substitute
,
**
substitution_method_parameter_dict
)
return
original_mime_type
,
result
else
:
# text_content is not set, return empty string instead of None
return
original_mime_type
,
''
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getContentBaseURL'
)
def
getContentBaseURL
(
self
):
"""
Returns the content base URL based on the actual content
(in HTML)
"""
if
self
.
hasTextContent
():
html
=
self
.
_asHTML
()
# a document can be entirely stripped by safe_html
# so its html conversion can be empty
if
html
.
strip
():
html_tree
=
etree_html
.
fromstring
(
html
)
base_list
=
[
href
for
href
in
html_tree
.
xpath
(
'//base/@href'
)
if
href
]
if
base_list
:
return
str
(
base_list
[
0
])
return
Document
.
getContentBaseURL
(
self
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setBaseData'
)
def
setBaseData
(
self
,
value
):
"""Store base_data into text_content
"""
self
.
_setTextContent
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setBaseData'
)
_setBaseData
=
setBaseData
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_baseSetBaseData'
)
_baseSetBaseData
=
_setBaseData
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setBaseContentType'
)
def
setBaseContentType
(
self
,
value
):
"""store value into content_type
"""
self
.
_setContentType
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setBaseContentType'
)
_setBaseContentType
=
setBaseContentType
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_baseSetBaseContentType'
)
_baseSetBaseContentType
=
_setBaseContentType
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getBaseData'
)
def
getBaseData
(
self
,
default
=
_MARKER
):
"""
"""
self
.
_checkConversionFormatPermission
(
None
)
if
default
is
_MARKER
:
return
self
.
getTextContent
()
else
:
return
self
.
getTextContent
(
default
=
default
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'hasBaseData'
)
def
hasBaseData
(
self
):
"""
"""
return
self
.
hasTextContent
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getContentType'
)
def
getContentType
(
self
,
default
=
_MARKER
):
"""Backward compatibility, read content_type
from text_format property
"""
if
not
self
.
hasContentType
():
# getProperty can not be used
# because text_format is not registered in local_properties
if
default
is
_MARKER
:
return
getattr
(
self
,
'text_format'
,
None
)
else
:
return
getattr
(
self
,
'text_format'
,
default
)
else
:
if
default
is
_MARKER
:
return
self
.
_baseGetContentType
()
else
:
return
self
.
_baseGetContentType
(
default
)
# base_convertable support
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'isSupportBaseDataConversion'
)
def
isSupportBaseDataConversion
(
self
):
"""
"""
return
True
def
_convertToBaseFormat
(
self
):
"""Conversion to base format for TextDocument consist
to convert file content into utf-8
"""
def
guessCharsetAndConvert
(
document
,
text_content
,
content_type
):
"""
return encoded content_type and message if encoding
is not utf-8
"""
codec
=
guessEncodingFromText
(
text_content
,
content_type
)
if
codec
is
not
None
:
try
:
text_content
=
text_content
.
decode
(
codec
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
message
=
'Conversion to base format with codec %r fails'
%
codec
# try again with another guesser based on file command
codec
=
guessEncodingFromText
(
text_content
,
'text/plain'
)
if
codec
is
not
None
:
try
:
text_content
=
text_content
.
decode
(
codec
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
message
=
'Conversion to base format with codec %r fails'
\
%
codec
else
:
message
=
'Conversion to base format with codec %r succeeds'
\
%
codec
else
:
message
=
'Conversion to base format with codec %r succeeds'
\
%
codec
else
:
message
=
'Conversion to base format without codec fails'
return
text_content
,
message
content_type
=
self
.
getContentType
()
or
DEFAULT_CONTENT_TYPE
text_content
=
self
.
getData
()
if
content_type
.
endswith
(
'xml'
):
try
:
tree
=
etree
.
fromstring
(
text_content
)
text_content
=
etree
.
tostring
(
tree
,
encoding
=
'utf-8'
,
xml_declaration
=
True
)
content_type
=
'application/xml'
message
=
'Conversion to base format succeeds'
except
etree
.
XMLSyntaxError
:
message
=
'Conversion to base format without codec fails'
elif
content_type
==
'text/html'
:
re_match
=
self
.
charset_parser
.
search
(
text_content
)
message
=
'Conversion to base format succeeds'
if
re_match
is
not
None
:
charset
=
re_match
.
group
(
'charset'
)
try
:
# Use encoding in html document
text_content
=
text_content
.
decode
(
charset
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
# Encoding read from document is wrong
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
message
=
'Conversion to base format with charset %r succeeds'
\
%
charset
if
charset
.
lower
()
!=
'utf-8'
:
charset
=
'utf-8'
# Override charset if convertion succeeds
# change charset value in html_document as well
def
subCharset
(
matchobj
):
keyword
=
matchobj
.
group
(
'keyword'
)
charset
=
matchobj
.
group
(
'charset'
)
if
not
(
keyword
or
charset
):
# no match, return same string
return
matchobj
.
group
(
0
)
elif
keyword
:
# if keyword is present, replace charset just after
return
keyword
+
'utf-8'
text_content
=
self
.
charset_parser
.
sub
(
subCharset
,
text_content
)
else
:
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
# generaly text/plain
try
:
# if succeeds, not need to change encoding
# it's already utf-8
text_content
.
decode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
),
error_message
:
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
message
=
'Conversion to base format succeeds'
self
.
_setBaseData
(
text_content
)
self
.
_setBaseContentType
(
content_type
)
return
message
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getTextContent'
)
def
getTextContent
(
self
,
default
=
_MARKER
):
"""Overriden method to check
permission to access content in raw format
"""
self
.
_checkConversionFormatPermission
(
None
)
if
default
is
_MARKER
:
return
self
.
_baseGetTextContent
()
else
:
return
self
.
_baseGetTextContent
(
default
)
# Backward compatibility for replacement of text_format by content_type
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getTextFormat'
)
def
getTextFormat
(
self
,
default
=
_MARKER
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
getContentType
(
default
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setTextFormat'
)
def
setTextFormat
(
self
,
value
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
setContentType
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setTextFormat'
)
def
_setTextFormat
(
self
,
value
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
_setContentType
(
value
)
def
getData
(
self
,
default
=
_MARKER
):
"""getData must returns original content but TextDocument accepts
data or text_content to store original content.
Fallback on text_content property if data is not defined
"""
if
not
self
.
hasData
():
if
default
is
_MARKER
:
return
self
.
getTextContent
()
else
:
return
self
.
getTextContent
(
default
)
else
:
if
default
is
_MARKER
:
return
File
.
getData
(
self
)
else
:
return
File
.
getData
(
self
,
default
)
product/ERP5/
Document/
Amount.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
Amount.py
View file @
96bbfad2
...
@@ -70,7 +70,7 @@ class Amount(Base, VariatedMixin):
...
@@ -70,7 +70,7 @@ class Amount(Base, VariatedMixin):
# THIS MUST BE UPDATE WITH CATEGORY ACQUISITION
# THIS MUST BE UPDATE WITH CATEGORY ACQUISITION
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getVariationCategoryList'
)
'getVariationCategoryList'
)
def
getVariationCategoryList
(
self
,
default
=
[],
base_category_list
=
(),
def
getVariationCategoryList
(
self
,
default
=
None
,
base_category_list
=
(),
# pylint: disable=arguments-differ
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
"""
"""
Returns the possible discrete variations
Returns the possible discrete variations
...
@@ -130,7 +130,7 @@ class Amount(Base, VariatedMixin):
...
@@ -130,7 +130,7 @@ class Amount(Base, VariatedMixin):
**
kw
).
render
(
object_list
)
**
kw
).
render
(
object_list
)
return
variation_category_item_list
return
variation_category_item_list
def
_setVariationCategoryList
(
self
,
value
):
def
_setVariationCategoryList
(
self
,
value
):
# pylint: disable=arguments-differ
resource
=
self
.
getDefaultResourceValue
()
resource
=
self
.
getDefaultResourceValue
()
if
resource
is
not
None
:
if
resource
is
not
None
:
variation_list
=
resource
.
getVariationBaseCategoryList
()
variation_list
=
resource
.
getVariationBaseCategoryList
()
...
@@ -139,13 +139,13 @@ class Amount(Base, VariatedMixin):
...
@@ -139,13 +139,13 @@ class Amount(Base, VariatedMixin):
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setVariationCategoryList'
)
'setVariationCategoryList'
)
def
setVariationCategoryList
(
self
,
value
):
def
setVariationCategoryList
(
self
,
value
):
# pylint: disable=arguments-differ
self
.
_setVariationCategoryList
(
value
)
self
.
_setVariationCategoryList
(
value
)
self
.
reindexObject
()
self
.
reindexObject
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getVariationBaseCategoryList'
)
'getVariationBaseCategoryList'
)
def
getVariationBaseCategoryList
(
self
,
default
=
[]
,
def
getVariationBaseCategoryList
(
self
,
default
=
None
,
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
"""
"""
Return the list of base_category from all variation related to
Return the list of base_category from all variation related to
...
@@ -203,7 +203,7 @@ class Amount(Base, VariatedMixin):
...
@@ -203,7 +203,7 @@ class Amount(Base, VariatedMixin):
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
\
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
\
'getVariationRangeCategoryList'
)
'getVariationRangeCategoryList'
)
def
getVariationRangeCategoryList
(
self
,
default
=
[]
,
base_category_list
=
(),
def
getVariationRangeCategoryList
(
self
,
default
=
None
,
base_category_list
=
(),
base
=
1
,
**
kw
):
base
=
1
,
**
kw
):
"""
"""
Returns possible variation category values for the
Returns possible variation category values for the
...
@@ -215,7 +215,7 @@ class Amount(Base, VariatedMixin):
...
@@ -215,7 +215,7 @@ class Amount(Base, VariatedMixin):
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getVariationRangeBaseCategoryList'
)
'getVariationRangeBaseCategoryList'
)
def
getVariationRangeBaseCategoryList
(
self
,
default
=
[],
def
getVariationRangeBaseCategoryList
(
self
,
default
=
None
,
# pylint: disable=arguments-differ
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
omit_optional_variation
=
0
,
omit_option_base_category
=
None
):
"""
"""
Returns possible variations base categories for this amount ie.
Returns possible variations base categories for this amount ie.
...
@@ -243,7 +243,7 @@ class Amount(Base, VariatedMixin):
...
@@ -243,7 +243,7 @@ class Amount(Base, VariatedMixin):
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getVariationRangeBaseCategoryItemList'
)
'getVariationRangeBaseCategoryItemList'
)
def
getVariationRangeBaseCategoryItemList
(
self
,
omit_optional_variation
=
0
,
def
getVariationRangeBaseCategoryItemList
(
self
,
omit_optional_variation
=
0
,
# pylint: disable=arguments-differ
omit_option_base_category
=
None
,
display_id
=
"title"
,
omit_option_base_category
=
None
,
display_id
=
"title"
,
display_none_category
=
0
):
display_none_category
=
0
):
"""
"""
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Amount.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
Amount
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.Amount
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.Amount
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.AmountGeneratorLine.py
View file @
96bbfad2
...
@@ -30,8 +30,8 @@ import zope.interface
...
@@ -30,8 +30,8 @@ import zope.interface
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLMatrix
import
XMLMatrix
from
Products.ERP5Type.XMLMatrix
import
XMLMatrix
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
erp5.component.interface.IAmountGeneratorLine
import
IAmountGeneratorLine
from
erp5.component.interface.IAmountGeneratorLine
import
IAmountGeneratorLine
...
...
product/ERP5/
Document/
BaseDomain.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
BaseDomain.py
View file @
96bbfad2
File moved
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.BaseDomain.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
BaseDomain
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.BaseDomain
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.BaseDomain
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/
Document/
ContributionPredicate.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
ContributionPredicate.py
View file @
96bbfad2
...
@@ -73,14 +73,14 @@ class ContributionPredicate(Predicate, XMLObject):
...
@@ -73,14 +73,14 @@ class ContributionPredicate(Predicate, XMLObject):
if
getattr
(
aq_base
(
self
),
'_identity_criterion'
,
None
)
is
None
:
if
getattr
(
aq_base
(
self
),
'_identity_criterion'
,
None
)
is
None
:
self
.
_identity_criterion
=
{}
self
.
_identity_criterion
=
{}
self
.
_range_criterion
=
{}
self
.
_range_criterion
=
{}
for
property
,
value
in
self
.
_identity_criterion
.
iteritems
():
for
property
_
,
value
in
self
.
_identity_criterion
.
iteritems
():
result
=
result
and
(
context
.
getProperty
(
property
)
in
value
)
result
=
result
and
(
context
.
getProperty
(
property
_
)
in
value
)
for
property
,
(
min
,
max
)
in
self
.
_range_criterion
.
iteritems
():
for
property
_
,
(
min_
,
max_
)
in
self
.
_range_criterion
.
iteritems
():
value
=
context
.
getProperty
(
property
)
value
=
context
.
getProperty
(
property
_
)
if
min
is
not
None
:
if
min
_
is
not
None
:
result
=
result
and
(
value
>=
min
)
result
=
result
and
(
value
>=
min
_
)
if
max
is
not
None
:
if
max
_
is
not
None
:
result
=
result
and
(
value
<
max
)
result
=
result
and
(
value
<
max
_
)
multimembership_criterion_base_category_list
=
\
multimembership_criterion_base_category_list
=
\
self
.
getMultimembershipCriterionBaseCategoryList
()
self
.
getMultimembershipCriterionBaseCategoryList
()
membership_criterion_base_category_list
=
\
membership_criterion_base_category_list
=
\
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.ContributionPredicate.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
ContributionPredicate
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.ContributionPredicate
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.ContributionPredicate
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.DeliveryCell.py
View file @
96bbfad2
...
@@ -36,7 +36,7 @@ from AccessControl.PermissionRole import PermissionRole
...
@@ -36,7 +36,7 @@ from AccessControl.PermissionRole import PermissionRole
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
erp5.component.document.Movement
import
Movement
from
erp5.component.document.Movement
import
Movement
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
erp5.component.document.ImmobilisationMovement
import
ImmobilisationMovement
from
erp5.component.document.ImmobilisationMovement
import
ImmobilisationMovement
from
erp5.component.interface.IDivergenceController
import
IDivergenceController
from
erp5.component.interface.IDivergenceController
import
IDivergenceController
...
...
product/ERP5/
Document/
DomainGenerator.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
DomainGenerator.py
View file @
96bbfad2
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.DomainGenerator.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
DomainGenerator
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.DomainGenerator
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.DomainGenerator
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.EmailDocument.py
View file @
96bbfad2
...
@@ -32,9 +32,9 @@ from DateTime import DateTime
...
@@ -32,9 +32,9 @@ from DateTime import DateTime
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type.Accessor.Constant
import
PropertyGetter
as
ConstantGetter
from
Products.ERP5Type.Accessor.Constant
import
PropertyGetter
as
ConstantGetter
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.TextDocument
import
TextDocument
from
erp5.component.d
ocument.TextDocument
import
TextDocument
from
Products.ERP5.Document.File
import
File
from
Products.ERP5.Document.File
import
File
from
Products.ERP5.mixin.mail_message
import
MailMessageMixin
,
testCharsetAndConvert
from
erp5.component.mixin.MailMessageMixin
import
MailMessageMixin
,
testCharsetAndConvert
from
Products.ERP5.mixin.document_proxy
import
DocumentProxyMixin
,
DocumentProxyError
from
Products.ERP5.mixin.document_proxy
import
DocumentProxyMixin
,
DocumentProxyError
from
MethodObject
import
Method
from
MethodObject
import
Method
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.ImmobilisableItem.py
View file @
96bbfad2
...
@@ -37,7 +37,7 @@ from erp5.component.interface.IImmobilisationItem import IImmobilisationItem
...
@@ -37,7 +37,7 @@ from erp5.component.interface.IImmobilisationItem import IImmobilisationItem
from
Products.ERP5Type.DateUtils
import
addToDate
,
getClosestDate
,
roundDate
from
Products.ERP5Type.DateUtils
import
addToDate
,
getClosestDate
,
roundDate
from
Products.ERP5Type.DateUtils
import
getRoundedMonthBetween
,
millis
from
Products.ERP5Type.DateUtils
import
getRoundedMonthBetween
,
millis
from
Products.ERP5Type.DateUtils
import
getAccountableYearFraction
from
Products.ERP5Type.DateUtils
import
getAccountableYearFraction
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
erp5.component.document.Item
import
Item
from
erp5.component.document.Item
import
Item
from
Products.CMFCore.utils
import
getToolByName
from
Products.CMFCore.utils
import
getToolByName
from
erp5.component.document.ImmobilisationMovement
import
(
from
erp5.component.document.ImmobilisationMovement
import
(
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Item.py
View file @
96bbfad2
...
@@ -31,7 +31,7 @@ from AccessControl import ClassSecurityInfo
...
@@ -31,7 +31,7 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
class
Item
(
XMLObject
,
Amount
):
class
Item
(
XMLObject
,
Amount
):
...
...
product/ERP5/
Document/
MappedValue.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
MappedValue.py
View file @
96bbfad2
...
@@ -29,12 +29,11 @@
...
@@ -29,12 +29,11 @@
import
zope.interface
import
zope.interface
from
AccessControl
import
ClassSecurityInfo
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_base
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type
import
Permissions
,
PropertySheet
,
interfaces
from
Products.ERP5Type.Core.Predicate
import
Predicate
from
Products.ERP5Type.Core.Predicate
import
Predicate
TRANSFORMATION_FIX
=
True
TRANSFORMATION_FIX
=
True
_MARKER
=
[]
_MARKER
=
object
()
class
MappedValue
(
Predicate
):
class
MappedValue
(
Predicate
):
"""
"""
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.MappedValue.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
MappedValue
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.MappedValue
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.MappedValue
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Movement.py
View file @
96bbfad2
...
@@ -41,7 +41,7 @@ from Products.ERP5Type.XMLObject import XMLObject
...
@@ -41,7 +41,7 @@ from Products.ERP5Type.XMLObject import XMLObject
from
Products.ERP5Type.UnrestrictedMethod
import
unrestricted_apply
from
Products.ERP5Type.UnrestrictedMethod
import
unrestricted_apply
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
erp5.component.mixin.AmountGeneratorMixin
import
AmountGeneratorMixin
from
Products.ERP5.mixin.composition
import
CompositionMixin
from
Products.ERP5.mixin.composition
import
CompositionMixin
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
from
Products.ERP5Type.Cache
import
transactional_cached
from
Products.ERP5Type.Cache
import
transactional_cached
from
erp5.component.interface.IAmountGenerator
import
IAmountGenerator
from
erp5.component.interface.IAmountGenerator
import
IAmountGenerator
from
erp5.component.interface.IMovement
import
IMovement
from
erp5.component.interface.IMovement
import
IMovement
...
...
product/ERP5/
Document/
Path.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
Path.py
View file @
96bbfad2
...
@@ -30,8 +30,8 @@ from AccessControl import ClassSecurityInfo
...
@@ -30,8 +30,8 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
Products.ERP5.D
ocument.Amount
import
Amount
from
erp5.component.d
ocument.Amount
import
Amount
class
Path
(
MappedValue
,
Amount
):
class
Path
(
MappedValue
,
Amount
):
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Path.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
Path
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.Path
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.Path
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/
Document/
PredicateGroup.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
PredicateGroup.py
View file @
96bbfad2
File moved
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateGroup.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
PredicateGroup
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.PredicateGroup
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.PredicateGroup
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/
Document/
PredicateMatrix.py
→
product/ERP5/
bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
PredicateMatrix.py
View file @
96bbfad2
...
@@ -85,8 +85,8 @@ class PredicateMatrix(XMLMatrix):
...
@@ -85,8 +85,8 @@ class PredicateMatrix(XMLMatrix):
c
.
edit
(
mapped_value_property_list
=
(
'title'
,),
c
.
edit
(
mapped_value_property_list
=
(
'title'
,),
predicate_category_list
=
[
self
.
_getOb
(
k_item
).
getRelativeUrl
()
predicate_category_list
=
[
self
.
_getOb
(
k_item
).
getRelativeUrl
()
for
k_item
in
k
],
for
k_item
in
k
],
title
=
" * "
.
join
(
map
(
lambda
k_item
:
\
title
=
" * "
.
join
(
[
self
.
unrestrictedTraverse
(
k_item
).
getTitle
(),
k
)
),
self
.
unrestrictedTraverse
(
k_item
).
getTitle
()
for
k_item
in
k
]
),
force_update
=
1
force_update
=
1
)
)
else
:
else
:
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.PredicateMatrix.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
PredicateMatrix
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.PredicateMatrix
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.PredicateMatrix
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.TextDocument.py
0 → 100644
View file @
96bbfad2
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL 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 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.ZopeGuards
import
guarded_getattr
from
AccessControl
import
ClassSecurityInfo
from
zLOG
import
LOG
,
WARNING
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5.Document.Document
import
Document
,
ConversionError
,
_MARKER
,
DEFAULT_CONTENT_TYPE
from
Products.ERP5.Document.File
import
File
from
Products.ERP5Type.WebDAVSupport
import
TextContent
from
Products.ERP5.Document.Document
import
VALID_IMAGE_FORMAT_LIST
,
VALID_TEXT_FORMAT_LIST
import
cStringIO
from
string
import
Template
# Mixin Import
from
Products.ERP5.mixin.cached_convertable
import
CachedConvertableMixin
from
Products.ERP5.mixin.base_convertable
import
BaseConvertableFileMixin
from
Products.ERP5Type.mixin.text_content_history
import
TextContentHistoryMixin
from
Products.ERP5Type.Utils
import
guessEncodingFromText
from
lxml
import
html
as
etree_html
from
lxml
import
etree
class
TextDocument
(
CachedConvertableMixin
,
BaseConvertableFileMixin
,
TextContentHistoryMixin
,
TextContent
,
File
):
"""A TextDocument impletents IDocument, IFile, IBaseConvertable, ICachedconvertable
and ITextConvertable
"""
meta_type
=
'ERP5 Text Document'
portal_type
=
'Text Document'
add_permission
=
Permissions
.
AddPortalContent
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# Declarative properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
Version
,
PropertySheet
.
Document
,
PropertySheet
.
ExternalDocument
,
PropertySheet
.
Url
,
PropertySheet
.
TextDocument
,
PropertySheet
.
Data
,
PropertySheet
.
Reference
)
def
_substituteTextContent
(
self
,
text
,
safe_substitute
=
True
,
**
kw
):
# If a method for string substitutions of the text content, perform it.
# Decode everything into unicode before the substitutions, in order to
# avoid encoding errors.
method_id
=
self
.
getTextContentSubstitutionMappingMethodId
()
if
method_id
:
try
:
method
=
guarded_getattr
(
self
,
method_id
)
except
AttributeError
:
LOG
(
'TextDocument'
,
WARNING
,
'could not get the substitution'
' mapping method %s from %r, so the content will not be'
' substituted.'
%
(
method_id
,
self
.
getRelativeUrl
()))
return
text
mapping
=
method
(
**
kw
)
is_str
=
isinstance
(
text
,
str
)
if
is_str
:
text
=
text
.
decode
(
'utf-8'
)
class
UnicodeMapping
:
def
__getitem__
(
self
,
item
):
v
=
mapping
[
item
]
if
isinstance
(
v
,
str
):
v
=
v
.
decode
(
'utf-8'
)
elif
not
isinstance
(
v
,
unicode
):
v
=
str
(
v
).
decode
(
'utf-8'
)
return
v
unicode_mapping
=
UnicodeMapping
()
if
safe_substitute
:
text
=
Template
(
text
).
safe_substitute
(
unicode_mapping
)
else
:
text
=
Template
(
text
).
substitute
(
unicode_mapping
)
# If the original was a str, convert it back to str.
if
is_str
:
text
=
text
.
encode
(
'utf-8'
)
return
text
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'asSubjectText'
)
def
asSubjectText
(
self
,
substitution_method_parameter_dict
=
None
,
safe_substitute
=
True
,
**
kw
):
"""
Converts the subject of the document to a textual representation.
"""
subject
=
TextDocument
.
inheritedAttribute
(
'asSubjectText'
)(
self
,
**
kw
)
if
substitution_method_parameter_dict
is
None
:
substitution_method_parameter_dict
=
{}
return
self
.
_substituteTextContent
(
subject
,
safe_substitute
=
safe_substitute
,
**
substitution_method_parameter_dict
)
def
_convert
(
self
,
format
,
substitution_method_parameter_dict
=
None
,
# pylint: disable=redefined-builtin
safe_substitute
=
True
,
charset
=
None
,
text_content
=
None
,
substitute
=
True
,
**
kw
):
"""
Convert text using portal_transforms or oood
"""
# XXX 'or DEFAULT_CONTENT_TYPE' is compaptibility code used for old
# web_page that have neither content_type nor text_format. Migration
# should be done to make all web page having content_type property
src_mimetype
=
self
.
getContentType
()
or
DEFAULT_CONTENT_TYPE
if
not
format
and
src_mimetype
==
'text/html'
:
format
=
'html'
# Force safe_html
if
not
format
:
# can return document without conversion
return
src_mimetype
,
self
.
getTextContent
()
portal
=
self
.
getPortalObject
()
mime_type
=
portal
.
mimetypes_registry
.
lookupExtension
(
'name.%s'
%
format
)
original_mime_type
=
mime_type
=
str
(
mime_type
)
if
text_content
is
None
:
# check if document has set text_content and convert if necessary
text_content
=
self
.
getTextContent
()
if
text_content
:
kw
[
'format'
]
=
format
convert_kw
=
{}
# PortalTransforms does not accept empty values for 'encoding' parameter
if
charset
:
kw
[
'charset'
]
=
convert_kw
[
'encoding'
]
=
charset
if
not
self
.
hasConversion
(
**
kw
):
portal_transforms
=
portal
.
portal_transforms
filename
=
self
.
getFilename
()
if
mime_type
==
'text/html'
:
mime_type
=
'text/x-html-safe'
if
src_mimetype
!=
"image/svg+xml"
:
result
=
portal_transforms
.
convertToData
(
mime_type
,
text_content
,
object
=
self
,
context
=
self
,
filename
=
filename
,
mimetype
=
src_mimetype
,
**
convert_kw
)
if
result
is
None
:
raise
ConversionError
(
'TextDocument conversion error. '
'portal_transforms failed to convert '
'from %r to %s: %r'
%
(
src_mimetype
,
mime_type
,
self
))
else
:
result
=
text_content
if
format
in
VALID_IMAGE_FORMAT_LIST
:
# Include extra parameter for image conversions
temp_image
=
self
.
portal_contributions
.
newContent
(
portal_type
=
'Image'
,
file
=
cStringIO
.
StringIO
(),
filename
=
self
.
getId
(),
temp_object
=
1
)
temp_image
.
_setData
(
result
)
_
,
result
=
temp_image
.
convert
(
**
kw
)
self
.
setConversion
(
result
,
original_mime_type
,
**
kw
)
else
:
mime_type
,
result
=
self
.
getConversion
(
**
kw
)
if
substitute
and
format
in
VALID_TEXT_FORMAT_LIST
:
# only textual content can be sustituted
if
substitution_method_parameter_dict
is
None
:
substitution_method_parameter_dict
=
{}
result
=
self
.
_substituteTextContent
(
result
,
safe_substitute
=
safe_substitute
,
**
substitution_method_parameter_dict
)
return
original_mime_type
,
result
else
:
# text_content is not set, return empty string instead of None
return
original_mime_type
,
''
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getContentBaseURL'
)
def
getContentBaseURL
(
self
):
"""
Returns the content base URL based on the actual content
(in HTML)
"""
if
self
.
hasTextContent
():
html
=
self
.
_asHTML
()
# a document can be entirely stripped by safe_html
# so its html conversion can be empty
if
html
.
strip
():
html_tree
=
etree_html
.
fromstring
(
html
)
base_list
=
[
href
for
href
in
html_tree
.
xpath
(
'//base/@href'
)
if
href
]
if
base_list
:
return
str
(
base_list
[
0
])
return
Document
.
getContentBaseURL
(
self
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setBaseData'
)
def
setBaseData
(
self
,
value
):
"""Store base_data into text_content
"""
self
.
_setTextContent
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setBaseData'
)
_setBaseData
=
setBaseData
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_baseSetBaseData'
)
_baseSetBaseData
=
_setBaseData
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setBaseContentType'
)
def
setBaseContentType
(
self
,
value
):
"""store value into content_type
"""
self
.
_setContentType
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setBaseContentType'
)
_setBaseContentType
=
setBaseContentType
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_baseSetBaseContentType'
)
_baseSetBaseContentType
=
_setBaseContentType
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getBaseData'
)
def
getBaseData
(
self
,
default
=
_MARKER
):
"""
"""
self
.
_checkConversionFormatPermission
(
None
)
if
default
is
_MARKER
:
return
self
.
getTextContent
()
else
:
return
self
.
getTextContent
(
default
=
default
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'hasBaseData'
)
def
hasBaseData
(
self
):
"""
"""
return
self
.
hasTextContent
()
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getContentType'
)
def
getContentType
(
self
,
default
=
_MARKER
):
# pylint: disable=arguments-differ
"""Backward compatibility, read content_type
from text_format property
"""
if
not
self
.
hasContentType
():
# getProperty can not be used
# because text_format is not registered in local_properties
if
default
is
_MARKER
:
return
getattr
(
self
,
'text_format'
,
None
)
else
:
return
getattr
(
self
,
'text_format'
,
default
)
else
:
if
default
is
_MARKER
:
return
self
.
_baseGetContentType
()
else
:
return
self
.
_baseGetContentType
(
default
)
# base_convertable support
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'isSupportBaseDataConversion'
)
def
isSupportBaseDataConversion
(
self
):
"""
"""
return
True
def
_convertToBaseFormat
(
self
):
"""Conversion to base format for TextDocument consist
to convert file content into utf-8
"""
def
guessCharsetAndConvert
(
document
,
text_content
,
content_type
):
"""
return encoded content_type and message if encoding
is not utf-8
"""
codec
=
guessEncodingFromText
(
text_content
,
content_type
)
if
codec
is
not
None
:
try
:
text_content
=
text_content
.
decode
(
codec
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
message
=
'Conversion to base format with codec %r fails'
%
codec
# try again with another guesser based on file command
codec
=
guessEncodingFromText
(
text_content
,
'text/plain'
)
if
codec
is
not
None
:
try
:
text_content
=
text_content
.
decode
(
codec
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
message
=
'Conversion to base format with codec %r fails'
\
%
codec
else
:
message
=
'Conversion to base format with codec %r succeeds'
\
%
codec
else
:
message
=
'Conversion to base format with codec %r succeeds'
\
%
codec
else
:
message
=
'Conversion to base format without codec fails'
return
text_content
,
message
content_type
=
self
.
getContentType
()
or
DEFAULT_CONTENT_TYPE
text_content
=
self
.
getData
()
if
content_type
.
endswith
(
'xml'
):
try
:
tree
=
etree
.
fromstring
(
text_content
)
text_content
=
etree
.
tostring
(
tree
,
encoding
=
'utf-8'
,
xml_declaration
=
True
)
content_type
=
'application/xml'
message
=
'Conversion to base format succeeds'
except
etree
.
XMLSyntaxError
:
# pylint: disable=catching-non-exception
message
=
'Conversion to base format without codec fails'
elif
content_type
==
'text/html'
:
re_match
=
self
.
charset_parser
.
search
(
text_content
)
message
=
'Conversion to base format succeeds'
if
re_match
is
not
None
:
charset
=
re_match
.
group
(
'charset'
)
try
:
# Use encoding in html document
text_content
=
text_content
.
decode
(
charset
).
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
# Encoding read from document is wrong
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
message
=
'Conversion to base format with charset %r succeeds'
\
%
charset
if
charset
.
lower
()
!=
'utf-8'
:
charset
=
'utf-8'
# Override charset if convertion succeeds
# change charset value in html_document as well
def
subCharset
(
matchobj
):
keyword
=
matchobj
.
group
(
'keyword'
)
charset
=
matchobj
.
group
(
'charset'
)
if
not
(
keyword
or
charset
):
# no match, return same string
return
matchobj
.
group
(
0
)
elif
keyword
:
# if keyword is present, replace charset just after
return
keyword
+
'utf-8'
text_content
=
self
.
charset_parser
.
sub
(
subCharset
,
text_content
)
else
:
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
# generaly text/plain
try
:
# if succeeds, not need to change encoding
# it's already utf-8
text_content
.
decode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
):
text_content
,
message
=
guessCharsetAndConvert
(
self
,
text_content
,
content_type
)
else
:
message
=
'Conversion to base format succeeds'
self
.
_setBaseData
(
text_content
)
self
.
_setBaseContentType
(
content_type
)
return
message
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getTextContent'
)
def
getTextContent
(
self
,
default
=
_MARKER
):
"""Overriden method to check
permission to access content in raw format
"""
self
.
_checkConversionFormatPermission
(
None
)
if
default
is
_MARKER
:
return
self
.
_baseGetTextContent
()
else
:
return
self
.
_baseGetTextContent
(
default
)
# Backward compatibility for replacement of text_format by content_type
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'getTextFormat'
)
def
getTextFormat
(
self
,
default
=
_MARKER
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
getContentType
(
default
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setTextFormat'
)
def
setTextFormat
(
self
,
value
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
setContentType
(
value
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'_setTextFormat'
)
def
_setTextFormat
(
self
,
value
):
"""
"""
LOG
(
'TextDocument'
,
WARNING
,
'Usage of text_format is deprecated, use content_type instead'
)
return
self
.
_setContentType
(
value
)
def
getData
(
self
,
default
=
_MARKER
):
"""getData must returns original content but TextDocument accepts
data or text_content to store original content.
Fallback on text_content property if data is not defined
"""
if
not
self
.
hasData
():
if
default
is
_MARKER
:
return
self
.
getTextContent
()
else
:
return
self
.
getTextContent
(
default
)
else
:
if
default
is
_MARKER
:
return
File
.
getData
(
self
)
else
:
return
File
.
getData
(
self
,
default
)
\ No newline at end of file
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.TextDocument.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
TextDocument
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.Document.TextDocument
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.TextDocument
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5
Workflow/Document/
Transition.py
→
product/ERP5
/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.
Transition.py
View file @
96bbfad2
...
@@ -76,7 +76,7 @@ class Transition(XMLObject):
...
@@ -76,7 +76,7 @@ class Transition(XMLObject):
status_dict
[
state_bc_id
]
=
document
.
getCategoryMembershipList
(
state_bc_id
)[
0
]
status_dict
[
state_bc_id
]
=
document
.
getCategoryMembershipList
(
state_bc_id
)[
0
]
state_object
=
document
.
unrestrictedTraverse
(
status_dict
[
state_bc_id
])
state_object
=
document
.
unrestrictedTraverse
(
status_dict
[
state_bc_id
])
object
=
workflow
.
getStateChangeInformation
(
document
,
state_object
,
transition
=
self
)
object
_
=
workflow
.
getStateChangeInformation
(
document
,
state_object
,
transition
=
self
)
# Update all variables
# Update all variables
for
variable
in
workflow
.
contentValues
(
portal_type
=
'Variable'
):
for
variable
in
workflow
.
contentValues
(
portal_type
=
'Variable'
):
...
@@ -87,13 +87,13 @@ class Transition(XMLObject):
...
@@ -87,13 +87,13 @@ class Transition(XMLObject):
if
variable_title
in
form_kw
:
if
variable_title
in
form_kw
:
status_dict
[
variable_title
]
=
form_kw
[
variable_title
]
status_dict
[
variable_title
]
=
form_kw
[
variable_title
]
else
:
else
:
status_dict
[
variable_title
]
=
variable
.
getInitialValue
(
object
=
object
)
status_dict
[
variable_title
]
=
variable
.
getInitialValue
(
object
=
object
_
)
# Update all transition variables
# Update all transition variables
if
form_kw
is
not
None
:
if
form_kw
is
not
None
:
object
.
REQUEST
.
other
.
update
(
form_kw
)
object
_
.
REQUEST
.
other
.
update
(
form_kw
)
for
variable
in
self
.
contentValues
(
portal_type
=
'Transition Variable'
):
for
variable
in
self
.
contentValues
(
portal_type
=
'Transition Variable'
):
status_dict
[
variable
.
getCausalityTitle
()]
=
variable
.
getInitialValue
(
object
=
object
)
status_dict
[
variable
.
getCausalityTitle
()]
=
variable
.
getInitialValue
(
object
=
object
_
)
workflow
.
_updateWorkflowHistory
(
document
,
status_dict
)
workflow
.
_updateWorkflowHistory
(
document
,
status_dict
)
...
...
product/ERP5/bootstrap/erp5_core/DocumentTemplateItem/portal_components/document.erp5.Transition.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Document Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
Transition
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5Workflow.Document.Transition
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
document.erp5.Transition
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Document Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.AmountGeneratorMixin.py
View file @
96bbfad2
...
@@ -35,7 +35,7 @@ from Acquisition import aq_base, Implicit
...
@@ -35,7 +35,7 @@ from Acquisition import aq_base, Implicit
from
Products.ERP5.GeneratedAmountList
import
GeneratedAmountList
from
Products.ERP5.GeneratedAmountList
import
GeneratedAmountList
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5Type.TransactionalVariable
import
getTransactionalVariable
from
Products.ERP5.D
ocument.MappedValue
import
MappedValue
from
erp5.component.d
ocument.MappedValue
import
MappedValue
from
erp5.component.interface.IAmountGenerator
import
IAmountGenerator
from
erp5.component.interface.IAmountGenerator
import
IAmountGenerator
# XXX What should be done when there is no base_application ?
# XXX What should be done when there is no base_application ?
...
...
product/ERP5/
mixin/mail_message
.py
→
product/ERP5/
bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.MailMessageMixin
.py
View file @
96bbfad2
...
@@ -30,7 +30,6 @@ from AccessControl import ClassSecurityInfo
...
@@ -30,7 +30,6 @@ from AccessControl import ClassSecurityInfo
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type.Globals
import
InitializeClass
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.Utils
import
guessEncodingFromText
from
Products.ERP5Type.Utils
import
guessEncodingFromText
from
Products.ERP5.Document.TextDocument
import
TextDocument
from
zLOG
import
LOG
,
INFO
from
zLOG
import
LOG
,
INFO
from
email.header
import
decode_header
,
HeaderParseError
from
email.header
import
decode_header
,
HeaderParseError
...
@@ -45,7 +44,7 @@ def testCharsetAndConvert(text_content, content_type, encoding):
...
@@ -45,7 +44,7 @@ def testCharsetAndConvert(text_content, content_type, encoding):
text_content
=
text_content
.
decode
(
encoding
).
encode
(
'utf-8'
)
text_content
=
text_content
.
decode
(
encoding
).
encode
(
'utf-8'
)
else
:
else
:
text_content
=
text_content
.
decode
().
encode
(
'utf-8'
)
text_content
=
text_content
.
decode
().
encode
(
'utf-8'
)
except
(
UnicodeDecodeError
,
LookupError
)
,
error_message
:
except
(
UnicodeDecodeError
,
LookupError
):
encoding
=
guessEncodingFromText
(
text_content
,
content_type
)
encoding
=
guessEncodingFromText
(
text_content
,
content_type
)
if
encoding
is
not
None
:
if
encoding
is
not
None
:
try
:
try
:
...
@@ -96,7 +95,6 @@ class MailMessageMixin:
...
@@ -96,7 +95,6 @@ class MailMessageMixin:
# Try to get the favourite text format defined on preference
# Try to get the favourite text format defined on preference
preferred_content_type
=
self
.
getPortalObject
().
portal_preferences
.
\
preferred_content_type
=
self
.
getPortalObject
().
portal_preferences
.
\
getPreferredTextFormat
(
'text/html'
)
getPreferredTextFormat
(
'text/html'
)
favourite_part
=
None
for
subpart
in
part
.
get_payload
():
for
subpart
in
part
.
get_payload
():
if
subpart
.
get_content_type
()
==
preferred_content_type
:
if
subpart
.
get_content_type
()
==
preferred_content_type
:
part_list
.
insert
(
0
,
subpart
)
part_list
.
insert
(
0
,
subpart
)
...
@@ -210,11 +208,11 @@ class MailMessageMixin:
...
@@ -210,11 +208,11 @@ class MailMessageMixin:
if
'text/html'
in
content_type
:
if
'text/html'
in
content_type
:
part_encoding
=
part
.
get_content_charset
()
part_encoding
=
part
.
get_content_charset
()
message_text
=
part
.
get_payload
(
decode
=
1
)
message_text
=
part
.
get_payload
(
decode
=
1
)
text_result
,
encoding
=
testCharsetAndConvert
(
message_text
,
text_result
,
_
=
testCharsetAndConvert
(
message_text
,
content_type
,
content_type
,
part_encoding
)
part_encoding
)
# Strip out html content in safe mode.
# Strip out html content in safe mode.
mime
,
content
=
self
.
convert
(
format
=
'html'
,
_
,
content
=
self
.
convert
(
format
=
'html'
,
text_content
=
text_result
,
text_content
=
text_result
,
encoding
=
part_encoding
,
encoding
=
part_encoding
,
index
=
index
)
# add index to generate
index
=
index
)
# add index to generate
...
...
product/ERP5/bootstrap/erp5_core/MixinTemplateItem/portal_components/mixin.erp5.MailMessageMixin.xml
0 → 100644
View file @
96bbfad2
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Mixin Component"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
MailMessageMixin
</string>
</value>
</item>
<item>
<key>
<string>
default_source_reference
</string>
</key>
<value>
<string>
Products.ERP5.mixin.mail_message
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
mixin.erp5.MailMessageMixin
</string>
</value>
</item>
<item>
<key>
<string>
portal_type
</string>
</key>
<value>
<string>
Mixin Component
</string>
</value>
</item>
<item>
<key>
<string>
sid
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
text_content_error_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
text_content_warning_message
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<string>
erp5
</string>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
component_validation_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
validate
</string>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
validated
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
product/ERP5/bootstrap/erp5_core/bt/template_document_id_list
View file @
96bbfad2
document.erp5.Amount
document.erp5.AmountGeneratorLine
document.erp5.AmountGeneratorLine
document.erp5.AppliedRule
document.erp5.AppliedRule
document.erp5.BaseDomain
document.erp5.ContributionPredicate
document.erp5.Delivery
document.erp5.Delivery
document.erp5.DeliveryCell
document.erp5.DeliveryCell
document.erp5.DeliveryLine
document.erp5.DeliveryLine
document.erp5.DomainGenerator
document.erp5.EmailDocument
document.erp5.EmailDocument
document.erp5.Event
document.erp5.Event
document.erp5.ImmobilisableItem
document.erp5.ImmobilisableItem
...
@@ -15,9 +19,15 @@ document.erp5.InvoiceCell
...
@@ -15,9 +19,15 @@ document.erp5.InvoiceCell
document.erp5.InvoiceLine
document.erp5.InvoiceLine
document.erp5.Item
document.erp5.Item
document.erp5.MailMessage
document.erp5.MailMessage
document.erp5.MappedValue
document.erp5.Movement
document.erp5.Movement
document.erp5.Order
document.erp5.Order
document.erp5.PackingList
document.erp5.PackingList
document.erp5.Path
document.erp5.PredicateGroup
document.erp5.PredicateMatrix
document.erp5.Project
document.erp5.Project
document.erp5.ScriptConstraint
document.erp5.ScriptConstraint
document.erp5.SimulationMovement
document.erp5.SimulationMovement
document.erp5.TextDocument
document.erp5.Transition
\ No newline at end of file
product/ERP5/bootstrap/erp5_core/bt/template_mixin_id_list
View file @
96bbfad2
mixin.erp5.AmountGeneratorMixin
mixin.erp5.AmountGeneratorMixin
mixin.erp5.ExplainableMixin
mixin.erp5.ExplainableMixin
mixin.erp5.MailMessageMixin
mixin.erp5.MovementCollectionUpdaterMixin
mixin.erp5.MovementCollectionUpdaterMixin
mixin.erp5.MovementGeneratorMixin
mixin.erp5.MovementGeneratorMixin
mixin.erp5.RuleMixin
mixin.erp5.RuleMixin
...
...
product/ERP5/tests/testERP5Interfaces.py
View file @
96bbfad2
...
@@ -53,7 +53,7 @@ implements_tuple_list = [
...
@@ -53,7 +53,7 @@ implements_tuple_list = [
((
'erp5.component.document.Image'
,
'Image'
),
'IDocument'
),
((
'erp5.component.document.Image'
,
'Image'
),
'IDocument'
),
((
'Products.ERP5.Document.File'
,
'File'
),
'IDocument'
),
((
'Products.ERP5.Document.File'
,
'File'
),
'IDocument'
),
((
'erp5.component.document.OOoDocument'
,
'OOoDocument'
),
'IDocument'
),
((
'erp5.component.document.OOoDocument'
,
'OOoDocument'
),
'IDocument'
),
((
'
Products.ERP5.D
ocument.TextDocument'
,
'TextDocument'
),
'IDocument'
),
((
'
erp5.component.d
ocument.TextDocument'
,
'TextDocument'
),
'IDocument'
),
((
'erp5.component.document.EmailDocument'
,
'EmailDocument'
),
'IDocument'
),
((
'erp5.component.document.EmailDocument'
,
'EmailDocument'
),
'IDocument'
),
((
'erp5.component.document.Event'
,
'Event'
),
'IDocument'
),
((
'erp5.component.document.Event'
,
'Event'
),
'IDocument'
),
# IAmountList
# IAmountList
...
...
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