Commit 2de0fc2a authored by Romain Courteaud's avatar Romain Courteaud

slapos_accounting: first version to fetch trade conditions and prices

parent 33ce14f6
def sort_key_method(e):
"""
Priority order of Sale Supply is :
having both group and source_function
having group only
having source_function only
others
"""
return 0
parent = e.getParentValue()
if parent.getPortalType().endswith('Line'):
parent = parent.getParentValue()
return 0 - 1 * int(parent.hasSourceFunction()) - 2 * int(parent.hasGroup())
def filter_method(source_function, group):
def filter_by_source_function_and_group(l):
ret = []
for i in l:
parent = i.getParentValue()
if parent.getPortalType().endswith('Line'):
parent = parent.getParentValue()
# Price should be set in Sale Supply only.
#if parent.getPortalType() != 'Sale Supply' and parent.getParentValue().getPortalType() != 'Sale Supply':
# continue
date = context.getStartDate()
# Check if effective
if parent.hasStartDateRangeMin() and date < parent.getStartDateRangeMin():
continue
# Check if not expired
if parent.hasStartDateRangeMax() and date > parent.getStartDateRangeMax():
continue
# Sale Supply having a different source_function should not be applied.
if parent.getSourceFunction() not in (None, source_function):
continue
# XXX Sale Supply having a different group should not be applied.
#if parent.getGroup() not in (None, group):
# continue
ret.append(i)
return ret
return filter_by_source_function_and_group
source = context.getSourceValue()
if source is None:
group = None
else:
group = source.getGroup()
kw['filter_method'] = filter_method(context.getSourceFunction(), group)
"""
def filter_couscous(predicate_list):
raise NotImplementedError(predicate_list)
return predicate_list
kw['filter_method'] = filter_couscous
"""
kw['sort_key_method'] = sort_key_method
resource = context.getResourceValue()
if resource is not None:
product_line = resource.getProductLine()
if product_line:
kw['categories'] = kw.get('categories', []) + ['product_line/%s' % product_line]
#raise NotImplementedError(str(kw))
return resource.getPriceCalculationOperandDict(
default=default, context=context, **kw)
return default
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>default=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Movement_getPriceCalculationOperandDict</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# This script searches for a trade condition matching the order
# and tries to complete some fields
order = context
Base_translateString = context.Base_translateString
trade_condition_portal_type = 'Sale Trade Condition'
trade_condition_list = order.getSpecialiseValueList(
portal_type=trade_condition_portal_type)
all_category_list = ('source_section', 'source', 'source_project',
'destination_section', 'destination', 'destination_project',
'currency')
tested_base_category_list = [ ]
for base_category in all_category_list:
if context.getProperty(base_category):
tested_base_category_list.append(base_category)
count = len(tested_base_category_list) + 1
# if no date is defined, use today's date to retrieve predicate that define start_date_range_min/max
if order.getStartDate() is None:
predicate_context = order.asContext(start_date=DateTime())
else:
predicate_context = order
def rank_method(trade_condition):
rank = 0
destination_project = trade_condition.getDestinationProject()
if destination_project:
if destination_project == context.getDestinationProject():
rank += 10
else:
rank -= 2
destination_section = trade_condition.getDestinationSection()
if destination_section:
if destination_section == context.getDestinationSection():
rank += 10
else:
rank -= 2
destination = trade_condition.getDestination()
if destination:
if destination == context.getDestination():
rank += 10
else:
rank -= 2
if trade_condition.getSourceProject():
rank += 1
if trade_condition.getSourceSection():
rank += 1
if trade_condition.getSource():
rank += 1
rank += len(trade_condition.getSpecialiseList())
return rank
def sort_method(a, b):
return -cmp(rank_method(a), rank_method(b))
def filter_method(trade_condition_list):
# Reject trade condition which has a non different value than the order
filtered_trade_condition_list = []
for trade_condition in trade_condition_list:
matching = True
for base_category in all_category_list:
if order.getProperty(base_category) and trade_condition.getProperty(base_category):
if trade_condition.getProperty(base_category) != order.getProperty(base_category):
#raise NotImplementedError('%s %s %s' % (base_category, trade_condition.getProperty(base_category), order.getProperty(base_category)))
matching = False
break
if matching:
filtered_trade_condition_list.append(trade_condition)
return filtered_trade_condition_list
while count > 0 and len(trade_condition_list) == 0:
count -= 1
count = 0
#raise NotImplementedError(order.getDestinationProjectUid())
trade_condition_list = context.portal_domains.searchPredicateList(
predicate_context, portal_type=trade_condition_portal_type,
validation_state='validated',
specialise__uid='%',
#source_project__uid=order.getSourceProjectUid(),
destination_project__uid=order.getDestinationProjectUid(),
tested_base_category_list=tested_base_category_list,#[:count],
filter_method=filter_method,
sort_method=sort_method)
#raise NotImplementedError('trade cl %s' % str([(x, rank_method(x), x.getValidationState()) for x in trade_condition_list]))
keep_items = {}
if len(trade_condition_list ) == 0 :
keep_items['portal_status_message'] = Base_translateString('No trade condition.')
keep_items['portal_status_level'] = 'error'
else :
# if more than one trade condition is found, simply apply the first one
trade_condition=trade_condition_list[0].getObject()
order.Order_applyTradeCondition(trade_condition, force=force)
# set date
if hasattr(order, 'getReceivedDate') and order.getReceivedDate() is None:
context.setReceivedDate(DateTime())
keep_items['portal_status_message'] = Base_translateString('Order updated.')
if not batch_mode:
return context.Base_redirect(form_id, keep_items=keep_items)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id=\'view\', batch_mode=0, force=1</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SaleOrder_applySaleTradeCondition</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
parent = context.getParentValue()
if (parent.getPortalType() != 'Sale Trade Condition') or (parent.getValidationState() != 'validated'):
# If this supply line is not in a validated trade condition, it does not apply.
return None
base_category_tuple = ('resource', 'price_currency')
if context.getSourceSection():
base_category_tuple += ('source_section',)
if context.getDestinationSection():
base_category_tuple += ('destination_section',)
if context.getSource():
base_category_tuple += ('source',)
if context.getDestination():
base_category_tuple += ('destination',)
if context.getSourceProject():
base_category_tuple += ('source_project',)
if context.getDestinationProject():
base_category_tuple += ('destination_project',)
# Supply Lines from trade conditions are set as specialise to this trade condition,
# so that we can apply a predicate on movements later. Supply Lines from trade condition
# only apply on movements using these trade conditions.
category_list = context.getCategoryList() + ['specialise/%s' % context.getParentValue().getRelativeUrl()]
context = context.asContext(categories=category_list)
base_category_tuple += ('specialise', )
#backwards compatibility
mapped_value_property_list = context.getMappedValuePropertyList()
for mapped_property in ('priced_quantity', 'quantity_unit'):
if not mapped_property in mapped_value_property_list:
mapped_value_property_list.append(mapped_property)
context.setMappedValuePropertyList(mapped_value_property_list)
return context.generatePredicate(membership_criterion_base_category_list = base_category_tuple,
criterion_property_list = ('start_date',))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args,**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupplyLine_asPredicate</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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