Commit 5bfec569 authored by Julien Muchembled's avatar Julien Muchembled

Bugfixes to Transformation + new testLegacyTransformation

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@39282 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent ea488e40
......@@ -63,8 +63,7 @@ class Amount(Base, VariatedMixin):
# Declarative interfaces
zope.interface.implements(interfaces.IAmount)
property_sheets = ( PropertySheet.Base
, PropertySheet.SimpleItem
property_sheets = ( PropertySheet.SimpleItem
, PropertySheet.Amount
, PropertySheet.Price
, PropertySheet.Reference
......
......@@ -27,14 +27,14 @@
#
##############################################################################
import zope.interface
from math import log
from warnings import warn
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLMatrix import XMLMatrix
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.Base import Base
from Products.ERP5Type.Utils import cartesianProduct
......@@ -44,7 +44,7 @@ from Products.CMFCore.utils import getToolByName
from zLOG import LOG, WARNING
class Resource(XMLMatrix, VariatedMixin):
class Resource(XMLObject, XMLMatrix, VariatedMixin):
"""
A Resource
"""
......@@ -57,20 +57,13 @@ class Resource(XMLMatrix, VariatedMixin):
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative interfaces
zope.interface.implements( interfaces.IVariated, )
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
property_sheets = ( PropertySheet.DublinCore
, PropertySheet.Price
, PropertySheet.Resource
, PropertySheet.Reference
, PropertySheet.Comment
, PropertySheet.FlowCapacity
, PropertySheet.VariationRange
, PropertySheet.DefaultSupply
, PropertySheet.Aggregated
)
......
......@@ -147,10 +147,9 @@ class SupplyLink(Path, XMLObject):
rule = applied_rule.getSpecialiseValue()
transformation = rule.getTransformation(movement)
# Call getAggregatedAmountList
tmp_context = movement.getParentValue().getParentValue().asContext()
tmp_context.asComposedDocument = lambda *args: transformation
input_amount = applied_rule.getParentValue()
resource_list = [x.getResourceValue()
for x in tmp_context.getAggregatedAmountList()
for x in transformation.getAggregatedAmountList((input_amount,))
if x.getCausalityValue().getIndustrialPhase() in ind_phase_url_list]
current_resource = movement.getResourceValue()
if current_resource not in resource_list:
......
......@@ -31,14 +31,12 @@
#
##############################################################################
from zLOG import LOG, WARNING
import zope.interface
from warnings import warn
from AccessControl import ClassSecurityInfo
from Products.CMFCategory.Renderer import Renderer
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Amount import Amount
from Products.ERP5.Document.MappedValue import MappedValue
from Products.ERP5.mixin.amount_generator import AmountGeneratorMixin
......@@ -46,7 +44,9 @@ from Products.ERP5.mixin.variated import VariatedMixin
from Products.ERP5.mixin.composition import CompositionMixin
from Products.ERP5Type.XMLObject import XMLObject
class Transformation(MappedValue, AmountGeneratorMixin, VariatedMixin):
# XXX Give priority to VariatedMixin (over Amount) due to conflicting
# implementations of getVariationBaseCategoryList
class Transformation(MappedValue, VariatedMixin, Amount, AmountGeneratorMixin):
"""
Build of material - contains a list of transformed resources
......@@ -65,59 +65,47 @@ class Transformation(MappedValue, AmountGeneratorMixin, VariatedMixin):
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.VariationRange
, PropertySheet.Predicate
, PropertySheet.Comment
, PropertySheet.Reference
property_sheets = ( PropertySheet.Comment
, PropertySheet.Version
#, PropertySheet.Resource
, PropertySheet.TransformedResource
, PropertySheet.Path
, PropertySheet.Transformation
, PropertySheet.Order
, PropertySheet.Task
)
# Declarative interfaces
zope.interface.implements(interfaces.IVariated,
interfaces.IVariationRange,
interfaces.IAmountGenerator
)
def getAggregatedAmountList(self, *args, **kw):
"""
"""
getAggregatedAmountList = \
super(Transformation, self).getAggregatedAmountList
# Detect old use of getAggregatedAmountList
if 'context' in kw:
context = kw.pop('context')
else:
if not args or isinstance(args[0], (list, tuple)):
return getAggregatedAmountList(*args, **kw)
context, args = args[0], args[1:]
warn("The API of getAggregatedAmountList has changed:"
" it must be called on the context instead of passing"
" the context as first parameter", DeprecationWarning)
# XXX add a 'transformation_amount_generator' group type
kw['amount_generator_type_list'] = ('Transformation',
'Transformed Resource',
'Assorted Resource')
if context is not None:
context = (context,)
return getAggregatedAmountList(context, *args, **kw)
def getQuantity(self, default=None):
# Used for amount generation
# (Transformation is defined for 1 unit of target resource)
return 1
# Predicate Value implementation
# asPredicate takes into account the resource
# XXX-JPS not Impl.
def getCellAggregateKey(self, amount_generator_cell):
"""Define a key in order to aggregate amounts at cell level
Transformed Resource (Transformation)
key must be None because:
- quantity and variation are defined in different cells so that the
user does not need to enter values depending on all axes
- amount_generator_cell.test should filter only 1 variant
current key = (acquired resource, acquired variation)
Assorted Resource (Transformation)
key = (assorted resource, assorted resource variation)
usually resource and quantity provided together
Payroll
key = (payroll resource, payroll resource variation)
Tax
key = (tax resource, tax resource variation)
"""
if len(amount_generator_cell.contentValues()):
key = (amount_generator_cell.getRelativeUrl(),)
else:
key = (amount_generator_cell.getParentValue().getRelativeUrl(),)
return key
# Mapped Value implementation
# Transformation itself provides no properties or categories
def getMappedValuePropertyList(self):
......@@ -126,34 +114,6 @@ class Transformation(MappedValue, AmountGeneratorMixin, VariatedMixin):
def getMappedValueBaseCategoryList(self):
return ()
# Amount Generator Mixin
def _getGlobalPropertyDict(self, context, amount_list=None, rounding=False):
"""
No global properties needed
"""
return {
}
def _getAmountPropertyDict(self, amount, amount_list=None, rounding=False):
"""
Produced amount quantity is needed to initialize transformation
"""
# XXX 1 is for compatibility
return {
'produced_quantity' : amount.getQuantity(1),
}
def getBaseApplication(self):
"""
"""
# It is OK to try to acquire
if getattr(self, '_baseGetBaseApplication', None) is not None:
result = self._baseGetBaseApplication()
if result:
return result
return 'produced_quantity'
# IVariationRange and IVariated Implementation
security.declareProtected(Permissions.AccessContentsInformation,
'updateVariationCategoryList')
......@@ -229,6 +189,15 @@ class Transformation(MappedValue, AmountGeneratorMixin, VariatedMixin):
base_category_list, base=1, display_none_category=0)
return result
security.declareProtected(Permissions.AccessContentsInformation,
'setVariationBaseCategoryList')
def setVariationBaseCategoryList(self, value):
"""
Define the possible base categories and reindex object
"""
self._setVariationBaseCategoryList(value)
self.reindexObject()
security.declareProtected(Permissions.AccessContentsInformation,
'getVariationCategoryItemList')
def getVariationCategoryItemList(self, base_category_list=(), base=1,
......
......@@ -71,6 +71,8 @@ class TransformedResource(AmountGeneratorLine):
if not result:
if not self.hasCellContent(base_id='variation'):
result = self.getVariationRangeBaseCategoryList() # The current resource variation
if 'trade_phase' not in result:
result.append('trade_phase')
return result
def getCellAggregateKey(self):
......@@ -81,7 +83,7 @@ class TransformedResource(AmountGeneratorLine):
def getBaseAmountQuantity(cls, delivery_amount, base_application, rounding):
value = delivery_amount.getGeneratedAmountQuantity(base_application)
if base_application == 'produced_quantity':
value += delivery_amount.getQuantity()
value += delivery_amount.getConvertedQuantity()
return value
def getBaseApplication(self):
......
......@@ -174,8 +174,10 @@ class AmountGeneratorMixin:
dict(rounding=rounding))
# If amount_list is None, then try to collect amount_list from
# the current context
default_target = None
if amount_list is None:
if self.providesIMovementCollection():
default_target = 'isMovement'
base_amount_list = BaseAmountDict(*args).__of__(self) \
.recurseMovementList(self.getMovementList())
elif self.providesIAmount():
......@@ -204,8 +206,8 @@ class AmountGeneratorMixin:
return
elif (self.getPortalType() not in amount_generator_line_type_list):
return
if not getattr(delivery_amount, self.isTargetDelivery() and
'isDelivery' or 'isMovement')():
target_method = self.isTargetDelivery() and 'isDelivery' or default_target
if target_method and not getattr(delivery_amount, target_method)():
return
# Try to collect cells and aggregate their mapped properties
# using resource + variation as aggregation key or base_application
......
......@@ -30,7 +30,7 @@
from warnings import warn
from AccessControl import ClassSecurityInfo
from Products.CMFCategory.Renderer import Renderer
from Products.ERP5Type import interfaces, Permissions
from Products.ERP5Type import interfaces, Permissions, PropertySheet
import zope.interface
......@@ -54,7 +54,11 @@ class VariatedMixin:
security = ClassSecurityInfo()
# Declarative interfaces
zope.interface.implements(interfaces.IVariated)
zope.interface.implements(interfaces.IVariated,
interfaces.IVariationRange)
isRADContent = 1 # for 'property_sheets'
property_sheets = (PropertySheet.VariationRange, )
security.declareProtected(Permissions.AccessContentsInformation,
'getVariationBaseCategoryList')
......
......@@ -395,25 +395,16 @@ class TestProductionOrderMixin(TestOrderMixin):
"""
Fills categories of variation
"""
transformation = sequence.get('transformation')
transformation.setVariationBaseCategoryList(self.variation_category_list)
transformation.edit(
variation_base_category_list = self.variation_category_list
)
def stepFillTransformationWithResource(self, sequence=None, sequence_list=None,
**kw):
transformation = sequence.get('transformation')
resource = sequence.get('resource')
self.assertNotEquals(None, resource)
transformation.edit(
resource_value = resource
)
transformation.setResourceValue(resource)
def stepSetOrderLineQuantity(self, sequence=None, sequence_list=None,
**kw):
......
......@@ -26,8 +26,8 @@
#
##############################################################################
from testProductionOrder import TestProductionOrderMixin
from testInventoryAPI import BaseTestUnitConversion
from Products.ERP5.tests.testProductionOrder import TestProductionOrderMixin
from Products.ERP5.tests.testInventoryAPI import BaseTestUnitConversion
import transaction
class TestTransformationMixin(TestProductionOrderMixin):
......@@ -146,15 +146,7 @@ class TestTransformation(TestTransformationMixin, BaseTestUnitConversion):
resource_value=component,
quantity=1)
transformed_resource.setTested(True)
from Products.ERP5Type.Document import newTempAmount
amount = newTempAmount(transformation, "foobar")
amount.edit(
quantity = 1.0,
resource = component.getRelativeUrl(),
)
aggregated_amount_list = transformation.getAggregatedAmountList(amount)
self.assertEquals(len(aggregated_amount_list), 1)
aggregated_amount = aggregated_amount_list[0]
aggregated_amount, = transformation.getAggregatedAmountList()
# Make sure that the isTested method is working properly on the
# temp object
self.assertTrue(aggregated_amount.isTested())
......
......@@ -219,7 +219,6 @@ class TransformationRule(TransformationSourcingRuleMixin, Rule):
transformation = self.getTransformation(applied_rule)
# Generate the fake context
tmp_context = parent_movement.asContext(categories=category_list)
tmp_context.asComposedDocument = lambda *args: transformation
# Calculate the industrial phase list
previous_ind_phase_list = supply_chain.\
getPreviousPackingListIndustrialPhaseList(current_supply_link)
......@@ -228,7 +227,7 @@ class TransformationRule(TransformationSourcingRuleMixin, Rule):
# Call getAggregatedAmountList
# XXX expand failed if transformation is not defined.
# Do we need to catch the exception ?
amount_list = tmp_context.getAggregatedAmountList()
amount_list = transformation.getAggregatedAmountList((tmp_context,))
# Add entries in the consumed_movement_dict
consumed_movement_dict = {}
for amount in amount_list:
......
......@@ -98,9 +98,8 @@ class TestProductionOrderMixin(TestOrderMixin):
some categories for testing them
"""
TestOrderMixin.createCategories(self)
operation_category_list = ['operation1', 'operation2']
if len(self.category_tool.operation.contentValues()) == 0:
for category_id in operation_category_list:
for category_id in self.operation_category_list:
o = self.category_tool.operation.newContent(
portal_type='Category',
id=category_id)
......
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Julien Muchembled <jm@nexedi.com>
#
# 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 sys
from Products.ERP5Legacy.tests import testLegacyProductionOrder
sys.modules['Products.ERP5.tests.testProductionOrder'] = \
testLegacyProductionOrder
from Products.ERP5.tests.testTransformation import *
from Products.ERP5Legacy.tests import Legacy_getBusinessTemplateList
Legacy_getBusinessTemplateList(TestTransformation)
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