Commit 95b48669 authored by Jérome Perrin's avatar Jérome Perrin

Change Item class hierarchy, not all Items are immobilisation items.

Change Machines to be immobilisation items, and adapt test to use computers
as an immobilised items.
Add an interface, but don't describe to much the current API which ideally
should be replaced by expandable item API.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@44438 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 0969f9fd
...@@ -33,11 +33,11 @@ from DateTime import DateTime ...@@ -33,11 +33,11 @@ from DateTime import DateTime
from string import capitalize from string import capitalize
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.DateUtils import addToDate, getClosestDate, roundDate from Products.ERP5Type.DateUtils import addToDate, getClosestDate, roundDate
from Products.ERP5Type.DateUtils import getRoundedMonthBetween, millis from Products.ERP5Type.DateUtils import getRoundedMonthBetween, millis
from Products.ERP5Type.DateUtils import getAccountableYearFraction from Products.ERP5Type.DateUtils import getAccountableYearFraction
from Products.ERP5.Document.Amount import Amount from Products.ERP5.Document.Amount import Amount
from Products.ERP5.Document.Item import Item
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.ERP5.Document.ImmobilisationMovement import ( from Products.ERP5.Document.ImmobilisationMovement import (
UNIMMOBILISING_METHOD, NO_CHANGE_METHOD, AMORTISATION_METHOD_PREFIX ) UNIMMOBILISING_METHOD, NO_CHANGE_METHOD, AMORTISATION_METHOD_PREFIX )
...@@ -52,7 +52,7 @@ NEGLIGEABLE_PRICE = 10e-8 ...@@ -52,7 +52,7 @@ NEGLIGEABLE_PRICE = 10e-8
from Products.ERP5Type.Errors import ImmobilisationValidityError from Products.ERP5Type.Errors import ImmobilisationValidityError
from Products.ERP5Type.Errors import ImmobilisationCalculationError from Products.ERP5Type.Errors import ImmobilisationCalculationError
class ImmobilisableItem(XMLObject, Amount): class ImmobilisableItem(Item, Amount):
""" """
An Immobilisable Item is an Item which can be immobilised An Immobilisable Item is an Item which can be immobilised
and amortised in accounting and amortised in accounting
...@@ -82,23 +82,30 @@ class ImmobilisableItem(XMLObject, Amount): ...@@ -82,23 +82,30 @@ class ImmobilisableItem(XMLObject, Amount):
# not have 'expand' method at the time beeing, simulation methods used here # not have 'expand' method at the time beeing, simulation methods used here
# have different names. # have different names.
## zope.interface.implements(interfaces.IExpandableItem,) zope.interface.implements(interfaces.IExpandableItem,
## interfaces.IImmobilisationItem)
## # IExpandableItem interface implementation
## def getSimulationMovementSimulationState(self, simulation_movement): # IExpandableItem interface implementation
## """Returns the simulation state for this simulation movement. def getSimulationMovementSimulationState(self, simulation_movement):
## """ """Returns the simulation state for this simulation movement.
## portal = self.getPortalObject() """
## draft_state_list = portal.getDraftOrderStateList() portal = self.getPortalObject()
## # if we have an order which is not draft, we'll consider the generated draft_state_list = portal.getDraftOrderStateList()
## # simulation movement are planned. # if we have an order which is not draft, we'll consider the generated
## # This is probably oversimplified implementation, as we may want to look # simulation movement are planned.
## # deliveries / invoices. # This is probably oversimplified implementation, as we may want to look
## for movement in self.getAggregateRelatedValueList( # deliveries / invoices.
## portal_type=portal.getPortalOrderMovementTypeList(),): for movement in self.getAggregateRelatedValueList(
## if movement.getSimulationState() not in draft_state_list: portal_type=portal.getPortalOrderMovementTypeList(),):
## return 'planned' if movement.getSimulationState() not in draft_state_list:
## return 'draft' return 'planned'
return 'draft'
def expand(self, applied_rule_id=None, activate_kw=None, **kw):
"""Expand is not implemented that way for now...
"""
pass
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getImmobilisationRelatedMovementList') 'getImmobilisationRelatedMovementList')
......
...@@ -28,13 +28,11 @@ ...@@ -28,13 +28,11 @@
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.ImmobilisableItem import ImmobilisationValidityError from Products.ERP5.Document.ImmobilisableItem import ImmobilisationValidityError
NEGLIGEABLE_PRICE = 10e-8
class ImmobilisationDelivery(XMLObject): class ImmobilisationDelivery(XMLObject):
""" """
An Immobilisation Delivery is an object whose role is to An Immobilisation Delivery is an object whose role is to
...@@ -122,16 +120,17 @@ class ImmobilisationDelivery(XMLObject): ...@@ -122,16 +120,17 @@ class ImmobilisationDelivery(XMLObject):
sub_movement_list = self.contentValues() sub_movement_list = self.contentValues()
for movement in self.getImmobilisationMovementList(**kw): for movement in self.getImmobilisationMovementList(**kw):
for item in movement.getAggregateValueList(): for item in movement.getAggregateValueList():
future_movement_list = item.getFutureImmobilisationMovementValueList( if interfaces.IImmobilisationItem.providedBy(item):
at_date = self.getStopDate(), future_movement_list = item.getFutureImmobilisationMovementValueList(
from_movement = self, at_date = self.getStopDate(),
filter_valid = 0) from_movement = self,
if future_movement_list is not None: filter_valid = 0)
for next_movement in future_movement_list: if future_movement_list is not None:
if next_movement is not None and \ for next_movement in future_movement_list:
next_movement not in sub_movement_list and \ if next_movement is not None and \
next_movement not in returned_list and \ next_movement not in sub_movement_list and \
next_movement.getStopDate() != self.getStopDate(): next_movement not in returned_list and \
returned_list.append(next_movement) next_movement.getStopDate() != self.getStopDate():
returned_list.append(next_movement)
return returned_list return returned_list
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.Movement import Movement from Products.ERP5.Document.Movement import Movement
...@@ -140,26 +140,27 @@ class ImmobilisationMovement(Movement, XMLObject): ...@@ -140,26 +140,27 @@ class ImmobilisationMovement(Movement, XMLObject):
# Check if the date of this movement is unique # Check if the date of this movement is unique
date_error = 0 date_error = 0
for item in self.getAggregateValueList(): for item in self.getAggregateValueList():
same_date_list = item.getUnfilteredImmobilisationMovementValueList( if interfaces.IImmobilisationItem.providedBy(item):
from_date = self.getStopDate(), same_date_list = item.getUnfilteredImmobilisationMovementValueList(
to_date = self.getStopDate(), from_date = self.getStopDate(),
include_to_date = 1) to_date = self.getStopDate(),
error_found = 0 include_to_date = 1)
for other_movement in same_date_list: error_found = 0
if other_movement != self and other_movement.getRootDeliveryValue().getImmobilisationState() == 'valid': for other_movement in same_date_list:
error_found = 1 if other_movement != self and other_movement.getRootDeliveryValue().getImmobilisationState() == 'valid':
date_error = 1 error_found = 1
if error_found: date_error = 1
if to_translate: if error_found:
msg = {'msg':"An other movement already exists at the same date for item ${item}", if to_translate:
'mapping': {'item':item.getRelativeUrl()} msg = {'msg':"An other movement already exists at the same date for item ${item}",
} 'mapping': {'item':item.getRelativeUrl()}
else: }
msg = "An other movement alreay exists at the same date for item %s" % item.getRelativeUrl() else:
errors.append([self.getRelativeUrl(), msg = "An other movement alreay exists at the same date for item %s" % item.getRelativeUrl()
"Property value inconsistency", 0, errors.append([self.getRelativeUrl(),
msg "Property value inconsistency", 0,
]) msg
])
# Return to avoid infinite loops in case of date errors # Return to avoid infinite loops in case of date errors
if date_error: if date_error:
...@@ -197,17 +198,18 @@ class ImmobilisationMovement(Movement, XMLObject): ...@@ -197,17 +198,18 @@ class ImmobilisationMovement(Movement, XMLObject):
return checkPreviousMovementForItem(previous_movement, item) return checkPreviousMovementForItem(previous_movement, item)
return checkPreviousMovementForItem(previous_movement, item) return checkPreviousMovementForItem(previous_movement, item)
for item in self.getAggregateValueList(): for item in self.getAggregateValueList():
if not checkPreviousMovementForItem(self,item): if interfaces.IImmobilisationItem.providedBy(item):
check_uncontinuous = 1 if not checkPreviousMovementForItem(self,item):
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 check_uncontinuous = 1
# If the previous method is the same, it means the previous movement did else:
# not stop the immobilisation, because stopping is a particular method # 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: if check_uncontinuous:
errors.extend(checkValuesAreNotNone(IMMOBILISATION_UNCONTINUOUS_NEEDED_PROPERTY_LIST)) errors.extend(checkValuesAreNotNone(IMMOBILISATION_UNCONTINUOUS_NEEDED_PROPERTY_LIST))
property_list = self.getUncontinuousNeededSpecificParameterListForItem(None) property_list = self.getUncontinuousNeededSpecificParameterListForItem(None)
......
...@@ -32,13 +32,9 @@ from AccessControl import ClassSecurityInfo ...@@ -32,13 +32,9 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.Amount import Amount from Products.ERP5.Document.Amount import Amount
from Products.ERP5.Document.ImmobilisableItem import ImmobilisableItem
NEGLIGEABLE_PRICE = 10e-8 class Item(XMLObject, Amount):
class Item(XMLObject, Amount, ImmobilisableItem):
""" """
Items in ERP5 are intended to provide a way to track objects Items in ERP5 are intended to provide a way to track objects
""" """
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5.Document.Item import Item from Products.ERP5.Document.ImmobilisableItem import ImmobilisableItem
class Machine(Item): class Machine(ImmobilisableItem):
""" """
Machine represents Machine represents
""" """
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2011 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from zope.interface import Interface
class IImmobilisationItem(Interface):
"""An immobilisation item is an item that acts as an immobilisation.
XXX At this time this interface is here to mark some item as beeing used as
beeing immobilisation. We might consider making it just a marker interface
"""
def getFutureImmobilisationMovementValueList(at_date, from_movement,
filter_valid):
"""Returns the future immobilisation movements.
XXX this method exists but seems wrong, as future movements just belongs to
simulation API.
"""
...@@ -42,7 +42,7 @@ from Products.ERP5.tests.utils import newSimulationExpectedFailure ...@@ -42,7 +42,7 @@ from Products.ERP5.tests.utils import newSimulationExpectedFailure
class TestImmobilisationMixin(ERP5TypeTestCase): class TestImmobilisationMixin(ERP5TypeTestCase):
run_all_test = 1 run_all_test = 1
# Different variables used for this test # Different variables used for this test
item_portal_type = 'Apparel Fabric Item' item_portal_type = 'Computer'
packing_list_portal_type = 'Purchase Packing List' packing_list_portal_type = 'Purchase Packing List'
packing_list_line_portal_type = 'Purchase Packing List Line' packing_list_line_portal_type = 'Purchase Packing List Line'
internal_packing_list_portal_type = 'Internal Packing List' internal_packing_list_portal_type = 'Internal Packing List'
...@@ -79,15 +79,16 @@ class TestImmobilisationMixin(ERP5TypeTestCase): ...@@ -79,15 +79,16 @@ class TestImmobilisationMixin(ERP5TypeTestCase):
Return the list of business templates. Return the list of business templates.
""" """
return ("erp5_base", return ("erp5_core_proxy_field_legacy",
"erp5_base",
"erp5_pdm",# Needed by accounting "erp5_pdm",# Needed by accounting
"erp5_simulation", "erp5_simulation",
"erp5_trade", "erp5_trade",
"erp5_accounting", "erp5_accounting",
"erp5_invoicing", "erp5_invoicing",
"erp5_simplified_invoicing", "erp5_simplified_invoicing",
"erp5_apparel", # In order to use items
"erp5_immobilisation", "erp5_immobilisation",
"erp5_computer_immobilisation", # In order to use items
"erp5_simulation_test", "erp5_simulation_test",
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment