SimulationLegacyPatches.py 4.73 KB
Newer Older
1
import warnings
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
from Products.ERP5.mixin import composition
from Products.ERP5.ERP5Site import ERP5Site

def patch():
  from AccessControl.PermissionRole import PermissionRole
  from Products.ERP5Type import Permissions
  def declareProtected(cls, permission, *name_list):
    roles = PermissionRole(permission)
    for name in name_list:
      setattr(cls, name + '__roles__', roles)

  ## ERP5Site

  declareProtected(ERP5Site, Permissions.AccessContentsInformation,
                   'getPortalBusinessStateTypeList',
                   'getPortalBusinessPathTypeList')

  def getPortalBusinessStateTypeList(self):
    """
      Return business state types.
    """
    return ('Business State',)

  ERP5Site.getPortalBusinessStateTypeList = getPortalBusinessStateTypeList

  def getPortalBusinessPathTypeList(self):
    """
      Return business path types.
    """
    return ('Business Path',)

  ERP5Site.getPortalBusinessPathTypeList = getPortalBusinessPathTypeList

  ## CompositionMixin

  composition._LEGACY_SIMULATION = True

Julien Muchembled's avatar
Julien Muchembled committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
  ## Movement

  from Products.ERP5.Document.Movement import Movement

  def isFrozen(self):
    """
    Returns the frozen status of this movement.
    a movement in stopped, delivered or cancelled states is automatically frozen.
    If frozen is locally set to '0', we must check for a parent set to '1', in
    which case, we want the children to be frozen as well.

    BPM evaluation allows to set frozen state list per Business Path.
    """
    business_path = self.getCausalityValue(portal_type='Business Path')
    if business_path is None:
      # XXX Hardcoded
      # Maybe, we should use getPortalCurrentInventoryStateList
      # and another portal method for cancelled (and deleted)
      #     LOG("Movement, isFrozen", DEBUG, "Hardcoded state list")
      if self.getSimulationState() in ('stopped', 'delivered', 'cancelled'):
        return 1
    else:
      # conditional BPM enabled frozen state check
      # BPM dynamic configuration
      if self.getSimulationState() in business_path.getFrozenStateList():
        return True

    # manually frozen
    frozen = self._baseIsFrozen()
    if frozen == 0:
      self._baseSetFrozen(None)
    return frozen or False

  Movement.isFrozen = isFrozen

74 75
  ## SimulationMovement

Julien Muchembled's avatar
Julien Muchembled committed
76
  from Products.ERP5.Document.SimulationMovement import SimulationMovement
77 78 79 80
  try:
    del SimulationMovement.isFrozen
  except AttributeError:
    pass
Julien Muchembled's avatar
Julien Muchembled committed
81 82 83 84 85 86 87 88 89

  def isCompleted(self):
    """Zope publisher docstring. Documentation in ISimulationMovement"""
    # only available in BPM, so fail totally in case of working without BPM
    return self.getSimulationState() in self.getCausalityValue(
        portal_type='Business Path').getCompletedStateList()

  SimulationMovement.isCompleted = isCompleted

90 91 92 93 94 95 96 97 98 99 100 101 102 103
  def asComposedDocument(self, *args, **kw):
    # XXX: What delivery should be used to find amount generator lines ?
    #      With the currently enabled code, entire branches in the simulation
    #      tree get (temporary) deleted when new delivery lines are being built
    #      (and don't have yet a specialise value).
    #      With the commented code, changing the STC on a SIT generated from a
    #      SPL/SO would have no impact (and would never make the SIT divergent).
    #return self.getRootSimulationMovement() \
    #           .getDeliveryValue() \
    #           .asComposedDocument(*args, **kw)
    while 1:
      delivery_value = self.getDeliveryValue()
      if delivery_value is not None:
        return delivery_value.asComposedDocument(*args, **kw)
Julien Muchembled's avatar
Julien Muchembled committed
104 105 106 107 108
      # below code is for compatibility with old rules
      grand_parent = self.getParentValue().getParentValue()
      if grand_parent.getPortalType() == 'Simulation Tool':
        return self.getOrderValue().asComposedDocument(*args, **kw)
      self = grand_parent
109 110 111

  SimulationMovement.asComposedDocument = asComposedDocument

Julien Muchembled's avatar
Julien Muchembled committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
  def isBuildable(self):
    """Simulation Movement buildable logic"""
    if self.getDeliveryValue() is not None:
      # already delivered
      return False

    # might be buildable - business path dependent
    business_path = self.getCausalityValue(portal_type='Business Path')
    explanation_value = self.getExplanationValue()
    if business_path is None or explanation_value is None:
      return True

    return len(business_path.filterBuildableMovementList([self])) == 1

  SimulationMovement.isBuildable = isBuildable

128 129
  def _asSuccessorContext(self):
    """ Legacy SimulationMovement doesn't try to look up successor trade phases
130
    """
131
    return self
132

133 134 135 136 137 138 139 140
  SimulationMovement._asSuccessorContext = _asSuccessorContext

  def _checkSuccessorContext(self):
    """ Legacy SimulationMovement doesn't try to look up successor trade phases
    """
    pass

  SimulationMovement._checkSuccessorContext = _checkSuccessorContext
141

142
patch()