MovementGroup.py 11.7 KB
Newer Older
Sebastien Robin's avatar
Sebastien Robin committed
1 2 3 4
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
#                    Sebastien Robin <seb@nexedi.com>
Sebastien Robin's avatar
Sebastien Robin committed
5
#                    Yoshinori Okuji <yo@nexedi.com>
6
#                    Romain Courteaud <romain@nexedi.com>
Sebastien Robin's avatar
Sebastien Robin committed
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
#
# 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.
#
##############################################################################

"""
Define in this class all classes intended to group every kind of movement
"""

from AccessControl import ClassSecurityInfo
Sebastien Robin's avatar
Sebastien Robin committed
36 37
from Globals import InitializeClass, DTMLFile
from zLOG import LOG
38
from Products.PythonScripts.Utility import allow_class
Sebastien Robin's avatar
Sebastien Robin committed
39

40
class RootMovementGroup:
Sebastien Robin's avatar
Sebastien Robin committed
41

Sebastien Robin's avatar
Sebastien Robin committed
42 43 44
  def getNestedClass(self, class_list):
    if len(class_list)>0:
      return class_list[0]
Sebastien Robin's avatar
Sebastien Robin committed
45 46
    return None

Sebastien Robin's avatar
Sebastien Robin committed
47
  def setNestedClass(self,class_list=None):
Sebastien Robin's avatar
Sebastien Robin committed
48 49 50
    """
      This sets an appropriate nested class.
    """
51
    #LOG('RootGroup.setNestedClass, class_list:',0,class_list)
Sebastien Robin's avatar
Sebastien Robin committed
52
    for i in range(len(class_list)):
53
      #LOG('RootGroup.setNestedClass, class_list[i]:',0,class_list[i])
Sebastien Robin's avatar
Sebastien Robin committed
54
      #LOG('RootGroup.setNestedClass, class_list[i].getId():',0,class_list[i].getId())
55
      #LOG('RootGroup.setNestedClass, self.__class__:',0,self.__class__)
Sebastien Robin's avatar
Sebastien Robin committed
56
      if class_list[i] == self.__class__:
Sebastien Robin's avatar
Sebastien Robin committed
57 58 59 60
        break
    else:
      raise RuntimeError, "no appropriate nested class is found for %s" % str(self)

Sebastien Robin's avatar
Sebastien Robin committed
61
    self.nested_class = self.getNestedClass(class_list[i+1:])
Sebastien Robin's avatar
Sebastien Robin committed
62

Sebastien Robin's avatar
Sebastien Robin committed
63
  def __init__(self, movement=None,class_list=None):
Sebastien Robin's avatar
Sebastien Robin committed
64
    self.nested_class = None
Sebastien Robin's avatar
Sebastien Robin committed
65 66
    class_list = [RootMovementGroup] + list(class_list)
    self.setNestedClass(class_list=class_list)
67
    self._movement_list = []
Sebastien Robin's avatar
Sebastien Robin committed
68 69
    self.group_list = []
    if movement is not None :
Sebastien Robin's avatar
Sebastien Robin committed
70
      self.append(movement,class_list=class_list)
Sebastien Robin's avatar
Sebastien Robin committed
71

72 73 74
  def getGroupList(self):
    return self.group_list

Sebastien Robin's avatar
Sebastien Robin committed
75
  def appendGroup(self, movement,class_list=None):
Sebastien Robin's avatar
Sebastien Robin committed
76
    if self.nested_class is not None:
77
      #LOG('RootGroup.appendGroup, class_list',0,class_list)
Sebastien Robin's avatar
Sebastien Robin committed
78
      nested_instance = self.nested_class(movement=movement,class_list=class_list)
Sebastien Robin's avatar
Sebastien Robin committed
79
      self.group_list.append(nested_instance)
Sebastien Robin's avatar
Sebastien Robin committed
80

Sebastien Robin's avatar
Sebastien Robin committed
81
  def append(self,movement,class_list=None):
82
    self._movement_list.append(movement)
Sebastien Robin's avatar
Sebastien Robin committed
83 84 85
    movement_in_group = 0
    for group in self.group_list :
      if group.test(movement) :
Sebastien Robin's avatar
Sebastien Robin committed
86
        group.append(movement,class_list=class_list)
Sebastien Robin's avatar
Sebastien Robin committed
87 88 89
        movement_in_group = 1
        break
    if movement_in_group == 0 :
90
      #LOG('RootGroup.append, class_list',0,class_list)
Sebastien Robin's avatar
Sebastien Robin committed
91
      self.appendGroup(movement,class_list=class_list)
Sebastien Robin's avatar
Sebastien Robin committed
92

93 94 95 96 97
  def setGroupEdit(self, **kw):
    """
      Store properties for the futur created object 
    """
    self._property_dict = kw
Sebastien Robin's avatar
Sebastien Robin committed
98

99 100 101 102 103 104 105 106 107 108 109 110 111 112
  def getGroupEditDict(self):
    """
      Get property dict for the futur created object 
    """
    if hasattr(self, '_property_dict'):
      return self._property_dict
    else:
      return {}

  def getMovementList(self):
    """
      Return movement list in the current group
    """
    return self._movement_list
Sebastien Robin's avatar
Sebastien Robin committed
113 114


115 116 117
allow_class(RootMovementGroup)

class OrderMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
118
  def __init__(self,movement,**kw):
119
    #LOG('OrderMovementGroup.__init__, kw:',0,kw)
Sebastien Robin's avatar
Sebastien Robin committed
120
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
121 122 123
    if hasattr(movement, 'getRootAppliedRule'):
      # This is a simulation movement
      order_value = movement.getRootAppliedRule().getCausalityValue(
124
                              portal_type=movement.getPortalOrderTypeList())
Sebastien Robin's avatar
Sebastien Robin committed
125 126 127 128
      if order_value is None:
        # In some cases (ex. DeliveryRule), there is no order
        # we may consider a PackingList as the order in the OrderGroup
        order_value = movement.getRootAppliedRule().getCausalityValue(
129
                        portal_type=movement.getPortalDeliveryTypeList())
Sebastien Robin's avatar
Sebastien Robin committed
130 131 132 133 134 135 136 137 138 139
    else:
      # This is a temp movement
      order_value = None
    if order_value is None:
      order_relative_url = None
    else:
      # get the id of the enclosing delivery
      # for this cell or line
      order_relative_url = order_value.getRelativeUrl()
    self.order = order_relative_url
140
    self.setGroupEdit(causality_value=order_value)
Sebastien Robin's avatar
Sebastien Robin committed
141 142 143 144

  def test(self,movement):
    if hasattr(movement, 'getRootAppliedRule'):
      order_value = movement.getRootAppliedRule().getCausalityValue(
145
                        portal_type=movement.getPortalOrderTypeList())
Sebastien Robin's avatar
Sebastien Robin committed
146 147 148 149 150

      if order_value is None:
        # In some cases (ex. DeliveryRule), there is no order
        # we may consider a PackingList as the order in the OrderGroup
        order_value = movement.getRootAppliedRule().getCausalityValue(
151
                        portal_type=movement.getPortalDeliveryTypeList())
Sebastien Robin's avatar
Sebastien Robin committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165
    else:
      # This is a temp movement
      order_value = None
    if order_value is None:
      order_relative_url = None
    else:
      # get the id of the enclosing delivery
      # for this cell or line
      order_relative_url = order_value.getRelativeUrl()
    if order_relative_url == self.order:
      return 1
    else :
      return 0

