• Arnaud Fontaine's avatar
    py2/py3: Make Products code compatible with both python2 and python3. · a17bb910
    Arnaud Fontaine authored
    Done through various 2to3 fixers (zope.fixers, modernize, future) and manual
    changes. This is a single commit so that we have a clearer picture of how code
    converted with my2to3 should look like.
    
    Except straightforward @implementer decorator 2to3 fixer, only product/ folder
    was considered as the goal was to be able to create an ERP5Site.
    
    * Use @implementer decorator introduced in zope.interface 3.6.0 (2010):
    
      The implements syntax used under Python 2.X does not work under 3.X, since it
      depends on how metaclasses are implemented and this has changed. Instead it
      now supports a decorator syntax (also under Python 2.X).
    
      Applied thanks to 2to3 `zope.fixers` package.
    
    * Use `six.moves` rather than `future` install_aliases() feature because the
      latter use unicode_literals and "wraps" module aliases so that unicode() are
      returned for text rather than str() (Python2 standard library). This notably
      breaks BusinessTemplate code which uses urllib quote() for filesystem paths...
    
    * No more unbound methods in python3 so use six.get_unbound_function().
    
    * dict.(iteritems,iterkeys,itervalues)() => six.\1(dict) thanks to `dict_six`
      2to3 fixer from `modernize`:
      $ python-modernize -w -f dict_six product/
    
    * Manually make sure that dict.{items,values,keys}() returns a real list when it
      is latter modified rather than a dict_{items,values,keys} (ensure_list()). By
      default, 2to3 blindly does list(dict.{items,values,keys}()) which is not
      acceptable from performances point of view. With my2to3, this will be possible
      to handle such case automatically.
    
    * Replace cStringIO.StringIO() by six.moves.cStringIO() (a module alias for
      cStringIO.StringIO() on py2 and io.StringIO() on py3).
    
    * Use six.text_type which maps to unicode() on py2 and str() on py3. This also
      makes a clearer difference between text and binary strings.
    
    * Replace map()/filter() with lambda function by list comprehension (this has
      the benefit to avoid casting to list for py3 as it returns iterators).
    a17bb910
document.erp5.LIFODeliverySolver.py 2.79 KB
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 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 AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from erp5.component.document.FIFODeliverySolver import FIFODeliverySolver
from erp5.component.interface.IDeliverySolver import IDeliverySolver

@zope.interface.implementer(IDeliverySolver,)
class LIFODeliverySolver(FIFODeliverySolver):
  """
  The LIFO solver reduces delivered quantity by reducing the quantity of
  simulation movements from the first order.
  """
  meta_type = 'ERP5 LIFO Delivery Solver'
  portal_type = 'LIFO Delivery Solver'
  add_permission = Permissions.AddPortalContent
  isIndexable = 0 # We do not want to fill the catalog with objects on which we need no reporting

  # Declarative security
  security = ClassSecurityInfo()
  security.declareObjectProtected(Permissions.AccessContentsInformation)

  # Default Properties
  property_sheets = ( PropertySheet.Base
                    , PropertySheet.XMLObject
                    , PropertySheet.CategoryCore
                    , PropertySheet.DublinCore
                    , PropertySheet.DeliverySolver
                    )

  def _getSimulationMovementList(self):
    """
    Returns a list of simulation movement sorted from the first order.
    """
    simulation_movement_list = self.getDeliveryValueList()
    if len(simulation_movement_list) > 1:
      return sorted(simulation_movement_list,
        key=lambda x:x.getExplanationValue().getStartDate())
    else:
      return simulation_movement_list