def _createDeliveryCell(self, delivery_line, movement, activate_kw,
                          base_id, cell_key):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_cell = movement.getDeliveryValue()
    except AttributeError:
      old_cell = None
    if old_cell is None:
      # from scratch
      cell = delivery_line.newCell(base_id=base_id, \
               portal_type=self.getDeliveryCellPortalType(),
               activate_kw=activate_kw,*cell_key)
    else:
      # from duplicated original line
      cp = tryMethodCallWithTemporaryPermission(
        delivery_line, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery_line, old_cell.getId()), {}, CopyError)
      cell = delivery_line[cp['new_id']]

    return cell
  def _createDelivery(self, delivery_module, movement_list, activate_kw):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_delivery = self._searchUpByPortalType(
        movement_list[0].getDeliveryValue(),
        self.getDeliveryPortalType())
    except AttributeError:
      old_delivery = None
    if old_delivery is None:
      # from scratch
      delivery = super(SimulatedDeliveryBuilder, self)._createDelivery(
        delivery_module, movement_list, activate_kw)
      # Interactions will usually trigger reindexing of related SM when
      # simulation state changes. Disable them for this transaction
      # because we already do this in _setDeliveryMovementProperties
      delivery.updateSimulation(index_related=0)
    else:
      # from duplicated original delivery
      cp = tryMethodCallWithTemporaryPermission(
        delivery_module, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery_module, old_delivery.getId()), {}, CopyError)
      delivery = delivery_module[cp['new_id']]
      # delete non-split movements
      keep_id_list = [y.getDeliveryValue().getId() for y in movement_list]
      delete_id_list = [x.getId() for x in delivery.contentValues() \
                       if x.getId() not in keep_id_list]
      delivery.deleteContent(delete_id_list)

    return delivery
  def _createDeliveryLine(self, delivery, movement_list, activate_kw):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_delivery_line = self._searchUpByPortalType(
        movement_list[0].getDeliveryValue(),
        self.getDeliveryLinePortalType())
    except AttributeError:
      old_delivery_line = None
    if old_delivery_line is None:
      # from scratch
      delivery_line = delivery.newContent(
        portal_type=self.getDeliveryLinePortalType(),
        variation_category_list=[],
        activate_kw=activate_kw)
    else:
      # from duplicated original line
      cp = tryMethodCallWithTemporaryPermission(
        delivery, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery, old_delivery_line.getId()), {}, CopyError)
      delivery_line = delivery[cp['new_id']]
      # reset variation category list
      delivery_line.setVariationCategoryList([])
      # delete non-split movements
      keep_id_list = [y.getDeliveryValue().getId() for y in movement_list]
      delete_id_list = [x.getId() for x in delivery_line.contentValues() \
                       if x.getId() not in keep_id_list]
      delivery_line.deleteContent(delete_id_list)

    return delivery_line
  def _createDelivery(self, delivery_module, movement_list, activate_kw):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_delivery = self._searchUpByPortalType(
        movement_list[0].getDeliveryValue(),
        self.getDeliveryPortalType())
    except AttributeError:
      old_delivery = None
    if old_delivery is None:
      # from scratch
      new_delivery_id = str(delivery_module.generateNewId())
      delivery = super(SimulatedDeliveryBuilder, self)._createDelivery(
        delivery_module, movement_list, activate_kw)
    else:
      # from duplicated original delivery
      cp = tryMethodCallWithTemporaryPermission(
        delivery_module, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery_module, old_delivery.getId()), {}, CopyError)
      delivery = delivery_module[cp['new_id']]
      # delete non-split movements
      keep_id_list = [y.getDeliveryValue().getId() for y in movement_list]
      delete_id_list = [x.getId() for x in delivery.contentValues() \
                       if x.getId() not in keep_id_list]
      delivery.deleteContent(delete_id_list)

    return delivery
示例#5
0
  def _createDeliveryCell(self, delivery_line, movement, activate_kw,
                          base_id, cell_key):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_cell = movement.getDeliveryValue()
    except AttributeError:
      old_cell = None
    if old_cell is None:
      # from scratch
      cell = delivery_line.newCell(base_id=base_id, \
               portal_type=self.getDeliveryCellPortalType(),
               activate_kw=activate_kw,*cell_key)
    else:
      # from duplicated original line
      cp = tryMethodCallWithTemporaryPermission(
        delivery_line, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery_line, old_cell.getId()), {}, CopyError)
      cell = delivery_line[cp['new_id']]

    return cell