166
allow_class(OrderMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
167

168
class PathMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
169

Sebastien Robin's avatar
Sebastien Robin committed
170 171
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
172
    self.source = movement.getSource()
173
    #LOG('PathGroup.__init__ source',0,self.source)
Sebastien Robin's avatar
Sebastien Robin committed
174
    self.destination = movement.getDestination()
175
    #LOG('PathGroup.__init__ destination',0,self.destination)
Sebastien Robin's avatar
Sebastien Robin committed
176
    self.source_section = movement.getSourceSection()
177
    #LOG('PathGroup.__init__ source_section',0,self.source_section)
Sebastien Robin's avatar
Sebastien Robin committed
178
    self.destination_section = movement.getDestinationSection()
179
    #LOG('PathGroup.__init__ destination_section',0,self.destination_section)
180 181 182 183 184 185
    self.setGroupEdit(
        source_value=movement.getSourceValue(),
        destination_value=movement.getDestinationValue(),
        source_section_value=movement.getSourceSectionValue(),
        destination_section_value=movement.getDestinationSectionValue(),
    )
Sebastien Robin's avatar
Sebastien Robin committed
186 187 188 189 190 191


  def test(self,movement):
    if movement.getSource() == self.source and \
      movement.getDestination() == self.destination and \
      movement.getSourceSection() == self.source_section and \
192
      movement.getDestinationSection() == self.destination_section  :
Sebastien Robin's avatar
Sebastien Robin committed
193 194 195 196 197

      return 1
    else :
      return 0

198
allow_class(PathMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
199

200
class DateMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
201

Sebastien Robin's avatar
Sebastien Robin committed
202 203
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
204 205
    self.start_date = movement.getStartDate()
    self.stop_date = movement.getStopDate()
206 207 208 209
    self.setGroupEdit(
        start_date=movement.getStartDate(),
        stop_date=movement.getStopDate()
    )
Sebastien Robin's avatar
Sebastien Robin committed
210 211 212 213 214 215 216 217

  def test(self,movement):
    if movement.getStartDate() == self.start_date and \
      movement.getStopDate() == self.stop_date :
      return 1
    else :
      return 0

218
allow_class(DateMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
219

220
class CriterionMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
221

Sebastien Robin's avatar
Sebastien Robin committed
222 223
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
224 225 226 227 228 229 230 231 232 233 234 235 236
    if hasattr(movement, 'getGroupCriterion'):
      self.criterion = movement.getGroupCriterion()
    else:
      self.criterion = None

  def test(self,movement):
    # we must have the same criterion
    if hasattr(movement, 'getGroupCriterion'):
      criterion = movement.getGroupCriterion()
    else:
      criterion = None
    return self.criterion == criterion

237
allow_class(CriterionMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
238

239
class ResourceMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
240

Sebastien Robin's avatar
Sebastien Robin committed
241 242
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
243
    self.resource = movement.getResource()
244 245 246
    self.setGroupEdit(
        resource_value=self.resource
    )
Sebastien Robin's avatar
Sebastien Robin committed
247 248 249 250 251 252 253

  def test(self,movement):
    if movement.getResource() == self.resource :
      return 1
    else :
      return 0

254
allow_class(ResourceMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
255

256
class BaseVariantMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
257

Sebastien Robin's avatar
Sebastien Robin committed
258 259
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
260 261
    self.base_category_list = movement.getVariationBaseCategoryList()
    if self.base_category_list is None:
262
      #LOG('BaseVariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict())))
Sebastien Robin's avatar
Sebastien Robin committed
263 264 265 266 267 268 269 270
      self.base_category_list = []

  def test(self,movement):
    # we must have the same number of categories
    categories_identity = 0
    #LOG('BaseVariantGroup', 0, 'self.base_category_list = %s, movement = %s, movement.getVariationBaseCategoryList() = %s' % (repr(self.base_category_list), repr(movement), repr(movement.getVariationBaseCategoryList())))
    movement_base_category_list = movement.getVariationBaseCategoryList()
    if movement_base_category_list is None:
271
      #LOG('BaseVariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict())))
Sebastien Robin's avatar
Sebastien Robin committed
272 273 274 275 276 277 278 279 280
      movement_base_category_list = []
    if len(self.base_category_list) == len(movement_base_category_list):
      for category in movement_base_category_list:
        if not category in self.base_category_list :
          break
      else :
        categories_identity = 1
    return categories_identity

281
allow_class(BaseVariantMovementGroup)
Sebastien Robin's avatar
Sebastien Robin committed
282

283
class VariantMovementGroup(RootMovementGroup):
Sebastien Robin's avatar
Sebastien Robin committed
284

Sebastien Robin's avatar
Sebastien Robin committed
285 286
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Sebastien Robin's avatar
Sebastien Robin committed
287 288
    self.category_list = movement.getVariationCategoryList()
    if self.category_list is None:
289
      #LOG('VariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict())))
Sebastien Robin's avatar
Sebastien Robin committed
290
      self.category_list = []
291 292 293
    self.setGroupEdit(
        variation_category_list=self.category_list
    )
Sebastien Robin's avatar
Sebastien Robin committed
294 295 296 297 298 299

  def test(self,movement):
    # we must have the same number of categories
    categories_identity = 0
    movement_category_list = movement.getVariationCategoryList()
    if movement_category_list is None:
300
      #LOG('VariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict())))
Sebastien Robin's avatar
Sebastien Robin committed
301 302 303 304 305 306 307 308
      movement_category_list = []
    if len(self.category_list) == len(movement_category_list):
      for category in movement_category_list:
        if not category in self.category_list :
          break
      else :
        categories_identity = 1
    return categories_identity
Sebastien Robin's avatar
Sebastien Robin committed
309

310
allow_class(VariantMovementGroup)
311

Jean-Paul Smets's avatar
Jean-Paul Smets committed
312
from copy import copy
313

Jean-Paul Smets's avatar
Jean-Paul Smets committed
314 315 316 317 318
class CategoryMovementGroup(RootMovementGroup):  
  """
    This seems to be a useless class
  """
  
319 320
  def __init__(self,movement,**kw):
    RootMovementGroup.__init__(self,movement,**kw)
Jean-Paul Smets's avatar
Jean-Paul Smets committed
321
    self.category_list = list(movement.getCategoryList())
322 323
    if self.category_list is None:
      self.category_list = []
Jean-Paul Smets's avatar
Jean-Paul Smets committed
324
    self.category_list.sort()
325 326 327

  def test(self,movement):
    # we must have the same number of categories
Jean-Paul Smets's avatar
Jean-Paul Smets committed
328
    movement_category_list = list(movement.getCategoryList())
329 330
    if movement_category_list is None:
      movement_category_list = []
Jean-Paul Smets's avatar
Jean-Paul Smets committed
331 332 333 334
    movement_category_list.sort()
    if self.category_list == movement_category_list:
      return 1
    return 0
335 336

allow_class(CategoryMovementGroup)