# -*- coding: utf-8 -*- ############################################################################# # # Copyright (c) 2009 Nexedi KK and Contributors. All Rights Reserved. # Yusei TAHARA <yusei@nexedi.com> # # 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. # ############################################################################## import zope.interface from AccessControl import ClassSecurityInfo from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5.interfaces.rounding_tool import IRoundingTool from decimal import (ROUND_DOWN, ROUND_UP, ROUND_CEILING, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP) ROUNDING_OPTION_DICT = {'ROUND_DOWN':ROUND_DOWN, 'ROUND_UP':ROUND_UP, 'ROUND_CEILING':ROUND_CEILING, 'ROUND_FLOOR':ROUND_FLOOR, 'ROUND_HALF_DOWN':ROUND_HALF_DOWN, 'ROUND_HALF_EVEN':ROUND_HALF_EVEN, 'ROUND_HALF_UP':ROUND_HALF_UP} class RoundingTool(BaseTool): """Rounding Tool""" id = 'portal_roundings' title = 'Rounding Tool' meta_type = 'ERP5 Rounding Tool' portal_type = 'Rounding Tool' zope.interface.implements(IRoundingTool) security = ClassSecurityInfo() security.declarePublic('findRoundingModel') def findRoundingModelValueList(self, document, property_id=None, context=None): """ Return a list of matched rounding models for `document` which is ordered by increasing distance from `context`. """ portal = self.getPortalObject() parent_uid_list = [portal.portal_roundings.getUid()] kw = {} if context is not None: current_document = context while True: if (current_document is None or current_document is portal or not current_document.getUid() or current_document.getUid() in parent_uid_list): break else: parent_uid_list.append(current_document.getUid()) current_document = current_document.aq_parent def sortMethod(document_a, document_b): def score(document): context_path = context.getPhysicalPath() result = len(context_path) for a, b in zip(context_path, document.getPhysicalPath()): if a==b: result -= 1 else: break return result return cmp(score(document_a), score(document_b)) kw['sort_method'] = sortMethod result = portal.portal_domains.searchPredicateList( context=document, parent_uid=parent_uid_list, portal_type='Rounding Model', validation_state='validated', **kw) if property_id is not None: for rounding_model in result: if property_id in rounding_model.getRoundedPropertyIdList(): return [rounding_model] return result security.declarePublic('getRoundingProxy') def getRoundingProxy(self, document, context=None): """ Return a rounding proxy object which getter methods returns rounded value by following matched rounding model definition. """ target_object = document for rounding_model in self.findRoundingModelValueList(document, context=context): target_object = rounding_model.getRoundingProxy(target_object) return target_object security.declarePublic('getDecimalRoundingOptionList') def getDecimalRoundingOptionItemList(self): """ Return the possible decimal rounding option item list which is provided by python standard decimal module. """ return ROUNDING_OPTION_DICT.items()