diff --git a/product/ERP5/Document/ImmobilisationCell.py b/product/ERP5/Document/ImmobilisationCell.py
new file mode 100755
index 0000000000000000000000000000000000000000..f3848b5af756446e00c9294d836cecb17ca74d71
--- /dev/null
+++ b/product/ERP5/Document/ImmobilisationCell.py
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Guillaume Michon <guillaume@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.
+#
+##############################################################################
+
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+from Products.ERP5Type import Base, Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5.Core import MetaNode, MetaResource
+from Products.CMFCore.WorkflowCore import WorkflowMethod
+
+from Products.ERP5Type.XMLObject import XMLObject
+from Products.ERP5.Document.Amount import Amount
+from Products.ERP5.Document.Movement import Movement
+from Products.ERP5.Document.ImmobilisationMovement import ImmobilisationMovement
+
+from string import capitalize
+from zLOG import LOG
+
+class ImmobilisationCell(Movement, XMLObject, ImmobilisationMovement):
+  """
+  """
+  meta_type = 'ERP5 Immobilisation Cell'
+  portal_type = 'Immobilisation Cell'
+  add_permission = Permissions.AddPortalContent
+  isPortalContent = 1
+  isRADContent = 1
+  isMovement = 1
+  isAccountable = 0 # It should not be indexed in stock table
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  # Declarative interfaces
+  __implements__ = ( Interface.Variated, )
+
+  # Declarative properties
+  property_sheets = ( PropertySheet.Base
+                      , PropertySheet.XMLObject
+                      , PropertySheet.CategoryCore
+                      , PropertySheet.DublinCore
+                      , PropertySheet.Task
+                      , PropertySheet.Arrow
+                      , PropertySheet.Movement
+                      , PropertySheet.Delivery
+                      , PropertySheet.Reference
+                      , PropertySheet.Amount
+                      , PropertySheet.Price
+                      , PropertySheet.Amortisation
+                      )
+
diff --git a/product/ERP5/Document/ImmobilisationDelivery.py b/product/ERP5/Document/ImmobilisationDelivery.py
new file mode 100755
index 0000000000000000000000000000000000000000..be68082b1602bc6a96f54bc7e550116214eb71fd
--- /dev/null
+++ b/product/ERP5/Document/ImmobilisationDelivery.py
@@ -0,0 +1,174 @@
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Guillaume Michon        <guillaume.michon@e-asc.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.
+#
+##############################################################################
+
+from Globals import InitializeClass, PersistentMapping
+from AccessControl import ClassSecurityInfo
+
+from DateTime import DateTime
+from string import capitalize
+
+from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5Type.XMLObject import XMLObject
+from Products.ERP5Type.DateUtils import addToDate, getClosestDate, getIntervalBetweenDates 
+from Products.ERP5Type.DateUtils import getMonthAndDaysBetween, getRoundedMonthBetween
+from Products.ERP5Type.DateUtils import getMonthFraction, getYearFraction, getBissextilCompliantYearFraction
+from Products.ERP5Type.DateUtils import same_movement_interval, number_of_months_in_year, centis, millis
+from Products.ERP5.Document.Amount import Amount
+from Products.CMFCore.WorkflowCore import WorkflowMethod
+from Products.CMFCore.utils import getToolByName
+from Products.ERP5.Document.ImmobilisableItem import ImmobilisationValidityError
+
+
+from zLOG import LOG
+
+
+NEGLIGEABLE_PRICE = 10e-8
+
+class ImmobilisationDelivery(XMLObject):
+    """
+      An Immobilisation Delivery is an object whose role is to
+      contain delivery movements which can immobilise items.
+    """
+
+    meta_type = 'ERP5 Immobilisation Delivery'
+    portal_type = 'Immobilisation Delivery'
+    add_permission = Permissions.AddPortalContent
+    isPortalContent = 1
+    isRADContent = 1
+
+    # Declarative security
+    security = ClassSecurityInfo()
+    security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+    # Declarative properties
+    property_sheets = ( PropertySheet.Base
+                      , PropertySheet.XMLObject
+                      , PropertySheet.CategoryCore
+                      , PropertySheet.DublinCore
+                      , PropertySheet.Task
+                      , PropertySheet.Arrow
+                      , PropertySheet.Movement
+                      , PropertySheet.Delivery
+                      , PropertySheet.Reference
+                      )
+
+    def validate_immobilisation(self, **kw):
+      pass
+    def invalidate_immobilisation(self, **kw):
+      pass
+    def calculate_immobilisation_validity(self, **kw):
+      pass
+    
+    validate_immobilisation = WorkflowMethod(validate_immobilisation)
+    invalidate_immobilisation = WorkflowMethod(invalidate_immobilisation)
+    calculate_immobilisation_validity = WorkflowMethod(calculate_immobilisation_validity)
+    
+    security.declareProtected(Permissions.View, 'updateImmobilisationState')
+    def updateImmobilisationState(self,**kw):
+      """
+      This is often called as an activity, it will check if the
+      delivery is valid as an immobilisation movement, and if so
+      it will put the delivery in a valid state, if not valid in
+      an invalid state
+      """
+      if self.getImmobilisationState() == 'calculating':
+        try:
+          if self.isValidImmobilisationMovement(**kw):
+            self.validate_immobilisation()
+          else:
+            self.invalidate_immobilisation()
+        except ImmobilisationValidityError:
+          self.calculate_immobilisation_validity()
+
+    security.declareProtected(Permissions.View, 'getImmobilisationState')
+    def getImmobilisationState(self, id_only=1):
+      """
+      Returns the current state in immobilisation validity
+      """
+      portal_workflow = getToolByName(self, 'portal_workflow')
+      wf = portal_workflow.getWorkflowById('immobilisation_workflow')
+      return wf._getWorkflowStateOf(self, id_only=id_only)
+
+    security.declareProtected(Permissions.View, 'getImmobilisationMovementList')
+    def getImmobilisationMovementList(self, **kw):
+      """
+      Return regular movements + immobilisation movements like
+      Immobilisation Line and Immobilisation Cell
+      """
+      return self.getMovementList(self.getPortalMovementTypeList() +
+                 ('Immobilisation Line', 'Immobilisation Cell'), **kw)
+      
+    security.declareProtected(Permissions.View, 'checkImmobilisationConsistency')
+    def checkImmobilisationConsistency(self, *args, **kw):
+      """
+      Check the consistency about immobilisation values
+      """
+      return_list = []
+      for movement in self.getImmobilisationMovementList():
+        return_list.extend(movement.checkImmobilisationConsistency())
+      return return_list
+
+    security.declareProtected(Permissions.View, 'isValidImmobilisationMovement')
+    def isValidImmobilisationMovement(self, *args, **kw):
+      """
+      Return true if all submovements are valid in terms of immobilisation
+      """
+      error_list = self.checkImmobilisationConsistency(*args, **kw)
+      if len(error_list) == 0:
+        return 1
+      return 0
+
+    security.declareProtected(Permissions.View, 'isInvalidImmobilisationMovement')
+    def isInvalidImmobilisationMovement(self, *args, **kw):
+      """
+      Return false if all submovements are valid in terms of immobilisation
+      """
+      return not self.isValidImmobilisationMovement(*args, **kw)
+
+    security.declareProtected(Permissions.View, 'getAggregatedItemsNextImmobilisationMovementValueList')
+    def getAggregatedItemsNextImmobilisationMovementValueList(self, **kw):
+      """
+      Return the list of each next immobilisation movement for each aggregated item
+      """
+      returned_list = []
+      sub_movement_list = self.contentValues()
+      for movement in self.getImmobilisationMovementList(**kw):
+        for item in movement.getAggregateValueList():
+          future_movement_list = item.getFutureImmobilisationMovementValueList(
+                                     at_date = self.getStopDate(),
+                                     from_movement = self,
+                                     filter_valid = 0)
+          if future_movement_list is not None:
+            for next_movement in future_movement_list:
+              if next_movement is not None and \
+                 next_movement not in sub_movement_list and \
+                 next_movement not in returned_list and \
+                 next_movement.getStopDate() != self.getStopDate():
+                returned_list.append(next_movement)
+      return returned_list
+      
diff --git a/product/ERP5/Document/ImmobilisationLine.py b/product/ERP5/Document/ImmobilisationLine.py
new file mode 100755
index 0000000000000000000000000000000000000000..98960fb718d724d45bf6cfb78cd9bd6a0f657ebb
--- /dev/null
+++ b/product/ERP5/Document/ImmobilisationLine.py
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Guillaume Michon <guillaume@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.
+#
+##############################################################################
+
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+from Products.ERP5Type import Base, Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5.Core import MetaNode, MetaResource
+from Products.CMFCore.WorkflowCore import WorkflowMethod
+
+from Products.ERP5Type.XMLObject import XMLObject
+from Products.ERP5.Document.Amount import Amount
+from Products.ERP5.Document.Movement import Movement
+from Products.ERP5.Document.ImmobilisationMovement import ImmobilisationMovement
+from Products.ERP5.Document.DeliveryLine import DeliveryLine
+
+from string import capitalize
+from zLOG import LOG
+
+class ImmobilisationLine(Movement, XMLObject, ImmobilisationMovement, DeliveryLine):
+  """
+  """
+  meta_type = 'ERP5 Immobilisation Line'
+  portal_type = 'Immobilisation Line'
+  add_permission = Permissions.AddPortalContent
+  isPortalContent = 1
+  isRADContent = 1
+  isMovement = 1
+  isAccountable = 0 # It should not be indexed in stock table
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  # Declarative interfaces
+  __implements__ = ( Interface.Variated, )
+
+  # Declarative properties
+  property_sheets = ( PropertySheet.Base
+                      , PropertySheet.XMLObject
+                      , PropertySheet.CategoryCore
+                      , PropertySheet.DublinCore
+                      , PropertySheet.Task
+                      , PropertySheet.Arrow
+                      , PropertySheet.Movement
+                      , PropertySheet.Delivery
+                      , PropertySheet.Reference
+                      , PropertySheet.Amount
+                      , PropertySheet.Price
+                      , PropertySheet.Amortisation
+                      )
diff --git a/product/ERP5/Document/ImmobilisationMovement.py b/product/ERP5/Document/ImmobilisationMovement.py
new file mode 100755
index 0000000000000000000000000000000000000000..8bfb744f5ff973fcee9ddf9bf1fed8112980c79c
--- /dev/null
+++ b/product/ERP5/Document/ImmobilisationMovement.py
@@ -0,0 +1,372 @@
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Guillaume Michon <guillaume.michon@e-asc.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.
+#
+##############################################################################
+
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+from Products.ERP5Type import Base, Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5.Core import MetaNode, MetaResource
+from Products.CMFCore.WorkflowCore import WorkflowMethod
+
+from Products.ERP5Type.XMLObject import XMLObject
+from Products.ERP5.Document.Amount import Amount
+from Products.ERP5.Document.Movement import Movement
+from Products.ERP5Type.DateUtils import millis
+
+from string import capitalize
+from zLOG import LOG
+
+UNIMMOBILISING_METHOD = "unimmobilise"
+NO_CHANGE_METHOD = "no_change"
+AMORTISATION_METHOD_PREFIX = "erp5_accounting_"
+IMMOBILISATION_NEEDED_PROPERTY_LIST = [
+              ("date",   "stop_date",           "Date"),
+              ("method", "amortisation_method", "Amortisation Method"),
+             ]
+IMMOBILISATION_UNCONTINUOUS_NEEDED_PROPERTY_LIST = [
+              ("main_price",     "amortisation_start_price", "Immobilised Price"),
+              ("disposal_price", "disposal_price",           "Disposal Price"),
+              ("duration",       "amortisation_duration",    "Amortisation Duration"),
+              ("vat",            "immobilisation_vat",       "VAT"),
+              ("input_account",          "input_account",    "Input Account"),
+              ("output_account",         "output_account",   "Output Account"),
+              ("immobilisation_account", "immobilisation_account", "Immobilisation Account"),
+              ("amortisation_account",   "amortisation_account",   "Amortisation Account"),
+              ("depreciation_account",   "depreciation_account",   "Depreciation Account"),
+              ("vat_account",            "immobilisation_vat_account", "VAT Account"),
+              ("extra_cost_account",     "extra_cost_account",     "Extra Costs Account"),
+             ]
+IMMOBILISATION_FACULTATIVE_PROPERTY_LIST = [
+              ("monthly_amortisation_account", "monthly_amortisation_account", "Monthly Amortisation Account"),
+              ("extra_cost_price",    "extra_cost_price", "Extra Costs Price"),
+              ("durability", "durability", "Durability"),
+             ]
+                                       
+                                       
+
+class ImmobilisationMovement(Movement, XMLObject):
+  """
+    An ImmobilisationMovement is a generic object representing an immobilisation
+    and optional amortisation decision for any item. It holds information about
+    an accounting immobilisation (in order to amortise an object)
+  """
+  meta_type = 'ERP5 Immobilisation Movement'
+  portal_type = 'Immobilisation Movement'
+  add_permission = Permissions.AddPortalContent
+  isPortalContent = 1
+  isRADContent = 1
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  # Declarative interfaces
+  __implements__ = ( Interface.Variated, )
+
+  # Declarative properties
+  property_sheets = ( PropertySheet.Base
+                      , PropertySheet.XMLObject
+                      , PropertySheet.CategoryCore
+                      , PropertySheet.DublinCore
+                      , PropertySheet.Task
+                      , PropertySheet.Arrow
+                      , PropertySheet.Movement
+                      , PropertySheet.Delivery
+                      , PropertySheet.Reference
+                      , PropertySheet.Amount
+                      , PropertySheet.Price
+                      , PropertySheet.Amortisation
+                      )
+
+                      
+  def _checkImmobilisationConsistency(self, fixit=0, mapped_value_property_list=()):
+    relative_url = self.getRelativeUrl()
+    
+    def checkValuesAreNotNone(property_list):
+      errors = []
+      for key, value, name in property_list:
+        value = 'get' + ''.join(map(capitalize, value.split('_')))
+        value = getattr(self, value, None)
+        if value is not None:
+          value = value()
+        if key == 'method' and not value:
+          value = NO_CHANGE_METHOD
+        errors.extend(checkValue(variable=value,
+                                 forbidden_value_list=[None],
+                                 error_message=["Property value inconsistency", 0, "%s property is empty" % name]
+                                )
+                     )
+      return errors
+    
+    def checkValue(variable,
+                   forbidden_value_list=None,
+                   authorized_value_list=None,
+                   error_message=["Error Type", 0, "Error message"]):
+      if forbidden_value_list is not None:
+        if type(forbidden_value_list) != type([]):
+          forbidden_value_list = [forbidden_value_list]
+        if variable in forbidden_value_list:
+          return [ tuple([relative_url] + error_message) ]
+      if authorized_value_list is not None:
+        if type(authorized_value_list) != type([]):
+          authorized_value_list = [authorized_value_list]
+        if variable not in authorized_value_list:
+          return [ tuple([relative_url] + error_message) ]
+      return []
+      
+    errors = []
+    # Check absolutely needed values
+    method = self.getAmortisationMethod() or NO_CHANGE_METHOD
+    errors.extend(checkValuesAreNotNone(IMMOBILISATION_NEEDED_PROPERTY_LIST))
+    property_list = self.getNeededSpecificParameterListForItem(None)
+    errors.extend(checkValuesAreNotNone(property_list))
+
+    # Check if the date of this movement is unique
+    date_error = 0
+    for item in self.getAggregateValueList():
+      same_date_list = item.getUnfilteredImmobilisationMovementValueList(
+                     from_date = self.getStopDate(),
+                     to_date = self.getStopDate(),
+                     include_to_date = 1)
+      error_found = 0
+      for other_movement in same_date_list:
+        if other_movement != self and other_movement.getRootDeliveryValue().getImmobilisationState() == 'valid':
+          error_found = 1
+          date_error = 1
+      if error_found:
+        errors.append([self.getRelativeUrl(),
+                      "Property value inconsistency", 0,
+                      "An other movement already exists at the same date for item %s" % item.getRelativeUrl()])
+
+    # Return to avoid infinite loops in case of date errors
+    if date_error:
+      return errors
+
+    item_list = self.getAggregateValueList()
+    if len(item_list) == 0:
+      # No item aggregated, so the movement is considered as valid
+      #errors.append([self.getRelativeUrl(),
+      #               "Property value inconsistency", 0,
+      #               "No item aggregated"])
+      return errors
+    
+    # Check values needed if the amortisation method is not continuous
+    check_uncontinuous = 0
+    if self.getStopDate() is not None:
+      if method not in [None, "", NO_CHANGE_METHOD, UNIMMOBILISING_METHOD]:
+        continuous = self.getAmortisationMethodParameter("continuous")["continuous"]
+        if not continuous:
+          check_uncontinuous = 1
+        else:
+          # We need to check if the preceding movement is in the same period, and if it is valid
+          # This check must be done on each item
+          def checkPreviousMovementForItem(movement, item):
+            previous_movement = item.getLastImmobilisationMovementValue(at_date=movement.getStopDate())
+            if previous_movement is None:
+              return 0
+            if previous_movement.getImmobilisationState() == 'valid':
+              if previous_movement.getAmortisationMethod() not in ("", NO_CHANGE_METHOD):
+                return 1
+              return checkPreviousMovementForItem(previous_movement, item)
+            return checkPreviousMovementForItem(previous_movement, item)
+          for item in self.getAggregateValueList():
+            if not checkPreviousMovementForItem(self,item):
+              check_uncontinuous = 1
+            else:
+              # The last movement which is not a NO_CHANGE is valid
+              # Now check if the method is the same, then if the period is really continuing from previous movement
+              previous_movement = item.getLastImmobilisationMovementValue(at_date=self.getStopDate())
+              previous_movement_method = previous_movement.getActualAmortisationMethodForItem(item)
+              if previous_movement_method != method:
+                check_uncontinuous = 1
+                # If the previous method is the same, it means the previous movement did
+                # not stop the immobilisation, because stopping is a particular method
+    if check_uncontinuous:
+      errors.extend(checkValuesAreNotNone(IMMOBILISATION_UNCONTINUOUS_NEEDED_PROPERTY_LIST))
+      property_list = self.getUncontinuousNeededSpecificParameterListForItem(None)
+      errors.extend(checkValuesAreNotNone(property_list))
+      
+    # Do not check facultative properties (of course)
+
+    # Check owner change for each aggregated item
+    # XXX Checking it here would be inadequate, since the owner can change by multiple ways :
+    # adding a new movement for this item, changing it, modifying related organisation, etc...
+    # It is not compatible with a validity workflow approach since the causalities are too numerous
+    # The actual check is done in ImmobilisableItem.getImmobilisationPeriodList()
+    return errors
+      
+      
+  security.declareProtected(Permissions.View, 'checkImmobilisationConsistency')
+  def checkImmobilisationConsistency(self, *args, **kw):
+    """
+    Checks the consistency about immobilisation values
+    """
+    return_value = self._checkImmobilisationConsistency(*args, **kw)
+    return return_value
+
+
+  security.declareProtected(Permissions.View, 'getAmortisationMethodParameter')
+  def getAmortisationMethodParameter(self, parameter_list, **kw):
+    """
+    Returns a dictionary containing the value of each parameter
+    whose name is given in parameter_list.
+    Warning : can only be used on a movement whose amortisation_method
+    is not in (None, NO_CHANGE_METHOD)
+    """
+    if self.getAmortisationMethod() in (None, "", NO_CHANGE_METHOD):
+      return None
+    return self.getAmortisationMethodParameterForItem(None, parameter_list, **kw)
+
+
+  security.declareProtected(Permissions.View, 'getAmortisationMethodParameter')
+  def getAmortisationMethodParameterForItem(self, item, parameter_list, split_char=None, split_qty=3, **kw):
+    """
+    Returns a dictionary containing the value of each parameter
+    whose name is given in parameter_list.
+    The value is get from the amortisation method parameter folder
+    (e.g. portal_skins/erp5_accounting_eu/linear)
+    This folder has specifical parameters needed for calculation
+    'item' can be None to access parameters on a movement whose method is not NO_CHANGE_METHOD nor None
+    """
+    parameter_dict = {}
+    if type(parameter_list) == type(""):
+      parameter_list = [parameter_list]
+    for parameter in parameter_list:
+      parameter_dict[parameter] = None
+    amortisation_method = self.getActualAmortisationMethodForItem(item, **kw)
+    if amortisation_method not in (None, NO_CHANGE_METHOD, UNIMMOBILISING_METHOD, ""):
+      parameter_object = self.restrictedTraverse(AMORTISATION_METHOD_PREFIX + amortisation_method)
+      if parameter_object is not None:
+        for parameter in parameter_list:
+          parameter_dict[parameter] = getattr(parameter_object, parameter, None)
+
+    if (split_char is not None) and (split_qty != 0):
+      new_parameter_dict = {}
+      for key in parameter_dict.keys():
+        param_list = parameter_dict[key]
+        if param_list is None:
+          new_parameter_dict[key] = []
+        if type(param_list) != type([]) and type(param_list) != type(()):
+          param_list = [param_list]
+        new_param_list = []
+        for param in param_list:
+          if param is not None:
+            if param.find(split_char) != -1:
+              param = param.split(split_char)
+              param = [x.strip() for x in param]
+            if type(param) != type([]) and type(param) != type(()):
+              param = [param]
+            if len(param) > split_qty:
+              param = param[:split_qty]
+            while len(param) < split_qty:
+              param.append(param[-1])
+            new_param_list.append(param)
+        new_parameter_dict[key] = new_param_list
+      parameter_dict = new_parameter_dict
+      
+    return parameter_dict
+
+      
+  security.declareProtected(Permissions.View, 'getActualAmortisationMethod')
+  def getActualAmortisationMethodForItem(self, item, **kw):
+    """
+    Returns the actual amortisation method by getting the previous
+    movement method if the current one is NO_CHANGE_METHOD
+    """
+    method = self.getAmortisationMethod()
+    if method not in (None, "", NO_CHANGE_METHOD):
+      return method
+    
+    stop_date = self.getStopDate()
+    if stop_date is None or item is None:
+      return None
+    previous_movement_list = item.getPastImmobilisationMovementValueList(at_date=stop_date, **kw)
+    if previous_movement_list is None:
+      return None
+    for i in range(len(previous_movement_list)-1, -1, -1):
+      movement = previous_movement_list[i]
+      if movement.getAmortisationMethod() not in (None, "", NO_CHANGE_METHOD):
+        return movement.getAmortisationMethod()
+    return None
+
+
+  security.declareProtected(Permissions.View, 'getNeededSpecificParameterListForItem()')
+  def getNeededSpecificParameterListForItem(self, item, **kw):
+    """
+    Returns the list of specific parameters which are
+    needed for the amortisation calculation for the given item
+    """
+    return self.getAmortisationMethodParameterForItem(item=item,
+                                                      parameter_list="needed_specific_parameter_list",
+                                                      split_char = '|',
+                                                      split_qty = 3,
+                                                      **kw)["needed_specific_parameter_list"]
+                                                      
+  
+  security.declareProtected(Permissions.View, 'getUncontinuousNeededSpecificParameterListForItem()')
+  def getUncontinuousNeededSpecificParameterListForItem(self, item, **kw):
+    """
+    Returns the list of specific parameters which are
+    needed for the amortisation calculation for the given item
+    when the amortisation is not continuing the previous period
+    """
+    return self.getAmortisationMethodParameterForItem(item=item,
+                                                      parameter_list="uncontinuous_needed_specific_parameter_list",
+                                                      split_char = '|',
+                                                      split_qty = 3,
+                                                      **kw)["uncontinuous_needed_specific_parameter_list"]
+                                                      
+                                                          
+  security.declareProtected(Permissions.View, 'getFacultativeSpecificParameterListForItem()')
+  def getFacultativeSpecificParameterListForItem(self, item, **kw):
+    """
+    Returns the list of specific parameters which are
+    facultative for the amortisation calculation for the given item
+    """
+    return self.getAmortisationMethodParameterForItem(item=item,
+                                                      parameter_list="facultative_specific_parameter_list",
+                                                      split_char = '|',
+                                                      split_qty = 3,
+                                                      **kw)["facultative_specific_parameter_list"]
+
+                                                                                                            
+  security.declareProtected(Permissions.View, 'isUsingAmortisationMethod')
+  def isUsingAmortisationMethod(self, method):
+    """
+    Return true if this item is using the given method
+    """
+    if self.getAmortisationMethod() == method:
+      return 1
+    return 0
+
+  security.declareProtected(Permissions.View, 'getImmobilisationState')
+  def getImmobilisationState(self, id_only=1):
+    """
+    Return root delivery immobilisation state
+    """
+    return self.getRootDeliveryValue().getImmobilisationState()