DuplicateInventory.py 5.39 KB
Newer Older
1 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
##############################################################################
#
# Copyright (c) 2002-2007 Nexedi SARL and Contributors. All Rights Reserved.
#
# 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 Products.ERP5Type.Constraint import Constraint
from zLOG import LOG

class DuplicateInventory(Constraint):
32 33 34 35 36 37 38 39
  """
    We want to check here that there is not 2 or more inventories with:
    - the same resource
    - the same date
    - the same node
  """

  def generateDuplicateError(self, portal, obj, resource, variation_text):
40
    """
41
      Use a single method in order to generate the message
42
    """
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    resource_value = portal.restrictedTraverse(resource)
    resource_title = resource_value.getTitle()
    variation_description = ''
    variation_title = ''
    if len(variation_text) > 0:
      variation_title_list = []
      for variation in variation_text.split('\n'):
        variation_value = portal.portal_categories\
                                 .getCategoryValue(variation)
        variation_title_list.append(variation_value.getTitle())
      variation_title = ("(%s)" % ''.join(variation_title_list))
      variation_description = "and variation $variation_title "
    error_message = "%s%s%s" % \
        ("There is already an inventory for $resource_title ",
         variation_description, "on this node and date")
    return self._generateError(obj, error_message,
        mapping={'variation_title' : variation_title,
                 'resource_title' : resource_title})
61

62 63 64 65 66 67
  def checkConsistency(self, obj, fixit = 0):
    """
      Implement here the consistency checker
      whenever fixit is not 0, object data should be updated to 
      satisfy the constraint
    """
68

69
    errors = []
70

71 72 73 74 75 76 77 78
    inventory = obj
    node = inventory.getDestination()
    node_value = inventory.getDestinationValue()
    # Make sure to raise conflict error when two inventories are
    # validated in the same time for the same node, this is the only
    # way to make sure that it is impossible to validate two inventories
    # in the same time (required because we have message with right tags
    # only when the transaction is finished)
Sebastien Robin's avatar
Sebastien Robin committed
79 80
    if node_value is not None:
      node_value.serialize()
81

Sebastien Robin's avatar
Sebastien Robin committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
      # For each resource, we look that there is not any inventory for
      # the same date, the same resource and the same node, or if there
      # is already such kind of inventories being indexed
      resource_and_variation_list = []
      date = inventory.getStartDate()
      date_string = repr(date)
      countMessageWithTag = inventory.portal_activities.countMessageWithTag
      portal = inventory.getPortalObject()
      getObjectFromUid = portal.portal_catalog.getObject
      getCurrentInventoryList = portal.portal_simulation.getCurrentInventoryList
      resource_and_variation_list = []
      for movement in inventory.getMovementList():
        resource =  movement.getResource()
        if resource is not None and movement.getQuantity() not in (None,''):
          variation_text = movement.getVariationText()
          if (resource,variation_text) not in resource_and_variation_list:
            resource_and_variation_list.append((resource,variation_text))
            tag = '%s_%s_%s' % (date_string, resource, variation_text)
            if countMessageWithTag(tag) > 0 :
101
              errors.append(self.generateDuplicateError(portal, obj, resource,
Sebastien Robin's avatar
Sebastien Robin committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
                                    variation_text))
            # Call sql request in order to see if there is another inventory
            # for this node, resource, variation_text and date
            inventory_list = getCurrentInventoryList(resource=resource,
                                     variation_text=variation_text,
                                     from_date=date, at_date=date,
                                     default_stock_table='inventory_stock',
                                     node=node)
            for inventory in inventory_list:
              movement = getObjectFromUid(inventory.stock_uid)
              if movement.getPortalType().find('Inventory') >= 0:
                errors.append(self.generateDuplicateError(portal, obj, resource,
                                    variation_text))
          # Now we must reindex with some particular tags
          activate_kw = {'tag': tag}
          movement.reindexObject(activate_kw=activate_kw)
118 119
    
    return errors