Commit 211407a7 authored by Jérome Perrin's avatar Jérome Perrin

Add documents, rules and test for new tax system.

Update some rules to expand base_contribution in simulation, and add corresponding movement groups.
Add a new movement group 'tax_movement'
TradeCondition now subclass Delivery, because it contains movements (Tax Model Line)


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@20467 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 8ff90971
......@@ -132,6 +132,8 @@ class DeliveryRule(Rule):
quantity_unit=deliv_mvt.getQuantityUnit(),
price=deliv_mvt.getPrice(),
price_currency=deliv_mvt.getPriceCurrency(),
base_contribution_list=deliv_mvt.getBaseContributionList(),
base_application_list=deliv_mvt.getBaseApplicationList(),
)
elif sim_mvt in existing_movement_list:
if sim_mvt not in immutable_movement_list:
......@@ -158,6 +160,8 @@ class DeliveryRule(Rule):
quantity_unit=deliv_mvt.getQuantityUnit(),
price=deliv_mvt.getPrice(),
price_currency=deliv_mvt.getPriceCurrency(),
base_contribution_list=deliv_mvt.getBaseContributionList(),
base_application_list=deliv_mvt.getBaseApplicationList(),
force_update=1)
else:
# modification disallowed, must compensate
......
......@@ -97,6 +97,7 @@ class InvoicingRule(Rule):
'resource': context_movement.getResource(),
'variation_category_list': context_movement.getVariationCategoryList(),
'variation_property_dict': context_movement.getVariationPropertyDict(),
'base_contribution_list': context_movement.getBaseContributionList(),
'aggregate_list': context_movement.getAggregateList(),
'quantity': context_movement.getCorrectedQuantity(),
'quantity_unit': context_movement.getQuantityUnit(),
......
......@@ -106,6 +106,9 @@ class OrderRule(DeliveryRule):
order_movement_dict[order_movement.getPath()] = s_m
# Create or modify movements
for movement in order_movement_list:
# FIXME: to be improved later
if movement.getPortalType() not in ('Tax Line', ):
continue
related_order = order_movement_dict.get(movement.getPath(), None)
if related_order is None:
related_order = movement.getOrderRelatedValue()
......@@ -181,6 +184,7 @@ class OrderRule(DeliveryRule):
'resource',
'variation_category_list',
'variation_property_dict',
'base_contribution_list',
'aggregate_list',
'price',
'price_currency',
......
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
# Jerome Perrin <jerome@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 AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5.Document.DeliveryLine import DeliveryLine
class TaxLine(DeliveryLine):
""" Tax Line
"""
meta_type = 'ERP5 Tax Line'
portal_type = 'Tax Line'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative interfaces
__implements__ = ( Interface.Variated, )
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.Amount
, PropertySheet.Task
, PropertySheet.Arrow
, PropertySheet.Movement
, PropertySheet.Price
, PropertySheet.VariationRange
, PropertySheet.ItemAggregation
, PropertySheet.Reference
, PropertySheet.SortIndex
)
security.declareProtected(Permissions.AccessContentsInformation,
'isAccountable')
def isAccountable(self):
""" """
return 1 # XXX not sure
security.declareProtected(Permissions.AccessContentsInformation,
'hasCellContent')
def hasCellContent(self, base_id='movement'):
"""Tax line does not contain cell
"""
return 0
security.declareProtected(Permissions.AccessContentsInformation,
'isMovement' )
def isMovement(self):
"""Tax lines are movements
"""
return 1
##############################################################################
#
# Copyright (c) 2002, 2005 Nexedi SARL and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
# Romain Courteaud <romain@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 AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5.Document.Rule import Rule
from Products.ERP5.Document.DeliveryRule import DeliveryRule
class TaxRule(DeliveryRule):
"""
"""
# CMF Type Definition
meta_type = 'ERP5 Tax Rule'
portal_type = 'Tax Rule'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
__implements__ = ( Interface.Predicate,
Interface.Rule )
# Default Properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
)
security.declareProtected(Permissions.ModifyPortalContent, 'expand')
def expand(self, applied_rule, force=0, **kw):
""" """
movement_type = 'Simulation Movement'
immutable_movement_list = []
parent_simulation_movement = applied_rule.getParentValue()
order_movement = parent_simulation_movement.getDefaultOrderValue()
order_movement_dict = {}
for s_m in applied_rule.objectValues():
order_movement_dict.setdefault(s_m.getOrder(), []).append(s_m)
order_movement_total_price = order_movement.getTotalPrice()
parent_simulation_movement_total_price = \
parent_simulation_movement.getTotalPrice()
# XXX round
if order_movement_total_price != 0 and \
parent_simulation_movement_total_price != 0:
ratio = parent_simulation_movement_total_price / \
order_movement_total_price
for tax_movement in order_movement\
.DeliveryMovement_getCorrespondingTaxLineList():
existing_simulation_movement_list = order_movement_dict.get(
tax_movement.getRelativeUrl(), [])
property_dict = dict()
for prop in ('price', 'base_application_list',
'base_contribution_list', 'resource'):
property_dict[prop] = tax_movement.getProperty(prop)
property_dict['quantity'] = tax_movement.getQuantity() * ratio
if not existing_simulation_movement_list:
applied_rule.newContent(
portal_type=movement_type,
order_value=tax_movement,
order_ratio=1,
delivery_ratio=1,
deliverable=1,
**property_dict )
else:
for existing_simulation_movement in \
existing_simulation_movement_list:
existing_simulation_movement.edit(**property_dict)
# Pass to base class
Rule.expand(self, applied_rule, force=force, **kw)
......@@ -32,8 +32,9 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5.Document.Path import Path
from Products.ERP5.Document.Delivery import Delivery
class TradeCondition(Path):
class TradeCondition(Delivery, Path):
"""
Trade Conditions are used to store the conditions (payment, logistic,...)
which should be applied (and used in the orders) when two companies make
......
......@@ -92,6 +92,9 @@ portal_invoice_movement_type_list = (
'Pay Sheet Cell',
)
portal_tax_movement_type_list = ( 'Tax Line', 'Discount Line',
'Pay Sheet Line', )
portal_order_movement_type_list = (
'Purchase Order Line',
'Purchase Order Cell',
......
......@@ -609,6 +609,16 @@ class ERP5Site(FolderMixIn, CMFSite):
return self._getPortalGroupedTypeList('invoice_movement') or \
self._getPortalConfiguration('portal_invoice_movement_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalTaxMovementTypeList')
def getPortalTaxMovementTypeList(self):
"""
Return tax movement types.
"""
return self._getPortalGroupedTypeList('tax_movement') or \
self._getPortalConfiguration('portal_tax_movement_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalOrderMovementTypeList')
def getPortalOrderMovementTypeList(self):
......
......@@ -1177,6 +1177,18 @@ class RequirementMovementGroup(RootMovementGroup):
def test(self,movement):
return self.getRequirementList(movement) == self.requirement_list
class BaseContributionMovementGroup(PropertyMovementGroup):
""" Group movements that have the same base contributions."""
_property = 'base_contribution_list'
class BaseApplicationMovementGroup(PropertyMovementGroup):
""" Group movements that have the same base applications."""
_property = 'base_application_list'
class PriceCurrencyMovementGroup(PropertyMovementGroup):
""" Group movements that have the same price currency."""
_property = 'price_currency'
class QuantityUnitMovementGroup(PropertyMovementGroup):
""" Group movements that have the same quantity unit."""
_property = 'quantity_unit'
......
......@@ -126,6 +126,7 @@ class Amount:
)
_categories = ('resource', 'quantity_unit',
'base_application', 'base_contribution',
# Acquired categories
'product_line', )
......@@ -182,6 +182,7 @@ class Resource:
_categories = ( 'source', 'destination', 'quantity_unit', 'price_unit',
'weight_unit', 'length_unit', 'height_unit', 'width_unit',
'volume_unit',
'base_contribution',
'price_currency', 'source_price_currency',
'destination_price_currency', 'product_line',
'industrial_phase')
......
This diff is collapsed.
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