Commit 12d62298 authored by Jérome Perrin's avatar Jérome Perrin

make it possible to budget for "unset" value. Due to technical limitations,

this is not working for section, node and movement axis.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@39011 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent f0bd3fdb
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="BaseCategory" module="Products.ERP5Type.Document.BaseCategory"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>budget_special_node</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>budget_special_node</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Base Category</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Special Nodes for Budget</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category" module="Products.ERP5Type.Document.Category"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>budget_special_node/all_other</string>
</tuple>
</value>
</item>
<item>
<key> <string>codification</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>all_other</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>All Others</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category" module="Products.ERP5Type.Document.Category"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>budget_special_node/none</string>
</tuple>
</value>
</item>
<item>
<key> <string>codification</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>none</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>None</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
<value> <value>
<list> <list>
<string>my_aggregate_title_list</string> <string>my_aggregate_title_list</string>
<string>my_include_virtual_none_node</string>
<string>my_include_virtual_other_node</string> <string>my_include_virtual_other_node</string>
</list> </list>
</value> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="CheckBoxField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_include_virtual_none_node</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Include a Virtual Node For "None"</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
budget_line_type budget_line_type
budget_section budget_section
budget_special_node
budget_type budget_type
budget_variation budget_variation
inventory_axis inventory_axis
\ No newline at end of file
portal_categories/budget_special_node/**
portal_categories/budget_variation/** portal_categories/budget_variation/**
portal_categories/inventory_axis/** portal_categories/inventory_axis/**
\ No newline at end of file
...@@ -34,28 +34,6 @@ from Products.ZSQLCatalog.SQLCatalog import Query, NegatedQuery, ComplexQuery ...@@ -34,28 +34,6 @@ from Products.ZSQLCatalog.SQLCatalog import Query, NegatedQuery, ComplexQuery
from Products.ERP5Type.Message import translateString from Products.ERP5Type.Message import translateString
class VirtualNode(object):
"""A Virtual Node for all Other Nodes.
This virtual document can be used in budget variations.
"""
__allow_access_to_unprotected_subobjects__ = 1
def __init__(self, relative_url):
"""The Virtual Node will use the relative URL of the budget line for
memberships.
"""
self.relative_url = relative_url
def getTitle(self):
return str(translateString('All Others'))
def getRelativeUrl(self):
return self.relative_url
def getUid(self):
return -1L
class NodeBudgetVariation(BudgetVariation): class NodeBudgetVariation(BudgetVariation):
""" A budget variation for node """ A budget variation for node
...@@ -94,11 +72,15 @@ class NodeBudgetVariation(BudgetVariation): ...@@ -94,11 +72,15 @@ class NodeBudgetVariation(BudgetVariation):
node_select_method_id = self.getProperty('node_select_method_id') node_select_method_id = self.getProperty('node_select_method_id')
if node_select_method_id: if node_select_method_id:
return guarded_getattr(context, node_select_method_id)() return guarded_getattr(context, node_select_method_id)()
# no script defined, used the explicitly selected values # no script defined, used the explicitly selected values
node_list = self.getAggregateValueList()
portal_categories = self.getPortalObject().portal_categories
if self.getProperty('include_virtual_none_node'):
node_list.append(portal_categories.budget_special_node.none)
if self.getProperty('include_virtual_other_node'): if self.getProperty('include_virtual_other_node'):
return self.getAggregateValueList() + [ node_list.append(portal_categories.budget_special_node.all_other)
VirtualNode(context.getRelativeUrl()), ] return node_list
return self.getAggregateValueList()
def _getNodeTitle(self, node): def _getNodeTitle(self, node):
"""Returns the title of a node """Returns the title of a node
...@@ -155,18 +137,31 @@ class NodeBudgetVariation(BudgetVariation): ...@@ -155,18 +137,31 @@ class NodeBudgetVariation(BudgetVariation):
continue continue
criterion_base_category, node_url = criterion_category.split('/', 1) criterion_base_category, node_url = criterion_category.split('/', 1)
if criterion_base_category == base_category: if criterion_base_category == base_category:
if node_url == budget_line.getRelativeUrl(): if node_url == 'budget_special_node/none':
# This is the "Nothing" virtual node
query_dict.setdefault(axis, []).append(Query(**{axis: None}))
if node_url == 'budget_special_node/all_other':
# This is the "All Other" virtual node # This is the "All Other" virtual node
other_uid_list = [] other_uid_list = []
none_node_selected = False
for node in self._getNodeList(budget_line): for node in self._getNodeList(budget_line):
if '%s/%s' % (base_category, node.getRelativeUrl()) in\ if '%s/%s' % (base_category, node.getRelativeUrl()) in\
budget_line.getVariationCategoryList(): budget_line.getVariationCategoryList():
if node.getRelativeUrl() == 'budget_special_node/none':
none_node_selected = True
else:
other_uid_list.append(node.getUid()) other_uid_list.append(node.getUid())
if none_node_selected:
# in this case we don't want to include NULL in All others
query_dict.setdefault(axis, []).append(
NegatedQuery(Query(**{axis: other_uid_list})))
else:
query_dict.setdefault(axis, []).append( query_dict.setdefault(axis, []).append(
ComplexQuery( ComplexQuery(
NegatedQuery(Query(**{axis: other_uid_list})), NegatedQuery(Query(**{axis: other_uid_list})),
Query(**{axis: None}), Query(**{axis: None}),
operator="OR")) operator="OR"))
query_dict.setdefault(axis, []).append( query_dict.setdefault(axis, []).append(
portal_categories.getCategoryValue(node_url, portal_categories.getCategoryValue(node_url,
base_category=criterion_base_category).getUid()) base_category=criterion_base_category).getUid())
...@@ -204,29 +199,38 @@ class NodeBudgetVariation(BudgetVariation): ...@@ -204,29 +199,38 @@ class NodeBudgetVariation(BudgetVariation):
# if we have a virtual "all others" node, we don't set a criterion here. # if we have a virtual "all others" node, we don't set a criterion here.
if self.getProperty('include_virtual_other_node'): if self.getProperty('include_virtual_other_node'):
return query_dict return query_dict
found = False found = False
for node_url in context.getVariationCategoryList( for node_url in context.getVariationCategoryList(
base_category_list=(base_category,)): base_category_list=(base_category,)):
if node_url != '%s/budget_special_node/none' % base_category:
query_dict.setdefault(axis, []).append( query_dict.setdefault(axis, []).append(
portal_categories.getCategoryValue(node_url, portal_categories.getCategoryValue(node_url,
base_category=base_category).getUid()) base_category=base_category).getUid())
found = True found = True
if found: if found:
if self.getProperty('include_virtual_none_node'):
query_dict[axis] = ComplexQuery(
Query(**{axis: None}),
Query(**{axis: query_dict[axis]}),
operator="OR")
return query_dict return query_dict
return dict() return dict()
def _getCellKeyFromInventoryListBrain(self, brain, budget_line, def _getCellKeyFromInventoryListBrain(self, brain, budget_line,
cell_key_cache=None): cell_key_cache=None):
"""Compute key from inventory brain, with support for "all others" virtual """Compute key from inventory brain, with support for virtual nodes.
node.
""" """
cell_key_cache[None] = '%s/budget_special_node/none'\
% self.getProperty('variation_base_category')
key = BudgetVariation._getCellKeyFromInventoryListBrain( key = BudgetVariation._getCellKeyFromInventoryListBrain(
self, brain, budget_line, cell_key_cache=cell_key_cache) self, brain, budget_line, cell_key_cache=cell_key_cache)
if self.getProperty('include_virtual_other_node'): if self.getProperty('include_virtual_other_node'):
if key not in [x[1] for x in if key not in [x[1] for x in
self.getBudgetVariationRangeCategoryList(budget_line)]: self.getBudgetVariationRangeCategoryList(budget_line)]:
key = '%s/%s' % ( self.getProperty('variation_base_category'), key = '%s/budget_special_node/all_other' % (
budget_line.getRelativeUrl() ) self.getProperty('variation_base_category'),)
return key return key
def getBudgetLineVariationRangeCategoryList(self, budget_line): def getBudgetLineVariationRangeCategoryList(self, budget_line):
......
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