Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Richard
erp5
Commits
ff76d8e3
Commit
ff76d8e3
authored
Jan 22, 2014
by
Tatuya Kamada
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pricing: Add pricing optimisation preference, by default make no difference.
parent
229b4d30
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1212 additions
and
6 deletions
+1212
-6
bt5/erp5_trade/ActionTemplateItem/portal_types/System%20Preference/pricing_preference.xml
...m/portal_types/System%20Preference/pricing_preference.xml
+81
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_getPricingSupplyPathKeyCategoryList.xml
.../SystemPreference_getPricingSupplyPathKeyCategoryList.xml
+78
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing.xml
.../portal_skins/erp5_trade/SystemPreference_viewPricing.xml
+157
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_pricing_optimise.xml
...mPreference_viewPricing/my_preferred_pricing_optimise.xml
+96
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_pricing_supply_path_key_category_list.xml
...ng/my_preferred_pricing_supply_path_key_category_list.xml
+135
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_purchase_movement_supply_path_type_list.xml
.../my_preferred_purchase_movement_supply_path_type_list.xml
+131
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_sale_movement_supply_path_type_list.xml
...cing/my_preferred_sale_movement_supply_path_type_list.xml
+131
-0
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_prrferred_internal_movement_supply_path_type_list.xml
.../my_prrferred_internal_movement_supply_path_type_list.xml
+131
-0
bt5/erp5_trade/bt/change_log
bt5/erp5_trade/bt/change_log
+3
-0
bt5/erp5_trade/bt/revision
bt5/erp5_trade/bt/revision
+1
-1
bt5/erp5_trade/bt/template_action_path_list
bt5/erp5_trade/bt/template_action_path_list
+1
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml
...ins/erp5_core/Movement_getPriceCalculationOperandDict.xml
+38
-1
product/ERP5/bootstrap/erp5_core/bt/change_log
product/ERP5/bootstrap/erp5_core/bt/change_log
+3
-0
product/ERP5/bootstrap/erp5_core/bt/revision
product/ERP5/bootstrap/erp5_core/bt/revision
+1
-1
product/ERP5/tests/testSupply.py
product/ERP5/tests/testSupply.py
+225
-3
No files found.
bt5/erp5_trade/ActionTemplateItem/portal_types/System%20Preference/pricing_preference.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_view
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_view
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
pricing_preference
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
View
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
8.5
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Pricing
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/SystemPreference_viewPricing
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_getPricingSupplyPathKeyCategoryList.xml
0 → 100644
View file @
ff76d8e3
<?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>
_body
</string>
</key>
<value>
<string>
"""\n
Key categories for Supply Paths for Pricing Optimisation\n
\n
The way of the optimisation is reducing target supply paths,\n
else all supply paths are the domain of the SELECT.\n
"""\n
category = context.portal_categories\n
\n
return [(x.id, x.id) for x in (category.resource, category.source, \n
category.source_section, category.destination,\n
category.destination_section, category.source_account,\n
category.price_currency)]\n
</string>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
**kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SystemPreference_getPricingSupplyPathKeyCategoryList
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ERP5Form"
module=
"Products.ERP5Form.Form"
/>
</pickle>
<pickle>
<dictionary>
<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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_objects
</string>
</key>
<value>
<tuple/>
</value>
</item>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
Base_edit
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
edit_order
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
enctype
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
group_list
</string>
</key>
<value>
<list>
<string>
left
</string>
<string>
right
</string>
<string>
center
</string>
<string>
bottom
</string>
<string>
hidden
</string>
</list>
</value>
</item>
<item>
<key>
<string>
groups
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
bottom
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
center
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
hidden
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
left
</string>
</key>
<value>
<list>
<string>
my_preferred_pricing_optimise
</string>
<string>
my_preferred_sale_movement_supply_path_type_list
</string>
<string>
my_preferred_purchase_movement_supply_path_type_list
</string>
<string>
my_prrferred_internal_movement_supply_path_type_list
</string>
</list>
</value>
</item>
<item>
<key>
<string>
right
</string>
</key>
<value>
<list>
<string>
my_preferred_pricing_supply_path_key_category_list
</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
SystemPreference_viewPricing
</string>
</value>
</item>
<item>
<key>
<string>
method
</string>
</key>
<value>
<string>
POST
</string>
</value>
</item>
<item>
<key>
<string>
name
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
pt
</string>
</key>
<value>
<string>
form_view
</string>
</value>
</item>
<item>
<key>
<string>
row_length
</string>
</key>
<value>
<int>
4
</int>
</value>
</item>
<item>
<key>
<string>
stored_encoding
</string>
</key>
<value>
<string>
UTF-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Pricing
</string>
</value>
</item>
<item>
<key>
<string>
unicode_mode
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
update_action
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
update_action_title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_pricing_optimise.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_preferred_pricing_optimise
</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>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
values
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string>
my_checkbox
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Enable following Pricing Peformance Optimisation
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_pricing_supply_path_key_category_list.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
items
</string>
<string>
size
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_preferred_pricing_supply_path_key_category_list
</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>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</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>
field_id
</string>
</key>
<value>
<string>
my_multi_list_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<int>
8
</int>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Select Key Categories for Pricing Supply Path (Performance Optimisation)
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python:here.SystemPreference_getPricingSupplyPathKeyCategoryList()
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_purchase_movement_supply_path_type_list.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
items
</string>
<string>
size
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_preferred_purchase_movement_supply_path_type_list
</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>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
target
</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>
field_id
</string>
</key>
<value>
<string>
my_multi_list_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<int>
8
</int>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Only Select these Supply Path Types for Purchase Movement (Performance Optimisation)
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python:here.getPortalSupplyPathTypeList()
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_preferred_sale_movement_supply_path_type_list.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
items
</string>
<string>
size
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_preferred_sale_movement_supply_path_type_list
</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>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
target
</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>
field_id
</string>
</key>
<value>
<string>
my_multi_list_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<int>
8
</int>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Only Select these Supply Path Types for Sale Movement (Performance Optimisation)
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python:here.getPortalSupplyPathTypeList()
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/SkinTemplateItem/portal_skins/erp5_trade/SystemPreference_viewPricing/my_prrferred_internal_movement_supply_path_type_list.xml
0 → 100644
View file @
ff76d8e3
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ProxyField"
module=
"Products.ERP5Form.ProxyField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
delegated_list
</string>
</key>
<value>
<list>
<string>
items
</string>
<string>
size
</string>
<string>
title
</string>
</list>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
my_prrferred_internal_movement_supply_path_type_list
</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>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key>
<string>
tales
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
field_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
target
</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>
field_id
</string>
</key>
<value>
<string>
my_multi_list_field
</string>
</value>
</item>
<item>
<key>
<string>
form_id
</string>
</key>
<value>
<string>
Base_viewFieldLibrary
</string>
</value>
</item>
<item>
<key>
<string>
items
</string>
</key>
<value>
<list/>
</value>
</item>
<item>
<key>
<string>
size
</string>
</key>
<value>
<int>
8
</int>
</value>
</item>
<item>
<key>
<string>
target
</string>
</key>
<value>
<string>
Click to edit the target
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Only Select these Supply Path Types for Internal Movement (Performance Optimisation)
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"TALESMethod"
module=
"Products.Formulator.TALESField"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_text
</string>
</key>
<value>
<string>
python:here.getPortalSupplyPathTypeList()
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_trade/bt/change_log
View file @
ff76d8e3
2014-01-15 tatuya
* Add Pricing Preference Tab so that we can optimise pricing query.
2013-09-03 arnaud.fontaine
2013-09-03 arnaud.fontaine
* ZODB Components: Workflow History must always be kept, so avoid an extra step for developers.
* ZODB Components: Workflow History must always be kept, so avoid an extra step for developers.
...
...
bt5/erp5_trade/bt/revision
View file @
ff76d8e3
1176
1177
\ No newline at end of file
\ No newline at end of file
bt5/erp5_trade/bt/template_action_path_list
View file @
ff76d8e3
...
@@ -192,6 +192,7 @@ Sale Trade Condition | view
...
@@ -192,6 +192,7 @@ Sale Trade Condition | view
Sale Trade Condition | view_payment
Sale Trade Condition | view_payment
Sale Trade Condition | view_profile
Sale Trade Condition | view_profile
Sale Trade Condition | view_trade_model_line_list
Sale Trade Condition | view_trade_model_line_list
System Preference | pricing_preference
System Preference | trade_preference
System Preference | trade_preference
Trade Model Line Cell Consistency Constraint | predicate
Trade Model Line Cell Consistency Constraint | predicate
Trade Model Line Cell Consistency Constraint | view
Trade Model Line Cell Consistency Constraint | view
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml
View file @
ff76d8e3
...
@@ -134,6 +134,39 @@ def getRelatedTradeConditionList(trade_condition):\n
...
@@ -134,6 +134,39 @@ def getRelatedTradeConditionList(trade_condition):\n
getRelatedTradeConditionList(related_trade_condition))\n
getRelatedTradeConditionList(related_trade_condition))\n
return related_trade_condition_list\n
return related_trade_condition_list\n
\n
\n
def getOptimisedPriceCalculationOperandDict(default=None, context=None, **kw):\n
"""\n
Price Method optimised by the preference \n
"""\n
movement_portal_type = context.portal_type\n
preferences = context.portal_preferences\n
supply_portal_type_list = []\n
if movement_portal_type in context.getPortalSaleTypeList():\n
supply_portal_type_list = preferences.getPreferredSaleMovementSupplyPathTypeList()\n
elif movement_portal_type in context.getPortalPurchaseTypeList():\n
supply_portal_type_list = preferences.getPreferredPurchaseMovementSupplyPathTypeList()\n
elif movement_portal_type in context.getPortalInternalTypeList():\n
supply_portal_type_list = preferences.getPreferredInternalMovementSupplyPathTypeList()\n
if supply_portal_type_list:\n
supply_kw = dict(portal_type=supply_portal_type_list)\n
for key in preferences.getPreferredPricingSupplyPathKeyCategoryList():\n
key_uid = \'%s_uid\' % key\n
supply_kw[\'default_%s\' % key_uid] = context.getProperty(key_uid)\n
supply_uid_list = [str(brain.uid) for brain in context.portal_catalog(**supply_kw)]\n
if len(supply_uid_list):\n
kw[\'query\'] = \' catalog.uid IN (%s)\' % \',\'.join(supply_uid_list)\n
else:\n
return default\n
return resource.getPriceCalculationOperandDict(default=default, context=context, **kw)\n
\n
def isPricingOptimise():\n
"""Check whether pricing optimisation is enabled or not """\n
try:\n
return context.portal_preferences.getPreferredPricingOptimise()\n
except AttributeError:\n
# When the preference is not support the property, for instance, old sites\n
return False\n
\n
try:\n
try:\n
explanation = context.getExplanationValue()\n
explanation = context.getExplanationValue()\n
except AttributeError:\n
except AttributeError:\n
...
@@ -171,8 +204,12 @@ if explanation is not None:\n
...
@@ -171,8 +204,12 @@ if explanation is not None:\n
high_priority_supply_line_list)\n
high_priority_supply_line_list)\n
\n
\n
resource = context.getResourceValue()\n
resource = context.getResourceValue()\n
\n
if resource is not None:\n
if resource is not None:\n
r = resource.getPriceCalculationOperandDict(\n
if isPricingOptimise():\n
return getOptimisedPriceCalculationOperandDict(default=default, context=context, **kw)\n
else:\n
r = resource.getPriceCalculationOperandDict(\n
default=default, context=context, **kw)\n
default=default, context=context, **kw)\n
return r\n
return r\n
\n
\n
...
...
product/ERP5/bootstrap/erp5_core/bt/change_log
View file @
ff76d8e3
2014-01-15 tatuya
* Add optimised Pricing Method which can be enabled/disabled by the preference.
2014-01-09 arnaud.fontaine
2014-01-09 arnaud.fontaine
* BusinessTemplate: Fix warning because of newly ListBox added parameter (following ca3440e).
* BusinessTemplate: Fix warning because of newly ListBox added parameter (following ca3440e).
...
...
product/ERP5/bootstrap/erp5_core/bt/revision
View file @
ff76d8e3
41148
41149
\ No newline at end of file
\ No newline at end of file
product/ERP5/tests/testSupply.py
View file @
ff76d8e3
...
@@ -51,6 +51,20 @@ class TestSupplyMixin:
...
@@ -51,6 +51,20 @@ class TestSupplyMixin:
self
.
portal
.
newContent
(
portal_type
=
'Folder'
,
self
.
portal
.
newContent
(
portal_type
=
'Folder'
,
id
=
'testing_folder'
)
id
=
'testing_folder'
)
self
.
folder
=
self
.
portal
.
testing_folder
self
.
folder
=
self
.
portal
.
testing_folder
self
.
setUpPreferences
()
def
setUpPreferences
(
self
):
portal_preferences
=
self
.
getPreferenceTool
()
preference
=
getattr
(
portal_preferences
,
'test_system_preference'
,
None
)
if
preference
is
None
:
preference
=
portal_preferences
.
newContent
(
portal_type
=
'System Preference'
,
title
=
'System Preference'
,
id
=
'test_system_preference'
)
if
preference
.
getPreferenceState
()
==
'disabled'
:
preference
.
enable
()
self
.
tic
()
def
beforeTearDown
(
self
):
def
beforeTearDown
(
self
):
module
=
self
.
portal
.
getDefaultModule
(
self
.
supply_portal_type
)
module
=
self
.
portal
.
getDefaultModule
(
self
.
supply_portal_type
)
...
@@ -69,6 +83,8 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
...
@@ -69,6 +83,8 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
generic_supply_line_portal_type
=
'Supply Line'
generic_supply_line_portal_type
=
'Supply Line'
generic_supply_cell_portal_type
=
'Supply Cell'
generic_supply_cell_portal_type
=
'Supply Cell'
predicate_portal_type
=
'Predicate'
predicate_portal_type
=
'Predicate'
delivery_portal_type
=
'Sale Order'
movement_portal_type
=
'Sale Order Line'
@
reindex
@
reindex
def
_makeMovement
(
self
,
**
kw
):
def
_makeMovement
(
self
,
**
kw
):
...
@@ -78,13 +94,29 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
...
@@ -78,13 +94,29 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
mvt
.
edit
(
**
kw
)
mvt
.
edit
(
**
kw
)
return
mvt
return
mvt
@
reindex
def
_makeRealMovement
(
self
,
**
kw
):
"""Creates a real movement.
"""
mvt
=
self
.
portal
\
.
getDefaultModule
(
portal_type
=
self
.
delivery_portal_type
)
\
.
newContent
(
portal_type
=
self
.
delivery_portal_type
)
\
.
newContent
(
portal_type
=
self
.
movement_portal_type
)
mvt
.
edit
(
**
kw
)
return
mvt
@
reindex
@
reindex
def
_makeSupply
(
self
,
**
kw
):
def
_makeSupply
(
self
,
**
kw
):
"""Creates a supply.
"""Creates a supply.
"""
"""
if
'portal_type'
in
kw
:
portal_type
=
kw
.
pop
(
'portal_type'
)
else
:
portal_type
=
self
.
supply_portal_type
supply
=
self
.
portal
\
supply
=
self
.
portal
\
.
getDefaultModule
(
portal_type
=
self
.
supply_
portal_type
)
\
.
getDefaultModule
(
portal_type
=
portal_type
)
\
.
newContent
(
portal_type
=
self
.
supply_
portal_type
)
.
newContent
(
portal_type
=
portal_type
)
supply
.
edit
(
**
kw
)
supply
.
edit
(
**
kw
)
return
supply
return
supply
...
@@ -92,7 +124,11 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
...
@@ -92,7 +124,11 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
def
_makeSupplyLine
(
self
,
supply
,
**
kw
):
def
_makeSupplyLine
(
self
,
supply
,
**
kw
):
"""Creates a supply line.
"""Creates a supply line.
"""
"""
supply_line
=
supply
.
newContent
(
portal_type
=
self
.
supply_line_portal_type
)
if
'portal_type'
in
kw
:
portal_type
=
kw
.
pop
(
'portal_type'
)
else
:
portal_type
=
self
.
supply_line_portal_type
supply_line
=
supply
.
newContent
(
portal_type
=
portal_type
)
supply_line
.
edit
(
**
kw
)
supply_line
.
edit
(
**
kw
)
return
supply_line
return
supply_line
...
@@ -104,6 +140,58 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
...
@@ -104,6 +140,58 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
supply_cell
.
edit
(
**
kw
)
supply_cell
.
edit
(
**
kw
)
return
supply_cell
return
supply_cell
def
_makeSections
(
self
):
""" make organisations """
self
.
_makeOrganisation
(
'my_section'
)
self
.
_makeOrganisation
(
'your_section'
)
self
.
tic
()
def
_makeOrganisation
(
self
,
organisation_id
):
""" make an organisation with the id"""
organisation_module
=
self
.
portal
.
organisation_module
if
getattr
(
organisation_module
,
organisation_id
,
None
)
is
None
:
organisation_module
.
newContent
(
portal_type
=
'Organisation'
,
id
=
organisation_id
)
def
_makeResource
(
self
,
resouce_id
):
""" make a resource with the id"""
product_module
=
self
.
portal
.
product_module
if
getattr
(
product_module
,
resouce_id
,
None
)
is
None
:
product_module
.
newContent
(
portal_type
=
"Product"
,
id
=
resouce_id
)
@
reindex
def
_makeVariableSupplyLine
(
self
,
supply_portal_type
=
None
,
supply_line_portal_type
=
None
,
resource_value
=
None
,
source_section_value
=
None
,
destination_section_value
=
None
,
price
=
None
):
""" Make a supply line with the parameters. """
supply
=
self
.
_makeSupply
(
start_date_range_min
=
'2014/01/01'
,
start_date_range_max
=
'2014/01/31'
,
portal_type
=
supply_portal_type
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
,
)
supply
.
validate
()
supply_line
=
self
.
_makeSupplyLine
(
supply
,
portal_type
=
supply_line_portal_type
)
supply_line
.
edit
(
resource_value
=
resource_value
,
base_price
=
price
)
self
.
tic
()
def
_clearCache
(
self
):
""" Clear cache to test preferences.
"""
self
.
portal
.
portal_caches
.
clearCache
(
cache_factory_list
=
(
'erp5_ui_short'
,
# for preference cache
))
def
test_MovementAndSupplyModification
(
self
):
def
test_MovementAndSupplyModification
(
self
):
"""
"""
Check that moving timeframe of supply
Check that moving timeframe of supply
...
@@ -370,6 +458,135 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
...
@@ -370,6 +458,135 @@ class TestSaleSupply(TestSupplyMixin, SubcontentReindexingWrapper,
self
.
assertEqual
(
None
,
another_supply_line
.
getBaseUnitPrice
())
self
.
assertEqual
(
None
,
another_supply_line
.
getBaseUnitPrice
())
def
testGetPriceWithOptimisation
(
self
):
"""
Test pricing optimisation based on the preference configuration.
"""
preference
=
getattr
(
self
.
getPreferenceTool
(),
'test_system_preference'
)
preference
.
setPreferredPricingOptimise
(
False
)
# every time modifying preference, need to clear cache
self
.
_clearCache
()
self
.
assertEquals
(
preference
.
getPreferredPricingOptimise
(),
False
)
self
.
_makeSections
()
self
.
_makeResource
(
self
.
id
())
self
.
tic
()
resource_value
=
self
.
portal
.
product_module
[
self
.
id
()]
source_section_value
=
self
.
portal
.
organisation_module
[
'my_section'
]
destination_section_value
=
self
.
portal
.
organisation_module
[
'your_section'
]
movement
=
self
.
_makeRealMovement
(
start_date
=
'2014/01/15'
,
resource_value
=
resource_value
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
)
self
.
assertEquals
(
movement
.
getPrice
(),
None
)
supply
=
self
.
_makeSupply
(
start_date_range_min
=
'2014/01/01'
,
start_date_range_max
=
'2014/01/31'
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
,
)
supply
.
validate
()
supply_line
=
self
.
_makeSupplyLine
(
supply
)
supply_line
.
edit
(
resource_value
=
resource_value
,
base_price
=
100
)
self
.
tic
()
self
.
assertEquals
(
movement
.
getPrice
(),
100
)
# only the flag is enabled, the behavior is same with not-optimised one
preference
.
setPreferredPricingOptimise
(
True
)
preference
.
getPreferredPricingSupplyPathKeyCategoryList
(
[
'resource'
,
'source_section'
,
'destination_section'
])
self
.
tic
()
self
.
_clearCache
()
self
.
assertEquals
(
movement
.
getPrice
(),
100
)
# With following setting, Movement_getPriceCalculationOperandDict creates
# efficient query from the RDBMS point of view.
# Note that following assertion does not check the efficiency, this only
# checks that the functionality is kept even after the optimisation.
preference
.
setPreferredSaleMovementSupplyPathTypeList
(
[
'Sale Supply Line'
])
preference
.
setPreferredPurchaseMovementSupplyPathTypeList
(
[
'Purchase Supply Line'
])
preference
.
setPreferredInternalMovementSupplyPathTypeList
(
[
'Internal Supply Line'
])
self
.
tic
()
self
.
_clearCache
()
movement
.
setPrice
(
None
)
# getPrice() sets the price, so clear it first.
self
.
assertEquals
(
movement
.
getPrice
(),
100
)
preference
.
setPreferredPricingOptimise
(
False
)
self
.
_clearCache
()
def
test_getPriceWithOptimisationWrongSetting
(
self
):
"""
Check Pricing optimisation with a strange setting.
With the setting, the strange supply path will be selected, thus
the following assertion make sure the preference certainly works.
"""
preference
=
getattr
(
self
.
getPreferenceTool
(),
'test_system_preference'
)
preference
.
setPreferredPricingOptimise
(
True
)
self
.
_clearCache
()
self
.
assertEquals
(
preference
.
getPreferredPricingOptimise
(),
True
)
self
.
_makeSections
()
self
.
_makeResource
(
self
.
id
())
self
.
tic
()
resource_value
=
self
.
portal
.
product_module
[
self
.
id
()]
source_section_value
=
self
.
portal
.
organisation_module
[
'my_section'
]
destination_section_value
=
self
.
portal
.
organisation_module
[
'your_section'
]
self
.
tic
()
preference
.
getPreferredPricingSupplyPathKeyCategoryList
(
[
'resource'
,
'source_section'
,
'destination_section'
])
movement
=
self
.
_makeRealMovement
(
start_date
=
'2014/01/15'
,
resource_value
=
resource_value
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
)
self
.
_makeVariableSupplyLine
(
supply_portal_type
=
'Sale Supply'
,
supply_line_portal_type
=
'Sale Supply Line'
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
,
resource_value
=
resource_value
,
price
=
5
)
self
.
_makeVariableSupplyLine
(
supply_portal_type
=
'Purchase Supply'
,
supply_line_portal_type
=
'Purchase Supply Line'
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
,
resource_value
=
resource_value
,
price
=
10
)
self
.
_makeVariableSupplyLine
(
supply_portal_type
=
'Internal Supply'
,
supply_line_portal_type
=
'Internal Supply Line'
,
resource_value
=
resource_value
,
source_section_value
=
source_section_value
,
destination_section_value
=
destination_section_value
,
price
=
15
)
self
.
tic
()
# wrong setting, then proper supply path can not be found, select wrong one
if
self
.
delivery_portal_type
==
'Sale Order'
:
preference
.
setPreferredSaleMovementSupplyPathTypeList
([
'Purchase Supply Line'
])
self
.
_clearCache
()
self
.
tic
()
movement
.
setPrice
(
None
)
self
.
assertEquals
(
movement
.
getPrice
(),
10
)
elif
self
.
delivery_portal_type
in
(
'Purchase Order'
,
'Internal Order'
):
preference
.
setPreferredPurchaseMovementSupplyPathTypeList
(
[
'Sale Supply Line'
])
preference
.
setPreferredInternalMovementSupplyPathTypeList
(
[
'Sale Supply Line'
])
self
.
_clearCache
()
self
.
tic
()
movement
.
setPrice
(
None
)
self
.
assertEquals
(
movement
.
getPrice
(),
5
)
preference
.
setPreferredPricingOptimise
(
False
)
self
.
_clearCache
()
class
TestPurchaseSupply
(
TestSaleSupply
):
class
TestPurchaseSupply
(
TestSaleSupply
):
"""
"""
Test Purchase Supplies usage
Test Purchase Supplies usage
...
@@ -377,6 +594,9 @@ class TestPurchaseSupply(TestSaleSupply):
...
@@ -377,6 +594,9 @@ class TestPurchaseSupply(TestSaleSupply):
supply_portal_type
=
'Purchase Supply'
supply_portal_type
=
'Purchase Supply'
supply_line_portal_type
=
'Purchase Supply Line'
supply_line_portal_type
=
'Purchase Supply Line'
supply_cell_portal_type
=
'Purchase Supply Cell'
supply_cell_portal_type
=
'Purchase Supply Cell'
delivery_portal_type
=
'Purchase Order'
movement_portal_type
=
'Purchase Order Line'
class
TestInternalSupply
(
TestSaleSupply
):
class
TestInternalSupply
(
TestSaleSupply
):
"""
"""
...
@@ -385,6 +605,8 @@ class TestInternalSupply(TestSaleSupply):
...
@@ -385,6 +605,8 @@ class TestInternalSupply(TestSaleSupply):
supply_portal_type
=
'Internal Supply'
supply_portal_type
=
'Internal Supply'
supply_line_portal_type
=
'Internal Supply Line'
supply_line_portal_type
=
'Internal Supply Line'
supply_cell_portal_type
=
'Internal Supply Cell'
supply_cell_portal_type
=
'Internal Supply Cell'
delivery_portal_type
=
'Internal Order'
movement_portal_type
=
'Internal Order Line'
def
test_suite
():
def
test_suite
():
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment