# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved. # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsibility 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 # guarantees 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################## import zope.interface from Products.ERP5Type import interfaces from Products.ERP5Type.Accessor.TypeDefinition import list_types class MovementCollectionDiff(object): """ Documents which implement IMovementCollectionDiff are used to represent the movements which should be added, updated or deleted in an IMovementCollection. They are usually generated and used by IMovementCollectionUpdater. """ # Declarative interfaces zope.interface.implements(interfaces.IMovementCollectionDiff,) def __init__(self): self._deletable_movement_list = [] self._new_movement_list = [] self._updatable_movement_list = [] self._property_dict_dict = {} def getDeletableMovementList(self): """ Returns the list of movements which need to be deleted. """ return self._deletable_movement_list def addDeletableMovement(self, movement): """ Add a deletable movement to the diff definition """ self._deletable_movement_list.append(movement) def getNewMovementList(self): """ Returns a list temp movements which represent new movements to add to an existing IMovementCollection. """ return self._new_movement_list def addNewMovement(self, movement): """ Add a new movement to the diff definition """ self._new_movement_list.append(movement) def getUpdatableMovementList(self): """ Returns the list of movements which need to be updated. """ return self._updatable_movement_list def getMovementPropertyDict(self, movement): """ Returns a dict of all properties and values to update an existing movement or to create a new movement. """ property_dict = self._property_dict.get(movement) if property_dict is None: # movement should be 'New Movement' return self._getPropertyAndCategoryList(movement) else: return property_dict def addUpdatableMovement(self, movement, property_dict): """ Add an updatable movement to the diff definition property_dict -- properties to update """ self._updatable_movement_list.append(movement) self._property_dict[movement] = property_dict def _getPropertyAndCategoryList(self, movement): """ Returns a dict that includes all property values, based on property sheet configuration and all category values. """ property_map = movement.getPropertyMap() bad_property_list = ['id', 'uid', 'categories_list', 'int_index'] # we don't want acquired properties without acquisition_mask_value for x in property_map: if x.has_key('acquisition_base_category') and not x.get('acquisition_mask_value', 0): bad_property_list.append(x['id']) default_value_dict = dict([(x['id'], x.get('default', None)) \ for x in property_map]) getPropertyList = movement.getPropertyList getProperty = movement.getProperty getter_list_type_dict = { True:getPropertyList, False:getProperty } getter_dict = dict([(x['id'], getter_list_type_dict[x['type'] in list_types and not x['id'].endswith('_list')]) \ for x in property_map]) def filter_property_func(x): key, value = x if key in bad_property_list: return False default = default_value_dict[key] if value == default: return False if isinstance(value, (list, tuple)) and \ isinstance(default, (list, tuple)) and \ tuple(value) == tuple(default): return False return True property_dict = dict(filter(filter_property_func, [(x, getter_dict[x](x)) for x in \ movement.getPropertyIdList()])) def filter_category_func(x): return len(x[1]) != 0 property_dict.update(dict(filter(filter_category_func, [(x, getPropertyList(x)) for x in \ movement.getBaseCategoryList()]))) return property_dict