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
from string import capitalize
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 getRoundedMonthBetween, millis
from Products.ERP5Type.DateUtils import getAccountableYearFraction
from Products.ERP5.Document.Amount import Amount
from Products.ERP5.Document.Item import Item
from Products.CMFCore.utils import getToolByName
from Products.ERP5.Document.ImmobilisationMovement import (
UNIMMOBILISING_METHOD, NO_CHANGE_METHOD, AMORTISATION_METHOD_PREFIX )
......@@ -52,7 +52,7 @@ NEGLIGEABLE_PRICE = 10e-8
from Products.ERP5Type.Errors import ImmobilisationValidityError
from Products.ERP5Type.Errors import ImmobilisationCalculationError
class ImmobilisableItem(XMLObject, Amount):
class ImmobilisableItem(Item, Amount):
"""
An Immobilisable Item is an Item which can be immobilised
and amortised in accounting
......@@ -82,23 +82,30 @@ class ImmobilisableItem(XMLObject, Amount):
# not have 'expand' method at the time beeing, simulation methods used here
# have different names.
## zope.interface.implements(interfaces.IExpandableItem,)
##
## # IExpandableItem interface implementation
## def getSimulationMovementSimulationState(self, simulation_movement):
## """Returns the simulation state for this simulation movement.
## """
## portal = self.getPortalObject()
## draft_state_list = portal.getDraftOrderStateList()
## # if we have an order which is not draft, we'll consider the generated
## # simulation movement are planned.
## # This is probably oversimplified implementation, as we may want to look
## # deliveries / invoices.
## for movement in self.getAggregateRelatedValueList(
## portal_type=portal.getPortalOrderMovementTypeList(),):
## if movement.getSimulationState() not in draft_state_list:
## return 'planned'
## return 'draft'
zope.interface.implements(interfaces.IExpandableItem,
interfaces.IImmobilisationItem)
# IExpandableItem interface implementation
def getSimulationMovementSimulationState(self, simulation_movement):
"""Returns the simulation state for this simulation movement.
"""
portal = self.getPortalObject()
draft_state_list = portal.getDraftOrderStateList()
# if we have an order which is not draft, we'll consider the generated
# simulation movement are planned.
# This is probably oversimplified implementation, as we may want to look
# deliveries / invoices.
for movement in self.getAggregateRelatedValueList(
portal_type=portal.getPortalOrderMovementTypeList(),):
if movement.getSimulationState() not in draft_state_list:
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,
'getImmobilisationRelatedMovementList')
......
......@@ -28,13 +28,11 @@
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.ERP5.Document.ImmobilisableItem import ImmobilisationValidityError
NEGLIGEABLE_PRICE = 10e-8
class ImmobilisationDelivery(XMLObject):
"""
An Immobilisation Delivery is an object whose role is to
......@@ -122,16 +120,17 @@ class ImmobilisationDelivery(XMLObject):
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)
if interfaces.IImmobilisationItem.providedBy(item):
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
......@@ -28,7 +28,7 @@
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.ERP5.Document.Movement import Movement
......@@ -140,26 +140,27 @@ class ImmobilisationMovement(Movement, XMLObject):
# 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:
if to_translate:
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()
errors.append([self.getRelativeUrl(),
"Property value inconsistency", 0,
msg
])
if interfaces.IImmobilisationItem.providedBy(item):
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:
if to_translate:
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()
errors.append([self.getRelativeUrl(),
"Property value inconsistency", 0,
msg
])
# Return to avoid infinite loops in case of date errors
if date_error:
......@@ -197,17 +198,18 @@ class ImmobilisationMovement(Movement, XMLObject):
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:
if interfaces.IImmobilisationItem.providedBy(item):
if not checkPreviousMovementForItem(self,item):
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
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)
......
......@@ -32,13 +32,9 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.Amount import Amount
from Products.ERP5.Document.ImmobilisableItem import ImmobilisableItem
NEGLIGEABLE_PRICE = 10e-8
class Item(XMLObject, Amount, ImmobilisableItem):
class Item(XMLObject, Amount):
"""
Items in ERP5 are intended to provide a way to track objects
"""
......
......@@ -29,10 +29,10 @@
from AccessControl import ClassSecurityInfo
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
"""
......
# -*- 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
class TestImmobilisationMixin(ERP5TypeTestCase):
run_all_test = 1
# 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_line_portal_type = 'Purchase Packing List Line'
internal_packing_list_portal_type = 'Internal Packing List'
......@@ -79,15 +79,16 @@ class TestImmobilisationMixin(ERP5TypeTestCase):
Return the list of business templates.
"""
return ("erp5_base",
return ("erp5_core_proxy_field_legacy",
"erp5_base",
"erp5_pdm",# Needed by accounting
"erp5_simulation",
"erp5_trade",
"erp5_accounting",
"erp5_invoicing",
"erp5_simplified_invoicing",
"erp5_apparel", # In order to use items
"erp5_immobilisation",
"erp5_computer_immobilisation", # In order to use items
"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