示例#6
0
  def _createDeliveryLine(self, delivery, movement_list, activate_kw):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_delivery_line = self._searchUpByPortalType(
        movement_list[0].getDeliveryValue(),
        self.getDeliveryLinePortalType())
    except AttributeError:
      old_delivery_line = None
    if old_delivery_line is None:
      # from scratch
      delivery_line = delivery.newContent(
        portal_type=self.getDeliveryLinePortalType(),
        variation_category_list=[],
        activate_kw=activate_kw)
    else:
      # from duplicated original line
      cp = tryMethodCallWithTemporaryPermission(
        delivery, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery, old_delivery_line.getId()), {}, CopyError)
      delivery_line = delivery[cp['new_id']]
      # reset variation category list
      delivery_line.setVariationCategoryList([])
      # delete non-split movements
      keep_id_list = [y.getDeliveryValue().getId() for y in movement_list]
      delete_id_list = [x.getId() for x in delivery_line.contentValues() \
                       if x.getId() not in keep_id_list]
      delivery_line.deleteContent(delete_id_list)

    return delivery_line
示例#7
0
  def _createDelivery(self, delivery_module, movement_list, activate_kw):
    """
      Refer to the docstring in GeneratedDeliveryBuilder.
      Unlike GeneratedDeliveryBuilder, SimulatedDeliveryBuilder needs to respect
      existing relationship.
    """
    try:
      old_delivery = self._searchUpByPortalType(
        movement_list[0].getDeliveryValue(),
        self.getDeliveryPortalType())
    except AttributeError:
      old_delivery = None
    if old_delivery is None:
      # from scratch
      delivery = super(SimulatedDeliveryBuilder, self)._createDelivery(
        delivery_module, movement_list, activate_kw)
      # Interactions will usually trigger reindexing of related SM when
      # simulation state changes. Disable them for this transaction
      # because we already do this in _setDeliveryMovementProperties
      delivery.updateSimulation(index_related=0)
    else:
      # from duplicated original delivery
      cp = tryMethodCallWithTemporaryPermission(
        delivery_module, 'Copy or Move',
        lambda parent, *ids:
        parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
        (delivery_module, old_delivery.getId()), {}, CopyError)
      delivery = delivery_module[cp['new_id']]
      # delete non-split movements
      keep_id_list = [y.getDeliveryValue().getId() for y in movement_list]
      delete_id_list = [x.getId() for x in delivery.contentValues() \
                       if x.getId() not in keep_id_list]
      delivery.deleteContent(delete_id_list)

    return delivery
示例#8
0
  def _processDeliveryCellGroup(self, delivery_line, movement_group_node,
                                collect_order_list, movement_group_node_list=None,
                                update_existing_line=0,
                                divergence_list=None,
                                activate_kw=None, force_update=0):
    """
      Build delivery cell from a list of movement on a delivery line
      or complete delivery line
    """
    if movement_group_node_list is None:
      movement_group_node_list = []
    if divergence_list is None:
      divergence_list = []
    # do not use 'append' or '+=' because they are destructive.
    movement_group_node_list = movement_group_node_list + [movement_group_node]

    if len(collect_order_list):
      # Get sorted movement for each delivery line
      for grouped_node in movement_group_node.getGroupList():
        self._processDeliveryCellGroup(
          delivery_line,
          grouped_node,
          collect_order_list[1:],
          movement_group_node_list=movement_group_node_list,
          update_existing_line=update_existing_line,
          divergence_list=divergence_list,
          activate_kw=activate_kw,
          force_update=force_update)
    else:
      movement_list = movement_group_node.getMovementList()
      if len(movement_list) != 1:
        raise CollectError, "DeliveryBuilder: %s unable to distinct those\
              movements: %s" % (self.getId(), str(movement_list))
      else:
        # XXX Hardcoded value
        base_id = 'movement'
        object_to_update = None
        # We need to initialize the cell
        update_existing_movement = 0
        movement = movement_list[0]
        # decide if we create a cell or if we update the line
        # Decision can only be made with line matrix range:
        # because matrix range can be empty even if line variation category
        # list is not empty
        property_dict = {}
        if len(delivery_line.getCellKeyList(base_id=base_id)) == 0:
          # update line
          if update_existing_line == 1:
            if self._isUpdated(delivery_line, 'cell'):
              object_to_update_list = []
            else:
              object_to_update_list = [delivery_line]
          else:
            object_to_update_list = []
          object_to_update, property_dict = self._findUpdatableObject(
            object_to_update_list, movement_group_node_list,
            divergence_list)
          if object_to_update is not None:
            update_existing_movement = 1
          else:
            object_to_update = delivery_line
        else:
          object_to_update_list = [
            delivery_line.getCell(base_id=base_id, *cell_key) for cell_key in \
            delivery_line.getCellKeyList(base_id=base_id) \
            if delivery_line.hasCell(base_id=base_id, *cell_key)]
          object_to_update, property_dict = self._findUpdatableObject(
            object_to_update_list, movement_group_node_list,
            divergence_list)
          if object_to_update is not None:
            # We update a existing cell
            # delivery_ratio of new related movement to this cell
            # must be updated to 0.
            update_existing_movement = 1

        if object_to_update is None:
          # create a new cell
          cell_key = movement.getVariationCategoryList(
              omit_optional_variation=1)
          if not delivery_line.hasCell(base_id=base_id, *cell_key):
            try:
              old_cell = movement_group_node.getMovementList()[0].getDeliveryValue()
            except AttributeError:
              old_cell = None
            if old_cell is None:
              # from scratch
              cell = delivery_line.newCell(base_id=base_id, \
                       portal_type=self.getDeliveryCellPortalType(),
                       activate_kw=activate_kw,*cell_key)
            else:
              # from duplicated original line
              cp = tryMethodCallWithTemporaryPermission(
                delivery_line, 'Copy or Move',
                lambda parent, *ids:
                parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
                (delivery_line, old_cell.getId()), {}, CopyError)
              cell = delivery_line[cp['new_id']]

            vcl = movement.getVariationCategoryList()
            cell._edit(category_list=vcl,
                      # XXX hardcoded value
                      mapped_value_property_list=['quantity', 'price'],
                      membership_criterion_category_list=vcl,
                      membership_criterion_base_category_list=movement.\
                                             getVariationBaseCategoryList())
            object_to_update = cell
          else:
            raise MatrixError, 'Cell: %s already exists on %s' % \
                  (str(cell_key), str(delivery_line))
        self._setUpdated(object_to_update, 'cell')
        self._setDeliveryMovementProperties(
                            object_to_update, movement, property_dict,
                            update_existing_movement=update_existing_movement,
                            force_update=force_update, activate_kw=activate_kw)
示例#9
0
  def _processDeliveryLineGroup(self, delivery, movement_group_node,
                                collect_order_list, movement_group_node_list=None,
                                divergence_list=None,
                                activate_kw=None, force_update=0, **kw):
    """
      Build delivery line from a list of movement on a delivery
    """
    if movement_group_node_list is None:
      movement_group_node_list = []
    if divergence_list is None:
      divergence_list = []
    # do not use 'append' or '+=' because they are destructive.
    movement_group_node_list = movement_group_node_list + [movement_group_node]

    if len(collect_order_list) and not movement_group_node.getCurrentMovementGroup().isBranch():
      # Get sorted movement for each delivery line
      for grouped_node in movement_group_node.getGroupList():
        self._processDeliveryLineGroup(
          delivery,
          grouped_node,
          collect_order_list[1:],
          movement_group_node_list=movement_group_node_list,
          divergence_list=divergence_list,
          activate_kw=activate_kw,
          force_update=force_update)
    else:
      # Test if we can update an existing line, or if we need to create a new
      # one
      delivery_line_to_update_list = [x for x in delivery.contentValues(
        portal_type=self.getDeliveryLinePortalType()) if \
                                      not self._isUpdated(x, 'line')]
      delivery_line, property_dict = self._findUpdatableObject(
        delivery_line_to_update_list, movement_group_node_list,
        divergence_list)
      if delivery_line is not None:
        update_existing_line = 1
      else:
        # Create delivery line
        update_existing_line = 0
        try:
          old_delivery_line = self._searchUpByPortalType(
            movement_group_node.getMovementList()[0].getDeliveryValue(),
            self.getDeliveryLinePortalType())
        except AttributeError:
          old_delivery_line = None
        if old_delivery_line is None:
          # from scratch
          new_delivery_line_id = str(delivery.generateNewId())
          delivery_line = delivery.newContent(
            portal_type=self.getDeliveryLinePortalType(),
            id=new_delivery_line_id,
            variation_category_list=[],
            created_by_builder=1,
            activate_kw=activate_kw)
        else:
          # from duplicated original line
          cp = tryMethodCallWithTemporaryPermission(
            delivery, 'Copy or Move',
            lambda parent, *ids:
            parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
            (delivery, old_delivery_line.getId()), {}, CopyError)
          delivery_line = delivery[cp['new_id']]
          # reset variation category list
          delivery_line.setVariationCategoryList([])
          # delete non-split movements
          keep_id_list = [y.getDeliveryValue().getId() for y in \
                          movement_group_node.getMovementList()]
          delete_id_list = [x.getId() for x in delivery_line.contentValues() \
                           if x.getId() not in keep_id_list]
          delivery_line.deleteContent(delete_id_list)
      # Put properties on delivery line
      self._setUpdated(delivery_line, 'line')
      if property_dict:
        delivery_line.edit(**property_dict)

      if movement_group_node.getCurrentMovementGroup().isBranch():
        for grouped_node in movement_group_node.getGroupList():
          self._processDeliveryLineGroup(
            delivery_line,
            grouped_node,
            collect_order_list[1:],
            movement_group_node_list=movement_group_node_list,
            divergence_list=divergence_list,
            activate_kw=activate_kw,
            force_update=force_update)
        return

      # Update variation category list on line
      variation_category_dict = dict([(variation_category, True) for
                                      variation_category in
                                      delivery_line.getVariationCategoryList()])
      for movement in movement_group_node.getMovementList():
        for category in movement.getVariationCategoryList():
          variation_category_dict[category] = True
      variation_category_list = sorted(variation_category_dict.keys())
      delivery_line.setVariationCategoryList(variation_category_list)
      # Then, create delivery movement (delivery cell or complete delivery
      # line)
      grouped_node_list = movement_group_node.getGroupList()
      # If no group is defined for cell, we need to continue, in order to
      # save the quantity value
      if len(grouped_node_list):
        for grouped_node in grouped_node_list:
          self._processDeliveryCellGroup(
                                    delivery_line,
                                    grouped_node,
                                    self.getDeliveryCellMovementGroupList()[1:],
                                    update_existing_line=update_existing_line,
                                    divergence_list=divergence_list,
                                    activate_kw=activate_kw,
                                    force_update=force_update)
      else:
        self._processDeliveryCellGroup(
                                  delivery_line,
                                  movement_group_node,
                                  [],
                                  update_existing_line=update_existing_line,
                                  divergence_list=divergence_list,
                                  activate_kw=activate_kw,
                                  force_update=force_update)
示例#10
0
  def _processDeliveryGroup(self, delivery_module, movement_group_node,
                            collect_order_list, movement_group_node_list=None,
                            delivery_to_update_list=None,
                            divergence_list=None,
                            activate_kw=None, force_update=0, **kw):
    """
      Build delivery from a list of movement
    """
    if movement_group_node_list is None:
      movement_group_node_list = []
    if divergence_list is None:
      divergence_list = []
    # do not use 'append' or '+=' because they are destructive.
    movement_group_node_list = movement_group_node_list + [movement_group_node]
    # Parameter initialization
    if delivery_to_update_list is None:
      delivery_to_update_list = []
    delivery_list = []

    if len(collect_order_list):
      # Get sorted movement for each delivery
      for grouped_node in movement_group_node.getGroupList():
        new_delivery_list = self._processDeliveryGroup(
                              delivery_module,
                              grouped_node,
                              collect_order_list[1:],
                              movement_group_node_list=movement_group_node_list,
                              delivery_to_update_list=delivery_to_update_list,
                              divergence_list=divergence_list,
                              activate_kw=activate_kw,
                              force_update=force_update)
        delivery_list.extend(new_delivery_list)
        force_update = 0
    else:
      # Test if we can update a existing delivery, or if we need to create
      # a new one
      delivery_to_update_list = [
        x for x in delivery_to_update_list \
        if x.getPortalType() == self.getDeliveryPortalType() and \
        not self._isUpdated(x, 'delivery')]
      delivery, property_dict = self._findUpdatableObject(
        delivery_to_update_list, movement_group_node_list,
        divergence_list)

      # if all deliveries are rejected in case of update, we update the
      # first one.
      if force_update and delivery is None and len(delivery_to_update_list):
        delivery = delivery_to_update_list[0]

      if delivery is None:
        # Create delivery
        try:
          old_delivery = self._searchUpByPortalType(
            movement_group_node.getMovementList()[0].getDeliveryValue(),
            self.getDeliveryPortalType())
        except AttributeError:
          old_delivery = None
        if old_delivery is None:
          # from scratch
          new_delivery_id = str(delivery_module.generateNewId())
          delivery = delivery_module.newContent(
            portal_type=self.getDeliveryPortalType(),
            id=new_delivery_id,
            created_by_builder=1,
            activate_kw=activate_kw)
        else:
          # from duplicated original delivery
          cp = tryMethodCallWithTemporaryPermission(
            delivery_module, 'Copy or Move',
            lambda parent, *ids:
            parent._duplicate(parent.manage_copyObjects(ids=ids))[0],
            (delivery_module, old_delivery.getId()), {}, CopyError)
          delivery = delivery_module[cp['new_id']]
          # delete non-split movements
          keep_id_list = [y.getDeliveryValue().getId() for y in \
                          movement_group_node.getMovementList()]
          delete_id_list = [x.getId() for x in delivery.contentValues() \
                           if x.getId() not in keep_id_list]
          delivery.deleteContent(delete_id_list)
      # Put properties on delivery
      self._setUpdated(delivery, 'delivery')
      if property_dict:
        delivery.edit(**property_dict)

      # Then, create delivery line
      for grouped_node in movement_group_node.getGroupList():
        self._processDeliveryLineGroup(
                                delivery,
                                grouped_node,
                                self.getDeliveryLineMovementGroupList()[1:],
                                divergence_list=divergence_list,
                                activate_kw=activate_kw,
                                force_update=force_update)
      delivery_list.append(delivery)
    return delivery_list