Commit a796aa0c authored by Jérome Perrin's avatar Jérome Perrin

*: refactor edit_order of Base._edit 💥

and maybe :

ERP5Type/Base: execute workflow interactions in alphabetic order

With a perfect configuration, this should probably does not matter,
because the order of interactions should not be important (if there
are dependencies they should be handled more explicitly), but this
makes the behavior deterministic.

and maybe:

always sort in edit
parent 98d5349e
...@@ -70,6 +70,8 @@ class Resource(XMLObject, XMLMatrix, VariatedMixin): ...@@ -70,6 +70,8 @@ class Resource(XMLObject, XMLMatrix, VariatedMixin):
, PropertySheet.Aggregated , PropertySheet.Aggregated
) )
_default_edit_order = VariatedMixin._default_edit_order
# Is it OK now ? # Is it OK now ?
# The same method is at about 3 different places # The same method is at about 3 different places
# Some genericity is needed # Some genericity is needed
......
...@@ -66,6 +66,28 @@ class Amount(Base, VariatedMixin): ...@@ -66,6 +66,28 @@ class Amount(Base, VariatedMixin):
, PropertySheet.Reference , PropertySheet.Reference
) )
_default_edit_order = (
'resource',
'resource_value',
# If variations and resources are set at the same time, resource must be
# set before any variation.
'variation_base_category_list',
'variation_category_list',
# If (quantity unit, base_contribution, or use) and resource are set at the same time,
# resource must be set first, because of an interaction that copies quantity unit
# base contribution and use from resource if not set.
'quantity_unit_value',
'quantity_unit',
'use_value',
'use',
'base_contribution_list',
'base_contribution_value_list',
'base_contribution_value',
'base_contribution',
)
# A few more mix-in methods which should be relocated # A few more mix-in methods which should be relocated
# THIS MUST BE UPDATE WITH CATEGORY ACQUISITION # THIS MUST BE UPDATE WITH CATEGORY ACQUISITION
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
......
...@@ -50,6 +50,8 @@ class AmountGeneratorLine(MappedValue, XMLMatrix, Amount, ...@@ -50,6 +50,8 @@ class AmountGeneratorLine(MappedValue, XMLMatrix, Amount,
property_sheets = (PropertySheet.DublinCore, property_sheets = (PropertySheet.DublinCore,
PropertySheet.AmountGeneratorLine) PropertySheet.AmountGeneratorLine)
_default_edit_order = Amount._default_edit_order
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getCellAggregateKey') 'getCellAggregateKey')
def getCellAggregateKey(self): def getCellAggregateKey(self):
......
...@@ -79,6 +79,11 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin, ...@@ -79,6 +79,11 @@ class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
, PropertySheet.Price , PropertySheet.Price
) )
_default_edit_order = (
'stop_date',
'start_date',
)
security.declareProtected(Permissions.AccessContentsInformation, 'isAccountable') security.declareProtected(Permissions.AccessContentsInformation, 'isAccountable')
def isAccountable(self): def isAccountable(self):
""" """
......
...@@ -124,24 +124,6 @@ class DeliveryCell(MappedValue, Movement, ImmobilisationMovement): ...@@ -124,24 +124,6 @@ class DeliveryCell(MappedValue, Movement, ImmobilisationMovement):
self._setPredicateValueList(new_predicate_value) self._setPredicateValueList(new_predicate_value)
# No reindex needed since uid stable # No reindex needed since uid stable
# XXX FIXME: option variation are today not well implemented
# This little hack is needed to make the matrixbox working
# in DeliveryLine_viewIndustrialPhase
# Generic form (DeliveryLine_viewOption) is required
def _edit(self, **kw):
"""
Store variation_category_list, in order to store new value of
industrial_phase after.
"""
edit_order = ['variation_category_list', # edit this one first
'item_id_list'] # this one must be the last
edit_order[1:1] = [x for x in kw.pop('edit_order', ())
if x not in edit_order]
# Base._edit updates unordered properties first
edit_order[1:1] = [x for x in kw if x not in edit_order]
MappedValue._edit(self, edit_order=edit_order, **kw)
# if self.isSimulated():
# self.getRootDeliveryValue().activate().propagateResourceToSimulation()
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
'updateSimulationDeliveryProperties') 'updateSimulationDeliveryProperties')
......
...@@ -36,9 +36,6 @@ from Products.ERP5Type.XMLMatrix import XMLMatrix ...@@ -36,9 +36,6 @@ from Products.ERP5Type.XMLMatrix import XMLMatrix
from erp5.component.document.Movement import Movement from erp5.component.document.Movement import Movement
from erp5.component.document.ImmobilisationMovement import ImmobilisationMovement from erp5.component.document.ImmobilisationMovement import ImmobilisationMovement
from inspect import getargspec
from Products.ERP5Type.Base import Base
edit_args_list = getargspec(Base._edit).args
from erp5.component.interface.IDivergenceController import IDivergenceController from erp5.component.interface.IDivergenceController import IDivergenceController
...@@ -75,29 +72,6 @@ class DeliveryLine(Movement, XMLMatrix, ImmobilisationMovement): ...@@ -75,29 +72,6 @@ class DeliveryLine(Movement, XMLMatrix, ImmobilisationMovement):
# Multiple inheritance definition # Multiple inheritance definition
updateRelatedContent = XMLMatrix.updateRelatedContent updateRelatedContent = XMLMatrix.updateRelatedContent
# Force in _edit to modify variation_base_category_list first
def _edit(self, edit_order=(), **kw):
# XXX FIXME For now, special cases are handled in _edit methods in many
# documents : DeliveryLine, DeliveryCell ... Ideally, to prevent code
# duplication, it should be handled in a _edit method present only in
# Amount.py
# If variations and resources are set at the same time, resource must be
# set before any variation.
before_order = ('resource', 'resource_value',
'variation_base_category_list',
'variation_category_list')
before_kw = {k: kw.pop(k) for k in before_order if k in kw}
if before_kw:
before_kw.update((k, kw[k]) for k in edit_args_list if k in kw)
Base._edit(self, edit_order=before_order, **before_kw)
if kw:
Movement._edit(self, edit_order=edit_order, **kw)
# We must check if the user has changed the resource of particular line
security.declareProtected( Permissions.ModifyPortalContent, 'edit' )
def edit(self, REQUEST=None, force_update = 0, reindex_object=1, **kw):
return self._edit(REQUEST=REQUEST, force_update=force_update, reindex_object=reindex_object, **kw)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'isAccountable') 'isAccountable')
......
...@@ -73,7 +73,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -73,7 +73,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
to define quantities in orders to define quantities in orders
- Deliveries: movements track the actual transfer of resources - Deliveries: movements track the actual transfer of resources
in the past (accounting) or in the future (planning / budgetting) in the past (accounting) or in the future (planning / budgeting)
For example, the following objects are Orders: For example, the following objects are Orders:
...@@ -217,8 +217,13 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -217,8 +217,13 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
, PropertySheet.Movement , PropertySheet.Movement
, PropertySheet.Price , PropertySheet.Price
, PropertySheet.Simulation # XXX-JPS property should be moved to GeneratedMovement class , PropertySheet.Simulation # XXX-JPS property should be moved to GeneratedMovement class
) )
_default_edit_order = Amount._default_edit_order + (
'stop_date',
'start_date',
)
def isPropertyRecorded(self, k): # XXX-JPS method should be moved to GeneratedMovement class def isPropertyRecorded(self, k): # XXX-JPS method should be moved to GeneratedMovement class
return False return False
...@@ -726,9 +731,6 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -726,9 +731,6 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
def _edit(self, edit_order=(), **kw): def _edit(self, edit_order=(), **kw):
"""Overloaded _edit to support setting debit and credit at the same time, """Overloaded _edit to support setting debit and credit at the same time,
which is required for the GUI. which is required for the GUI.
Also sets the variation category list and property dict at the end, because
_setVariationCategoryList and _setVariationPropertyDict needs the resource
to be set.
""" """
quantity = 0 quantity = 0
if 'source_debit' in kw and 'source_credit' in kw: if 'source_debit' in kw and 'source_credit' in kw:
...@@ -757,9 +759,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -757,9 +759,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
if kw.get('destination_asset_credit') in (None, ''): if kw.get('destination_asset_credit') in (None, ''):
kw.pop('destination_asset_credit', None) kw.pop('destination_asset_credit', None)
if not edit_order: return super(Movement, self)._edit(edit_order=edit_order, **kw)
edit_order = ('variation_category_list', 'variation_property_dict', 'quantity_unit',)
return XMLObject._edit(self, edit_order=edit_order, **kw)
# Debit and credit methods for asset # Debit and credit methods for asset
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
......
...@@ -59,6 +59,11 @@ class VariatedMixin: ...@@ -59,6 +59,11 @@ class VariatedMixin:
isRADContent = 1 # for 'property_sheets' isRADContent = 1 # for 'property_sheets'
property_sheets = (PropertySheet.VariationRange, ) property_sheets = (PropertySheet.VariationRange, )
_default_edit_order = (
'variation_base_category_list',
'variation_category_list',
)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getVariationBaseCategoryList') 'getVariationBaseCategoryList')
def getVariationBaseCategoryList(self, omit_optional_variation=0, def getVariationBaseCategoryList(self, omit_optional_variation=0,
......
...@@ -222,6 +222,8 @@ class WorkflowMethod(Method): ...@@ -222,6 +222,8 @@ class WorkflowMethod(Method):
# Otherwise, an exception is raised if the workflow transition does not # Otherwise, an exception is raised if the workflow transition does not
# exist from the current state, or if the guard rejects it. # exist from the current state, or if the guard rejects it.
valid_transition_item_list = [] valid_transition_item_list = []
# XXX sort ?
# for wf_id, transition_list in sorted(candidate_transition_item_list):
for wf_id, transition_list in candidate_transition_item_list: for wf_id, transition_list in candidate_transition_item_list:
candidate_workflow = wf[wf_id] candidate_workflow = wf[wf_id]
valid_list = [] valid_list = []
...@@ -779,6 +781,8 @@ class Base( ...@@ -779,6 +781,8 @@ class Base(
# Declarative properties # Declarative properties
property_sheets = ( PropertySheet.Base, ) property_sheets = ( PropertySheet.Base, )
_default_edit_order = ()
# We want to use a default property view # We want to use a default property view
manage_main = manage_propertiesForm = DTMLFile( 'properties', _dtmldir ) manage_main = manage_propertiesForm = DTMLFile( 'properties', _dtmldir )
manage_main._setName('manage_main') manage_main._setName('manage_main')
...@@ -1478,7 +1482,7 @@ class Base( ...@@ -1478,7 +1482,7 @@ class Base(
# Object attributes update method # Object attributes update method
def _edit(self, REQUEST=None, force_update=0, reindex_object=0, def _edit(self, REQUEST=None, force_update=0, reindex_object=0,
keep_existing=0, activate_kw=None, edit_order=[], restricted=0, **kw): keep_existing=0, activate_kw=None, edit_order=(), restricted=0, **kw):
""" """
Generic edit Method for all ERP5 object Generic edit Method for all ERP5 object
The purpose of this method is to update attributed, eventually do The purpose of this method is to update attributed, eventually do
...@@ -1496,6 +1500,7 @@ class Base( ...@@ -1496,6 +1500,7 @@ class Base(
""" """
if not kw: if not kw:
return return
edit_order = edit_order or self._default_edit_order
key_list = kw.keys() key_list = kw.keys()
modified_property_dict = self._v_modified_property_dict = {} modified_property_dict = self._v_modified_property_dict = {}
modified_object_dict = {} modified_object_dict = {}
...@@ -1556,6 +1561,8 @@ class Base( ...@@ -1556,6 +1561,8 @@ class Base(
self.setId(kw['id'], reindex=reindex_object) self.setId(kw['id'], reindex=reindex_object)
return not_modified_list return not_modified_list
# XXX sort ??
#unmodified_key_list = setChangedPropertyList(sorted(unordered_key_list))
unmodified_key_list = setChangedPropertyList(unordered_key_list) unmodified_key_list = setChangedPropertyList(unordered_key_list)
setChangedPropertyList(unmodified_key_list) setChangedPropertyList(unmodified_key_list)
# edit_order MUST be enforced, and done at the complete end # edit_order MUST be enforced, and done at the complete end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment