Commit 305f0ac3 authored by Julien Muchembled's avatar Julien Muchembled

* Add support for unit conversion:

   * resources are described using Measure objects
   * stock can be queried in any unit
   * movements perform unit conversion

 * See following wiki articles:
   * HowToUseMeasures
   * TechnicalNotesOnUnitConversion

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@21253 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent a1394fa1
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_report</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>converted_inventory_report</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>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Converted Inventory Report</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ResourceModule_viewConvertedInventoryReportDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_measure</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>1.5</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Measure</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Resource_viewMeasure</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_report</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>converted_inventory_report</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>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Converted Inventory Report</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ResourceModule_viewConvertedInventoryReportDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_measure</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>1.5</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Measure</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Resource_viewMeasure</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_report</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>converted_inventory_report</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>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Converted Inventory Report</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ResourceModule_viewConvertedInventoryReportDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_measure</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>1.5</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Measure</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Expression" module="Products.CMFCore.Expression"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Resource_viewMeasure</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="BaseCategory" module="Products.ERP5Type.Document.BaseCategory"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_folder_handler</string> </key>
<value> <string>CMFBTreeFolderHandler</string> </value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>acquisition_append_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>acquisition_copy_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_mask_value</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>acquisition_object_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>acquisition_portal_type</string> </key>
<value> <string>python:[]</string> </value>
</item>
<item>
<key> <string>acquisition_sync_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>metric_type</string>
</tuple>
</value>
</item>
<item>
<key> <string>category_type</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>fallback_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>metric_type</string> </value>
</item>
<item>
<key> <string>id_generator</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id_group</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>last_id</string> </key>
<value> <string>3</string> </value>
</item>
<item>
<key> <string>membership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>multimembership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Base Category</string> </value>
</item>
<item>
<key> <string>read_permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>rid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>metric_type</string> </value>
</item>
<item>
<key> <string>uid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees._OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees._OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<allowed_content_type_list> <allowed_content_type_list>
<portal_type id="Component"> <portal_type id="Component">
<item>Measure</item>
<item>Sale Supply Line</item> <item>Sale Supply Line</item>
<item>Supply Line</item> <item>Supply Line</item>
<item>Image</item> <item>Image</item>
...@@ -9,7 +10,11 @@ ...@@ -9,7 +10,11 @@
<portal_type id="Component Module"> <portal_type id="Component Module">
<item>Component</item> <item>Component</item>
</portal_type> </portal_type>
<portal_type id="Measure">
<item>Measure Cell</item>
</portal_type>
<portal_type id="Product"> <portal_type id="Product">
<item>Measure</item>
<item>Sale Supply Line</item> <item>Sale Supply Line</item>
<item>Supply Line</item> <item>Supply Line</item>
<item>Image</item> <item>Image</item>
...@@ -46,6 +51,7 @@ ...@@ -46,6 +51,7 @@
<item>Service Individual Variation</item> <item>Service Individual Variation</item>
<item>Purchase Supply Line</item> <item>Purchase Supply Line</item>
<item>Sale Supply Line</item> <item>Sale Supply Line</item>
<item>Measure</item>
</portal_type> </portal_type>
<portal_type id="Service Module"> <portal_type id="Service Module">
<item>Service</item> <item>Service</item>
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
<item>Supply Line</item> <item>Supply Line</item>
<item>Image</item> <item>Image</item>
</portal_type> </portal_type>
<portal_type id="Measure">
<item>Measure Cell</item>
</portal_type>
<portal_type id="Product"> <portal_type id="Product">
<item>Image</item> <item>Image</item>
<item>Sale Supply Line</item> <item>Sale Supply Line</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ERP5TypeInformation" module="Products.ERP5Type.ERP5Type"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_actions</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_aliases</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_roles</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>allowed_content_types</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>base_category_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>document_icon.gif</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Mapped Value</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addMappedValue</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>hidden_content_type_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Measure Cell</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>permission</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>property_sheet_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ERP5TypeInformation" module="Products.ERP5Type.ERP5Type"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_actions</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_aliases</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_roles</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>allowed_content_types</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>base_category_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>document_icon.gif</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Measure</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addMeasure</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>hidden_content_type_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Measure</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>permission</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>property_sheet_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
<type>Component</type> <type>Component</type>
<workflow>validation_workflow, edit_workflow</workflow> <workflow>validation_workflow, edit_workflow</workflow>
</chain> </chain>
<chain>
<type>Measure</type>
<workflow>edit_workflow, measure_interaction_workflow</workflow>
</chain>
<chain> <chain>
<type>Product</type> <type>Product</type>
<workflow>validation_workflow, edit_workflow</workflow> <workflow>validation_workflow, edit_workflow</workflow>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ERP5Form" module="Products.ERP5Form.Form"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</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>
<string>matrixbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>matrixbox_quantity</string>
<string>matrixbox_predicate_category_list</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_metric_type</string>
<string>my_default_metric_type</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_quantity</string>
<string>my_quantity_unit</string>
<string>my_measure_variation_base_category_list</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Measure_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Measure_view</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></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>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="MatrixBox" module="Products.ERP5Form.MatrixBox"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>matrixbox</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>cell_base_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cell_portal_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</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>editable_attributes</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>getter_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>tabs</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_cell_range</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>cell_base_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cell_portal_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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>editable_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>getter_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>tabs</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_cell_range</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>all_editable_attributes</string> </key>
<value>
<list>
<tuple>
<string>target_quantity</string>
<string>quantity</string>
</tuple>
<tuple>
<string>price</string>
<string>price</string>
</tuple>
<tuple>
<string>predicate_value</string>
<string>predicate_value</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cell_base_id</string> </key>
<value> <string>cell</string> </value>
</item>
<item>
<key> <string>cell_portal_type</string> </key>
<value> <string>Measure Cell</string> </value>
</item>
<item>
<key> <string>cell_range</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list/>
</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> <int>1</int> </value>
</item>
<item>
<key> <string>editable_attributes</string> </key>
<value>
<list>
<tuple>
<string>quantity</string>
<string>quantity</string>
</tuple>
<tuple>
<string>predicate_category_list</string>
<string>predicate_category_list</string>
</tuple>
</list>
</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>getter_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>tabs</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>matrixbox</string> </value>
</item>
<item>
<key> <string>update_cell_range</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.getVariationRangeCategoryItemList(1)</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/getMeasureVariationBaseCategoryList</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.getVariationRangeCategoryItemList(0)</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.getVariationRangeCategoryItemList(2)</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="LinesField" module="Products.Formulator.StandardFields"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>matrixbox_predicate_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>
<item>
<key> <string>line_too_long</string> </key>
<value> <string>A line was too long.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>You entered too many characters.</string> </value>
</item>
<item>
<key> <string>too_many_lines</string> </key>
<value> <string>You entered too many lines.</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>height</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>view_separator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</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>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</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>height</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>view_separator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</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>
<list/>
</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>height</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_linelength</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>matrixbox_predicate_value</string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>view_separator</string> </key>
<value> <string encoding="cdata"><![CDATA[
<br />
]]></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>40</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell_index</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>matrixbox_quantity</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>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<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>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_quantity</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>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell is not None and cell.getQuantity() or \'\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</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_default_metric_type</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>Default Metric Type</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>items</string>
<string>size</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_measure_variation_base_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>3</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>Variation Axes</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.getResourceValue().getVariationBaseCategoryItemList(omit_optional_variation=1)</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>items</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_metric_type</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_category</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>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Metric Type</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: getattr(here.portal_categories[field.getId().split(\'_\',1)[1]], preferences.getPreference(\'preferred_category_child_item_list_method_id\', \'getCategoryChildCompactLogicalPathItemList\'))(display_none_category=1, local_sort_id=(\'int_index\', \'translated_title\'), checked_permission=\'View\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_quantity</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_quantity</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>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>default</string>
<string>items</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_quantity_unit</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>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<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">AAAAAAAAAAM=</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>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_category</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>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Quantity Unit</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/getLocalQuantityUnit</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/getQuantityUnitItemList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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>kw[\'resource_uid\'] = context.ResourceModule_getSelection().getUidList()\n
\n
if kw.setdefault(\'inventory_list\', 1):\n
kw.update(group_by_node = 1, group_by_resource = 0)\n
else:\n
kw.update(ignore_group_by = 1)\n
\n
return context.getPortalObject().portal_simulation \\\n
.getConvertedInventoryList(simulation_period=\'All\', **kw)\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>kw</string>
<string>_getattr_</string>
<string>context</string>
<string>_write_</string>
<string>_apply_</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ResourceModule_getConvertedInventoryList</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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>return context.ResourceModule_getConvertedInventoryList(inventory_list=0, **kw)\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>kw</string>
<string>_apply_</string>
<string>_getattr_</string>
<string>context</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ResourceModule_getConvertedInventoryStat</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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># JM: a \'preferred_category_display_method_id\' preference would be better\n
\n
def getPreferredCategoryChildItemListMethodId():\n
return context.getPortalObject().portal_preferences.getPreference(\n
\'preferred_category_child_item_list_method_id\',\n
\'getCategoryChildCompactLogicalPathItemList\')\n
\n
def getPreferredCategoryDisplayMethodId():\n
method = \'get\' + getPreferredCategoryChildItemListMethodId() \\\n
[ len(\'getCategoryChild\') : - len(\'ItemList\') ]\n
return method == \'getTranslatedCompactTitle\' and \'getCompactTranslatedTitle\' \\\n
or method\n
\n
# Zope: waiting for __builtin__.set\n
set = lambda seq: dict((k,None) for k in seq).iterkeys()\n
\n
# Zope: waiting for __builtin__.sorted\n
def sorted(seq):\n
l = list(seq)\n
l.sort()\n
return l\n
\n
class ResourceSelection:\n
"""\n
Helper class to handle a selection of resources.\n
"""\n
def getCommonMetricTypeList(self):\n
"""\n
Get the list of metric_type categories\n
that are common to all selected resources.\n
"""\n
return [ metric_type[\'relative_url\'].split(\'/\',1)[1]\n
for metric_type in self.context.\n
ResourceModule_zGetCommonMetricTypeList(\n
resource_uid = self.getUidList()) ]\n
\n
def getCommonBaseQuantityUnitSet(self):\n
"""\n
Get the set of possible quantity_unit categories\n
for the list of metric_type returned by getCommonMetricTypeList.\n
"""\n
return set([mt.split(\'/\',1)[0] for mt in self.getCommonMetricTypeList()])\n
\n
def getCommonMetricTypeItemList(self):\n
"""\n
Similar to getCommonMetricTypeList\n
but return the categories as a list of tuples (title, id).\n
This is mostly useful in ERP5Form instances to generate selection menus.\n
"""\n
traverse = self.portal.portal_categories[\'metric_type\'].restrictedTraverse\n
display = getPreferredCategoryDisplayMethodId()\n
return sorted((getattr(traverse(metric_type),display)(), metric_type)\n
for metric_type in self.getCommonMetricTypeList())\n
\n
def getCommonQuantityUnitItemList(self):\n
"""\n
Similar to getCommonBaseQuantityUnitSet\n
but return the categories as a list of tuples (title, id).\n
This is mostly useful in ERP5Form instances to generate selection menus.\n
"""\n
traverse = self.portal.portal_categories[\'quantity_unit\'].restrictedTraverse\n
display = getPreferredCategoryChildItemListMethodId()\n
common_quantity_unit_item_list = []\n
for qu in sorted(self.getCommonBaseQuantityUnitSet()):\n
common_quantity_unit_item_list.extend(getattr(traverse(qu),display)\n
(display_none_category=0, local_sort_id=\'quantity\'))\n
return common_quantity_unit_item_list\n
\n
self = ResourceSelection()\n
self.context = context\n
self.portal = context.getPortalObject()\n
uid_list = self.portal.portal_selections \\\n
.getSelectionCheckedUidsFor(context.REQUEST.selection_name)\n
if not uid_list:\n
raise ValueError(\'No resource selected.\')\n
self.getUidList = lambda: uid_list\n
\n
return self\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>getPreferredCategoryChildItemListMethodId</string>
<string>getPreferredCategoryDisplayMethodId</string>
<string>set</string>
<string>sorted</string>
<string>ResourceSelection</string>
<string>self</string>
<string>context</string>
<string>_write_</string>
<string>_getattr_</string>
<string>portal</string>
<string>uid_list</string>
<string>ValueError</string>
<string>getUidList</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ResourceModule_getSelection</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ERP5Form" module="Products.ERP5Form.Form"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>ResourceModule_viewConvertedInventoryReportDialog</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>hidden</string>
<string>bottom</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>your_metric_type</string>
<string>your_quantity_unit</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ResourceModule_viewConvertedInventoryReportDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>ResourceModule_viewConvertedInventoryReportDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view_dialog</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>Converted Inventory Report</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>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>columns</string>
<string>list_method</string>
<string>stat_method</string>
<string>stat_columns</string>
<string>enabled</string>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</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>columns</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>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<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>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_method</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>all_editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>node_title</string>
<string>Site or Warehouse</string>
</tuple>
<tuple>
<string>current_converted_quantity</string>
<string>Current</string>
</tuple>
<tuple>
<string>available_converted_quantity</string>
<string>Available</string>
</tuple>
<tuple>
<string>future_converted_quantity</string>
<string>Future</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>stat_columns</string> </key>
<value>
<list>
<tuple>
<string>current_converted_quantity</string>
<string>current_converted_quantity</string>
</tuple>
<tuple>
<string>available_converted_quantity</string>
<string>available_converted_quantity</string>
</tuple>
<tuple>
<string>future_converted_quantity</string>
<string>future_converted_quantity</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</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>Stock</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: (lambda mt, qu: mt and qu and mt.split(\'/\')[0] == qu.split(\'/\')[0])(request.get(\'metric_type\'), request.get(\'quantity_unit\'))</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="Method" module="Products.Formulator.MethodField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>ResourceModule_getConvertedInventoryList</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<tuple>
<global name="Method" module="Products.Formulator.MethodField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>ResourceModule_getConvertedInventoryStat</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>items</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_metric_type</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_category</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>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Metric Type</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.ResourceModule_getSelection().getCommonMetricTypeItemList()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>items</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_quantity_unit</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_category</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>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Quantity Unit</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.ResourceModule_getSelection().getCommonQuantityUnitItemList()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<value> <value>
<list> <list>
<string>title</string> <string>title</string>
<string>items</string>
</list> </list>
</value> </value>
</item> </item>
...@@ -63,6 +64,12 @@ ...@@ -63,6 +64,12 @@
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>items</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -86,6 +93,12 @@ ...@@ -86,6 +93,12 @@
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value> <value> <string>Base_viewFieldLibrary</string> </value>
</item> </item>
<item>
<key> <string>items</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
...@@ -100,4 +113,20 @@ ...@@ -100,4 +113,20 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: here.portal_categories[\'quantity_unit\'].getCategoryChildCompactLogicalPathItemList(local_sort_id=(\'int_index\', \'translated_title\'), checked_permission=\'View\', filter_node=1)</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData> </ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ERP5Form" module="Products.ERP5Form.Form"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</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>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_quantity_unit</string>
<string>listbox_quantity</string>
<string>listbox_default_metric_type</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_quantity_unit_list</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Resource_viewMeasure</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Product_viewQuantityUnit</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></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>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>columns</string>
<string>selection_name</string>
<string>portal_types</string>
<string>default_params</string>
<string>anchor</string>
<string>editable_columns</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</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>anchor</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>metric_type_logical_path</string>
<string>Metric Type</string>
</tuple>
<tuple>
<string>quantity_unit</string>
<string>Quantity Unit</string>
</tuple>
<tuple>
<string>quantity</string>
<string>Quantity</string>
</tuple>
<tuple>
<string>default_metric_type</string>
<string>Default</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>default_params</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list>
<tuple>
<string>quantity_unit</string>
<string>quantity_unit</string>
</tuple>
<tuple>
<string>quantity</string>
<string>quantity</string>
</tuple>
<tuple>
<string>default_metric_type</string>
<string>default_metric_type</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>Measure</string>
<string>Measure</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>product_measure_selection</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>Measures</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_default_metric_type</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>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_quantity</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_quantity</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Measure_view</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>items</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_quantity_unit</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>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<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">AAAAAAAAAAM=</string> </persistent>
</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>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_quantity_unit</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Measure_view</string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>cell/getLocalQuantityUnit</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>cell/getQuantityUnitItemList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_quantity_unit_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>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_quantity_unit_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Product_view</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="InteractionWorkflowDefinition" module="Products.ERP5.InteractionWorkflow"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>measure_interaction_workflow</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="Interaction" module="Products.ERP5.Interaction"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interactions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>Measure_reindexResource</string>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Measure_updateCatalog</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>unindexObject</string>
<string>reindexObject</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="Scripts" module="Products.DCWorkflow.Scripts"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>scripts</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</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>state_change[\'object\'].getResourceValue().reindexObject()\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>state_change</string>
<string>_getattr_</string>
<string>_getitem_</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Measure_reindexResource</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="Variables" module="Products.DCWorkflow.Variables"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variables</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="Worklists" module="Products.DCWorkflow.Worklists"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklists</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
112 113
\ No newline at end of file \ No newline at end of file
Component Individual Variation | view Component Individual Variation | view
Component Module | converted_inventory_report
Component Module | view Component Module | view
Component | purchase_price_view Component | purchase_price_view
Component | sale_price_view Component | sale_price_view
Component | view Component | view
Component | view_flow_capacity Component | view_flow_capacity
Component | view_measure
Preference | pdm_preference
Product Individual Variation | view Product Individual Variation | view
Product Module | converted_inventory_report
Product Module | view Product Module | view
Product | purchase_price_view Product | purchase_price_view
Product | sale_price_view Product | sale_price_view
Product | view Product | view
Product | view_measure
Product | view_stock Product | view_stock
Purchase Supply Line | additional_price Purchase Supply Line | additional_price
Purchase Supply Line | base_price Purchase Supply Line | base_price
...@@ -31,10 +36,12 @@ Sale Supply Line | view ...@@ -31,10 +36,12 @@ Sale Supply Line | view
Sale Supply Module | view Sale Supply Module | view
Sale Supply | view Sale Supply | view
Service Individual Variation | view Service Individual Variation | view
Service Module | converted_inventory_report
Service Module | view Service Module | view
Service | purchase_price_view Service | purchase_price_view
Service | sale_price_view Service | sale_price_view
Service | view Service | view
Service | view_measure
Supply Line | additional_price Supply Line | additional_price
Supply Line | base_price Supply Line | base_price
Supply Line | discount_ratio Supply Line | discount_ratio
...@@ -43,7 +50,6 @@ Supply Line | non_discountable_additional_price ...@@ -43,7 +50,6 @@ Supply Line | non_discountable_additional_price
Supply Line | surcharge_ratio Supply Line | surcharge_ratio
Supply Line | variable_additional_price Supply Line | variable_additional_price
Supply Line | view Supply Line | view
System Preference | pdm_preference
Transformation Module | view Transformation Module | view
Transformation Operation | complete_quantity_matrix Transformation Operation | complete_quantity_matrix
Transformation Operation | view Transformation Operation | view
......
...@@ -7,6 +7,7 @@ feature ...@@ -7,6 +7,7 @@ feature
image image
industrial_phase industrial_phase
measure measure
metric_type
morphology morphology
operation operation
option option
......
Component Module | Component Component Module | Component
Component | Component Individual Variation Component | Component Individual Variation
Component | Image Component | Image
Component | Measure
Component | Purchase Supply Line Component | Purchase Supply Line
Component | Sale Supply Line Component | Sale Supply Line
Component | Supply Line Component | Supply Line
Measure | Measure Cell
Product Module | Product Product Module | Product
Product | Image Product | Image
Product | Measure
Product | Product Individual Variation Product | Product Individual Variation
Product | Purchase Supply Line Product | Purchase Supply Line
Product | Sale Supply Line Product | Sale Supply Line
...@@ -21,6 +24,7 @@ Sale Supply Module | Sale Supply ...@@ -21,6 +24,7 @@ Sale Supply Module | Sale Supply
Sale Supply | Sale Supply Line Sale Supply | Sale Supply Line
Sale Supply | Supply Line Sale Supply | Supply Line
Service Module | Service Service Module | Service
Service | Measure
Service | Purchase Supply Line Service | Purchase Supply Line
Service | Sale Supply Line Service | Sale Supply Line
Service | Service Individual Variation Service | Service Individual Variation
......
...@@ -2,6 +2,7 @@ Component | Image ...@@ -2,6 +2,7 @@ Component | Image
Component | Purchase Supply Line Component | Purchase Supply Line
Component | Sale Supply Line Component | Sale Supply Line
Component | Supply Line Component | Supply Line
Measure | Measure Cell
Product | Image Product | Image
Product | Purchase Supply Line Product | Purchase Supply Line
Product | Sale Supply Line Product | Sale Supply Line
......
Component Component
Component Individual Variation Component Individual Variation
Component Module Component Module
Measure
Measure Cell
Product Product
Product Individual Variation Product Individual Variation
Product Module Product Module
......
Component | edit_workflow Component | edit_workflow
Component | validation_workflow Component | validation_workflow
Measure | edit_workflow
Measure | measure_interaction_workflow
Product | edit_workflow Product | edit_workflow
Product | validation_workflow Product | validation_workflow
Purchase Supply Line | edit_workflow Purchase Supply Line | edit_workflow
......
measure_interaction_workflow
supply_line_interaction_workflow supply_line_interaction_workflow
\ No newline at end of file
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
#
# 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 Products.ERP5Type.Constraint import Constraint
class ResourceMeasuresConsistency(Constraint):
"""Check that measures defined on a resource are not meaningless.
Choosing quantity units for a resource without defining measures is
tolerated, for compatibility, although conversion between units won't be
possible.
"""
_message_id_list = ['message_measure_no_quantity_unit',
'message_measure_no_quantity',
'message_duplicate_metric_type',
'message_duplicate_default_measure',
'message_missing_metric_type']
_message_measure = "Measure for metric_type '${metric_type}' "
message_measure_no_quantity_unit = \
_message_measure + "doesn't have a valid quantity_unit"
message_measure_no_quantity = \
_message_measure + "doesn't have a valid quantity value"
message_duplicate_metric_type = \
"Several measures have the same metric_type '${metric_type}'"
message_duplicate_default_measure = \
"Several measures are associated to the same unit '${quantity_unit}'"
message_missing_metric_type = \
"Implicit measure for the management unit can't be created" \
" because 'metric_type/${metric_type}' category doesn't exist."
def checkConsistency(self, obj, fixit=0):
"""Implement here the consistency checker
"""
error_list = []
portal = obj.getPortalObject()
if obj.getPortalType() not in portal.getPortalResourceTypeList():
return error_list
error = lambda msg, **kw: error_list.append(
self._generateError(obj, self._getMessage(msg), mapping=kw))
getCategoryValue = portal.portal_categories.getCategoryValue
display = lambda *args, **kw: \
getCategoryValue(*args, **kw).getCompactLogicalPath()
top = lambda relative_url: relative_url.split('/', 1)[0]
quantity_map = {}
metric_type_set = set()
for measure in obj.getMeasureList():
metric_type = measure.getMetricType()
if metric_type:
quantity = top(metric_type)
default_or_generic = quantity_map.setdefault(quantity, [0, 0])
if measure.getDefaultMetricType():
default_or_generic[0] += 1
if quantity == metric_type:
default_or_generic[1] += 1
if not measure.getConvertedQuantityUnit():
error('message_measure_no_quantity_unit',
metric_type=display(metric_type, 'metric_type'))
elif not measure.asCatalogRowList():
error('message_measure_no_quantity',
metric_type=display(metric_type, 'metric_type'))
if metric_type in metric_type_set:
error('message_duplicate_metric_type',
metric_type=display(metric_type, 'metric_type'))
else:
metric_type_set.add(metric_type)
#else:
# pass # we don't care about undefined measures
for i, quantity_unit in enumerate(obj.getQuantityUnitList()):
quantity = top(quantity_unit)
default, generic = quantity_map.get(quantity, (0, 0))
if (default or generic) > 1:
error('message_duplicate_default_measure',
quantity_unit=display(quantity_unit, 'quantity_unit'))
elif not (default or generic):
if i:
pass # tolerate quantity units without any measure associated to them
else: # management unit: check we can create an implicit measure
if getCategoryValue(quantity, 'metric_type') is None:
error('message_missing_metric_type', metric_type=quantity)
return error_list
...@@ -405,17 +405,10 @@ class Amount(Base, Variated): ...@@ -405,17 +405,10 @@ class Amount(Base, Variated):
Price is defined on Price is defined on
""" """
result = None price = self.getResourcePrice()
efficiency = self.getEfficiency() quantity = self.getNetConvertedQuantity()
if efficiency != 0: if isinstance(price, (int, float)) and isinstance(quantity, (int, float)):
resource_price = self.getResourcePrice() return quantity * price
if resource_price is not None:
return resource_price * self.getConvertedQuantity() / efficiency
price = self.getPrice()
quantity = self.getQuantity()
if type(price) in (type(1.0), type(1)) and type(quantity) in (type(1.0), type(1)):
result = quantity * price
return result
# Conversion to standard unit # Conversion to standard unit
security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedQuantity') security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedQuantity')
...@@ -426,25 +419,26 @@ class Amount(Base, Variated): ...@@ -426,25 +419,26 @@ class Amount(Base, Variated):
resource = self.getResourceValue() resource = self.getResourceValue()
quantity_unit = self.getQuantityUnit() quantity_unit = self.getQuantityUnit()
quantity = self.getQuantity() quantity = self.getQuantity()
converted_quantity = None if quantity is not None and quantity_unit and resource is not None:
if resource is not None: converted = resource.convertQuantity(quantity, quantity_unit,
resource_quantity_unit = resource.getDefaultQuantityUnit() resource.getDefaultQuantityUnit(),
converted_quantity = resource.convertQuantity(quantity, quantity_unit, resource_quantity_unit) self.getVariationCategoryList())
else: # For compatibility, return quantity non-converted if conversion fails.
#LOG("ERP5 WARNING:", 100, 'could not convert quantity for %s' % self.getRelativeUrl()) if converted is not None:
pass return converted
return converted_quantity return quantity
security.declareProtected(Permissions.ModifyPortalContent, 'setConvertedQuantity') security.declareProtected(Permissions.ModifyPortalContent, 'setConvertedQuantity')
def setConvertedQuantity(self, value): def setConvertedQuantity(self, value):
resource = self.getResourceValue() resource = self.getResourceValue()
quantity_unit = self.getQuantityUnit() quantity_unit = self.getQuantityUnit()
if resource is not None: if value is not None and quantity_unit and resource is not None:
resource_quantity_unit = resource.getDefaultQuantityUnit() quantity = resource.convertQuantity(value,
quantity = resource.convertQuantity(value, resource_quantity_unit, quantity_unit) resource.getDefaultQuantityUnit(),
self.setQuantity(quantity) quantity_unit,
else: self.getVariationCategoryList())
LOG("ERP5 WARNING:", 100, 'could not set converted quantity for %s' % self.getRelativeUrl()) if quantity is not None:
return self.setQuantity(quantity)
security.declareProtected(Permissions.AccessContentsInformation, 'getNetQuantity') security.declareProtected(Permissions.AccessContentsInformation, 'getNetQuantity')
def getNetQuantity(self): def getNetQuantity(self):
......
...@@ -63,7 +63,9 @@ class Currency(Resource): ...@@ -63,7 +63,9 @@ class Currency(Resource):
# Unit conversion # Unit conversion
security.declareProtected(Permissions.AccessContentsInformation, 'convertQuantity') security.declareProtected(Permissions.AccessContentsInformation, 'convertQuantity')
def convertQuantity(self, quantity, from_unit, to_unit): def convertQuantity(self, quantity, from_unit, to_unit, variation_list=()):
# 'variation_list' parameter may be deprecated:
# cf Measure.getConvertedQuantity
return quantity return quantity
security.declareProtected(Permissions.AccessContentsInformation, 'convertCurrency') security.declareProtected(Permissions.AccessContentsInformation, 'convertCurrency')
......
##############################################################################
#
# Copyright (c) 2008 Nexedi SARL and Contributors. All Rights Reserved.
#
# 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 PropertySheet
from Products.ERP5Type.Permissions import AccessContentsInformation
from Products.ERP5Type.XMLMatrix import XMLMatrix
from Products.ERP5.Variated import Variated
class Measure(XMLMatrix):
"""
A Measure
"""
meta_type = 'ERP5 Measure'
portal_type = 'Measure'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.Measure
)
security.declareProtected(AccessContentsInformation, 'getResourceValue')
def getResourceValue(self):
"""
Gets the resource object described by this measure.
"""
return self.getDefaultResourceValue()
##
# Forms.
security.declareProtected(AccessContentsInformation, 'getVariationRangeCategoryItemList')
def getVariationRangeCategoryItemList(self, variation):
"""
Returns possible variation category values for the selected variation.
variation is a 0-based index and possible category values is provided
as a list of tuples (id, title). This is mostly useful for matrixbox.
"""
mvbc_list = self.getMeasureVariationBaseCategoryList()
if len(mvbc_list) <= variation:
return ()
return self.getResourceValue().getVariationCategoryItemList(
is_right_display=1,
base_category_list=(mvbc_list[variation],),
omit_individual_variation=0,
display_base_category=0,
sort_id='id')
security.declareProtected(AccessContentsInformation, 'getQuantityUnitItemList')
def getQuantityUnitItemList(self):
"""
Returns the list of possible quantity units for the current metric type.
This is mostly useful in ERP5Form instances to generate selection menus.
"""
metric_type = self.getMetricType()
if not metric_type:
return ('', ''),
portal = self.getPortalObject()
return getattr(
portal.portal_categories.getCategoryValue(metric_type.split('/', 1)[0],
'quantity_unit'),
portal.portal_preferences.getPreference(
'preferred_category_child_item_list_method_id',
'getCategoryChildCompactLogicalPathItemList')
)(recursive=0, local_sort_id='quantity', checked_permission='View')
security.declareProtected(AccessContentsInformation, 'getLocalQuantityUnit')
def getLocalQuantityUnit(self):
"""
Returns the 'quantity_unit' category without acquisition.
Used in Resource_viewMeasure and Measure_view.
"""
quantity_unit_list = self.getPortalObject().portal_categories \
.getSingleCategoryMembershipList(self, 'quantity_unit')
if quantity_unit_list:
return quantity_unit_list[0]
##
# Measures associated to a quantity unit of the resource
# have a specific behaviour.
security.declareProtected(AccessContentsInformation, 'isDefaultMeasure')
def isDefaultMeasure(self, quantity_unit=None):
"""
Checks if self is a default measure for the associated resource.
"""
default = self.getResourceValue().getDefaultMeasure(quantity_unit)
return default is not None \
and self.getRelativeUrl() == default.getRelativeUrl()
##
# Conversion.
security.declareProtected(AccessContentsInformation, 'getConvertedQuantityUnit')
def getConvertedQuantityUnit(self):
"""
Gets the quantity unit ratio, in respect to the base quantity unit.
"""
quantity_unit = self.getQuantityUnitValue()
metric_type = self.getMetricType()
if quantity_unit is not None and metric_type and \
quantity_unit.getParentId() == metric_type.split('/', 1)[0]:
return quantity_unit.getProperty('quantity')
security.declareProtected(AccessContentsInformation, 'getConvertedQuantity')
def getConvertedQuantity(self, variation_list=()):
"""
Gets the measure value for a specified variation,
in respected to the base quantity unit.
Should it be reimplemented using predicates?
If so, 'variation_list' parameter is deprecated.
"""
quantity_unit = self.getConvertedQuantityUnit()
if not quantity_unit:
return
quantity = self.getQuantity()
if variation_list:
variation_set = set(variation_list)
for cell in self.objectValues():
# if cell.test(context): # XXX
if variation_set.issuperset(
cell.getMembershipCriterionCategoryList()):
quantity = cell.getQuantity()
break
return quantity * quantity_unit
##
# Cataloging.
security.declareProtected(AccessContentsInformation, 'asCatalogRowList')
def asCatalogRowList(self):
"""
Returns the list of rows to insert in the measure table of the catalog.
Called by Resource.getMeasureRowList.
"""
quantity_unit = self.getConvertedQuantityUnit()
if not quantity_unit:
return ()
uid = self.getUid()
resource = self.getResourceValue()
resource_uid = resource.getUid()
metric_type_uid = self.getMetricTypeUid()
quantity = self.getQuantity()
# The only purpose of the defining a default measure explicitly is to
# set a specific metric_type for the management unit.
# Therefore, the measure mustn't be variated and the described quantity
# (quantity * quantity_unit) must match the management unit.
# If the conditions aren't met, return an empty list.
default = self.isDefaultMeasure()
measure_variation_base_category_list = \
self.getMeasureVariationBaseCategoryList()
if not measure_variation_base_category_list:
# Easy case: there is no variation axe for this metric_type,
# so we simply return 1 row.
if quantity is not None:
quantity *= quantity_unit
if (not default or quantity ==
resource.getQuantityUnitValue().getProperty('quantity')):
return (uid, resource_uid, '^', metric_type_uid, quantity),
return ()
if default:
return ()
# 1st step: Build a list of possible variation combinations.
# Each element of the list (variation_list) is a pair of lists, where:
# * first list's elements are regex tokens:
# they'll be used to build the 'variation' values (in the result).
# * the second list is a combination of categories, used to find
# the measure cells containing the 'quantity' values.
#
# This step is done by starting from a 1-element list (variation_list).
# For each variation axe (if variation_base_category in
# measure_variation_base_category_list), we rebuild variation_list entirely
# and its size is multiplied by the number of categories in this axe.
# For other varation base categories (variation_base_category not in
# measure_variation_base_category_list), we simply
# update variation_list to add 1 regex token to each regex list.
#
# Example:
# * variation base categories: colour, logo, size
# * variation axes: colour, size
#
# variation_list (tokens are simplified for readability):
# 0. []
# 1. [([colour/red], ['colour/red']),
# ([colour/green], ['colour/green']),
# ([colour/blue], ['colour/blue'])]
# 2. [([colour/red, logo/*], ['colour/red']),
# ([colour/green, logo/*], ['colour/green']),
# ([colour/blue, logo/*], ['colour/blue'])]
# 3. [([colour/red, logo/*, size/small], ['colour/red', 'size/small']),
# ([colour/green, logo/*, size/small], ['colour/green', 'size/small']),
# ([colour/blue, logo/*, size/small], ['colour/blue', 'size/small']),
# ([colour/red, logo/*, size/medium], ['colour/red', 'size/medium']),
# ([colour/green, logo/*, size/medium], ['colour/green', 'size/medium']),
# ([colour/blue, logo/*, size/medium], ['colour/blue', 'size/medium']),
# ([colour/red, logo/*, size/big], ['colour/red', 'size/big']),
# ([colour/green, logo/*, size/big], ['colour/green', 'size/big']),
# ([colour/blue, logo/*, size/big], ['colour/blue', 'size/big'])]
# Note that from this point, we always work with sorted lists of
# categories (or regex tokens).
variation_list = ([], []),
optional_variation_base_category_set = \
set(resource.getOptionalVariationBaseCategoryList())
for variation_base_category in sorted(
resource.getVariationBaseCategoryList(omit_optional_variation=0)):
if variation_base_category in measure_variation_base_category_list:
# This is where we rebuild variation_list entirely. Size of
# variation_list is multiplied by len(getVariationCategoryList).
# The lists of each pairs in variation_list get one more element:
# variation_category.
variation_list = [(regex_list + [variation_category + '\n'],
variation_base_category_list + [variation_category])
for variation_category in resource.getVariationCategoryList(
base_category_list=(variation_base_category,),
omit_individual_variation=0)
for regex_list, variation_base_category_list in variation_list]
else:
variation_base_category_regex = variation_base_category + '/[^\n]+\n'
if variation_base_category in optional_variation_base_category_set:
variation_base_category_regex = \
'(%s)*' % (variation_base_category_regex, )
for regex_list, variation_base_category_list in variation_list:
regex_list.append(variation_base_category_regex)
# 2nd step: Retrieve all measure cells in a dictionary for fast lookup.
cell_map = {}
for cell in self.objectValues():
cell_map[tuple(sorted(cell.getMembershipCriterionCategoryList()))] \
= cell.getQuantity()
# 3rd step: Build the list of rows to return,
# by merging variation_list (1st step) and cell_map (2nd step).
row_list = []
for regex_list, variation_base_category_list in variation_list:
cell = cell_map.get(tuple(variation_base_category_list))
if cell is None:
if quantity is None:
continue
cell = quantity
row_list.append((uid,
resource_uid,
'^%s$' % ''.join(regex_list),
metric_type_uid,
cell * quantity_unit))
return row_list
...@@ -199,9 +199,18 @@ class Movement(XMLObject, Amount): ...@@ -199,9 +199,18 @@ class Movement(XMLObject, Amount):
# _getPrice is defined in the order / delivery # _getPrice is defined in the order / delivery
# Pricing mehod # Pricing mehod
def _getPrice(self, context): def _getPrice(self, context):
context = self.asContext(context=context,
quantity=self.getConvertedQuantity())
operand_dict = self.getPriceCalculationOperandDict(context=context) operand_dict = self.getPriceCalculationOperandDict(context=context)
if operand_dict is not None: if operand_dict is not None:
return operand_dict['price'] price = operand_dict['price']
resource = self.getResourceValue()
quantity_unit = self.getQuantityUnit()
if price is not None and quantity_unit and resource is not None:
return resource.convertQuantity(price, quantity_unit,
resource.getDefaultQuantityUnit(),
self.getVariationCategoryList())
return price
def _getTotalPrice(self, default=None, context=None, fast=0): def _getTotalPrice(self, default=None, context=None, fast=0):
price = self.getPrice(context=context) price = self.getPrice(context=context)
......
...@@ -252,11 +252,6 @@ class Resource(XMLMatrix, Variated): ...@@ -252,11 +252,6 @@ class Resource(XMLMatrix, Variated):
omit_individual_variation=omit_individual_variation,**kw) omit_individual_variation=omit_individual_variation,**kw)
return [x[1] for x in vcil] return [x[1] for x in vcil]
# Unit conversion
security.declareProtected(Permissions.AccessContentsInformation, 'convertQuantity')
def convertQuantity(self, quantity, from_unit, to_unit):
return quantity
# This patch is temporary and allows to circumvent name conflict in ZSQLCatalog process for Coramy # This patch is temporary and allows to circumvent name conflict in ZSQLCatalog process for Coramy
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultDestinationAmountBis') 'getDefaultDestinationAmountBis')
...@@ -783,3 +778,120 @@ class Resource(XMLMatrix, Variated): ...@@ -783,3 +778,120 @@ class Resource(XMLMatrix, Variated):
except TypeError: except TypeError:
return 0 return 0
return 0 return 0
def _getConversionRatio(self, quantity_unit, variation_list):
"""
Converts a quantity unit into a ratio in respect to the resource's
management unit, for the specified variation.
A quantity can be multiplied by the returned value in order to convert it
in the management unit.
'variation_list' parameter may be deprecated:
cf Measure.getConvertedQuantity
"""
management_unit = self.getDefaultQuantityUnit()
if management_unit == quantity_unit:
return 1.0
traverse = self.portal_categories['quantity_unit'].unrestrictedTraverse
quantity = traverse(quantity_unit).getProperty('quantity')
if quantity_unit.split('/', 1)[0] != management_unit.split('/', 1)[0]:
measure = self.getDefaultMeasure(quantity_unit)
quantity /= measure.getConvertedQuantity(variation_list)
else:
quantity /= traverse(management_unit).getProperty('quantity')
return quantity
# Unit conversion
security.declareProtected(Permissions.AccessContentsInformation, 'convertQuantity')
def convertQuantity(self, quantity, from_unit, to_unit, variation_list=()):
# 'variation_list' parameter may be deprecated:
# cf Measure.getConvertedQuantity
try:
return quantity * self._getConversionRatio(from_unit, variation_list) \
/ self._getConversionRatio(to_unit, variation_list)
except (ArithmeticError, AttributeError, LookupError, TypeError), error:
# For compatibility, we only log the error and return None.
# No exception for the moment.
LOG('Resource.convertQuantity', WARNING,
'could not convert quantity for %s (%r)'
% (self.getRelativeUrl(), error))
security.declareProtected(Permissions.AccessContentsInformation,
'getMeasureList')
def getMeasureList(self):
"""
Gets the list of Measure objects describing this resource.
"""
return self.objectValues(portal_type='Measure')
security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultMeasure')
def getDefaultMeasure(self, quantity_unit=None):
"""
Returns the measure object associated to quantity_unit.
If no quantity_unit is specified, the quantity_unit of the resource is used.
None is returned if the number of found measures differs from 1.
"""
if quantity_unit is None:
quantity_unit = self.getQuantityUnit()
if quantity_unit:
top = lambda relative_url: relative_url.split('/', 1)[0]
quantity = top(quantity_unit)
generic = []
default = []
for measure in self.getMeasureList():
metric_type = measure.getMetricType()
if metric_type and quantity == top(metric_type) and \
measure.getDefaultMetricType():
default.append(measure)
if quantity == metric_type:
generic.append(measure)
result = default or generic
if len(result) == 1:
return result[0]
security.declareProtected(Permissions.AccessContentsInformation,
'getMeasureRowList')
def getMeasureRowList(self):
"""
Returns a list rows to insert in the measure table.
Used by z_catalog_measure_list.
"""
quantity_unit_value = self.getQuantityUnitValue()
if quantity_unit_value is None:
return ()
quantity_unit = quantity_unit_value.getCategoryRelativeUrl()
default = self.getDefaultMeasure(quantity_unit)
if default is not None:
default = default.getRelativeUrl()
metric_type_map = {} # duplicate metric_type are not valid
for measure in self.getMeasureList():
metric_type = measure.getMetricType()
if metric_type in metric_type_map:
metric_type_map[metric_type] = ()
else:
metric_type_map[metric_type] = measure.asCatalogRowList()
if measure.getRelativeUrl() == default:
quantity_unit = ''
insert_list = []
for measure_list in metric_type_map.itervalues():
insert_list += measure_list
metric_type = quantity_unit.split('/', 1)[0]
if metric_type and metric_type not in metric_type_map:
# At this point, we know there is no default measure and we must add
# a row for the management unit, with the resource's uid as uid, and
# a generic metric_type.
quantity = quantity_unit_value.getProperty('quantity')
metric_type_uid = self.getPortalObject().portal_categories \
.getCategoryUid(metric_type, 'metric_type')
if quantity and metric_type_uid:
uid = self.getUid()
insert_list += (uid, uid, '^', metric_type_uid, quantity),
return insert_list
##############################################################################
#
# Copyright (c) 2008 Nexedi SARL and Contributors. All Rights Reserved.
#
# 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.
#
##############################################################################
class Measure:
_properties = (
{ 'id' : 'quantity',
'description' : "Value of the measure, expressed in the selected quantity unit.",
'type' : 'float',
'mode' : 'w' },
{ 'id' : 'measure_variation_base_category',
'description' : "Base category range of matrix.",
'type' : 'tokens',
'mode' : 'w' },
{ 'id' : 'default_metric_type',
'description' : "Use this measure by default to perform unit conversion\n"
"(useful in cases where only a quantity unit is specified).",
'type' : 'boolean',
'mode' : 'w' },
)
_categories = ( 'metric_type', 'quantity_unit' )
...@@ -179,6 +179,13 @@ class Resource: ...@@ -179,6 +179,13 @@ class Resource:
) )
_constraints = (
{ 'id': 'resource_measures_consistency',
'description': '',
'type': 'ResourceMeasuresConsistency',
},
)
_categories = ( 'source', 'destination', 'quantity_unit', 'price_unit', _categories = ( 'source', 'destination', 'quantity_unit', 'price_unit',
'weight_unit', 'length_unit', 'height_unit', 'width_unit', 'weight_unit', 'length_unit', 'height_unit', 'width_unit',
'volume_unit', 'volume_unit',
......
...@@ -49,6 +49,7 @@ from Products.PythonScripts.Utility import allow_class ...@@ -49,6 +49,7 @@ from Products.PythonScripts.Utility import allow_class
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, QueryMixin from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, QueryMixin
from Shared.DC.ZRDB.Results import Results from Shared.DC.ZRDB.Results import Results
from Products.ERP5Type.Utils import mergeZRDBResults
class SimulationTool(BaseTool): class SimulationTool(BaseTool):
""" """
...@@ -878,7 +879,8 @@ class SimulationTool(BaseTool): ...@@ -878,7 +879,8 @@ class SimulationTool(BaseTool):
default_stock_table='stock', default_stock_table='stock',
selection_domain=None, selection_report=None, selection_domain=None, selection_report=None,
statistic=0, inventory_list=1, statistic=0, inventory_list=1,
precision=None, connection_id=None, **kw): precision=None, connection_id=None,
quantity_unit=None, **kw):
""" """
Returns a list of inventories for a single or multiple Returns a list of inventories for a single or multiple
resources on a single or multiple nodes, grouped by resource, resources on a single or multiple nodes, grouped by resource,
...@@ -1058,6 +1060,7 @@ class SimulationTool(BaseTool): ...@@ -1058,6 +1060,7 @@ class SimulationTool(BaseTool):
assert isinstance(where_query, basestring) and len(where_query) assert isinstance(where_query, basestring) and len(where_query)
stock_sql_kw['where_expression'] = '(%s) AND (%s)' % \ stock_sql_kw['where_expression'] = '(%s) AND (%s)' % \
(where_query, greater_than_date_query) (where_query, greater_than_date_query)
LOG(None, 0, 'optimisation_success = True')
# Get initial inventory amount # Get initial inventory amount
initial_inventory_line_list = self.Resource_zGetInventoryList( initial_inventory_line_list = self.Resource_zGetInventoryList(
stock_table_id=EQUAL_DATE_TABLE_ID, stock_table_id=EQUAL_DATE_TABLE_ID,
...@@ -1066,7 +1069,8 @@ class SimulationTool(BaseTool): ...@@ -1066,7 +1069,8 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain, selection_domain=selection_domain,
selection_report=selection_report, precision=precision, selection_report=selection_report, precision=precision,
inventory_list=inventory_list, inventory_list=inventory_list,
statistic=statistic, **inventory_stock_sql_kw) statistic=statistic, quantity_unit=quantity_unit,
**inventory_stock_sql_kw)
# Get delta inventory # Get delta inventory
delta_inventory_line_list = self.Resource_zGetInventoryList( delta_inventory_line_list = self.Resource_zGetInventoryList(
stock_table_id=GREATER_THAN_DATE_TABLE_ID, stock_table_id=GREATER_THAN_DATE_TABLE_ID,
...@@ -1075,7 +1079,8 @@ class SimulationTool(BaseTool): ...@@ -1075,7 +1079,8 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain, selection_domain=selection_domain,
selection_report=selection_report, precision=precision, selection_report=selection_report, precision=precision,
inventory_list=inventory_list, inventory_list=inventory_list,
statistic=statistic, **stock_sql_kw) statistic=statistic, quantity_unit=quantity_unit,
**stock_sql_kw)
# Match & add initial and delta inventories # Match & add initial and delta inventories
if src__: if src__:
sql_source_list.extend((initial_inventory_line_list, sql_source_list.extend((initial_inventory_line_list,
...@@ -1104,6 +1109,8 @@ class SimulationTool(BaseTool): ...@@ -1104,6 +1109,8 @@ class SimulationTool(BaseTool):
result_column_id_dict['inventory'] = None result_column_id_dict['inventory'] = None
result_column_id_dict['total_quantity'] = None result_column_id_dict['total_quantity'] = None
result_column_id_dict['total_price'] = None result_column_id_dict['total_price'] = None
if quantity_unit:
result_column_id_dict['converted_quantity'] = None
def addLineValues(line_a=None, line_b=None): def addLineValues(line_a=None, line_b=None):
""" """
Addition columns of 2 lines and return a line with same Addition columns of 2 lines and return a line with same
...@@ -1189,13 +1196,73 @@ class SimulationTool(BaseTool): ...@@ -1189,13 +1196,73 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain, selection_domain=selection_domain,
selection_report=selection_report, precision=precision, selection_report=selection_report, precision=precision,
inventory_list=inventory_list, connection_id=connection_id, inventory_list=inventory_list, connection_id=connection_id,
statistic=statistic, **stock_sql_kw) statistic=statistic, quantity_unit=quantity_unit,
**stock_sql_kw)
if src__: if src__:
sql_source_list.append(result) sql_source_list.append(result)
if src__: if src__:
result = ';\n-- NEXT QUERY\n'.join(sql_source_list) result = ';\n-- NEXT QUERY\n'.join(sql_source_list)
return result return result
security.declareProtected(Permissions.AccessContentsInformation,
'getConvertedInventoryList')
def getConvertedInventoryList(self, metric_type, quantity_unit=1,
simulation_period='', **kw):
"""
Return list of inventory with a 'converted_quantity' additional column,
which contains the sum of measurements for the specified metric type,
expressed in the 'quantity_unit' unit.
metric_type - category relative url
quantity_unit - int, float or category relative url
"""
getCategory = self.getPortalObject().portal_categories.getCategoryValue
kw['metric_type_uid'] = Query(
metric_type_uid=getCategory(metric_type, 'metric_type').getUid(),
table_alias_list=(("measure", "measure"),))
if isinstance(quantity_unit, str):
quantity_unit = getCategory(quantity_unit,
'quantity_unit').getProperty('quantity')
method = getattr(self,'get%sInventoryList' % simulation_period)
return method(quantity_unit=quantity_unit, **kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getAllInventoryList')
def getAllInventoryList(self, src__=0, **kw):
"""
Returns list of inventory, for all periods.
Performs 1 SQL request for each simulation state, and merge the results.
Rename relevant columns with a '${simulation}_' prefix
(ex: 'total_price' -> 'current_total_price').
"""
columns = ('total_quantity', 'total_price', 'converted_quantity')
# Guess the columns to use to identify each row, by looking at the GROUP
# clause. Note that the call to 'mergeZRDBResults' will crash if the GROUP
# clause contains a column not requested in the SELECT clause.
kw.update(self._getDefaultGroupByParameters(**kw), ignore_group_by=1)
group_by_list = self._generateKeywordDict(**kw)[1].get('group_by', ())
results = []
edit_result = {}
get_false_value = lambda row, column_name: row.get(column_name) or 0
for simulation in 'current', 'available', 'future':
method = getattr(self, 'get%sInventoryList' % simulation.capitalize())
rename = {'inventory': None} # inventory column is deprecated
for column in columns:
rename[column] = new_name = '%s_%s' % (simulation, column)
edit_result[new_name] = get_false_value
results += (method(src__=src__, **kw), rename),
if src__:
return ';\n-- NEXT QUERY\n'.join(r[0] for r in results)
return mergeZRDBResults(results, group_by_list, edit_result)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getCurrentInventoryList') 'getCurrentInventoryList')
def getCurrentInventoryList(self, omit_transit=1, def getCurrentInventoryList(self, omit_transit=1,
...@@ -1268,7 +1335,7 @@ class SimulationTool(BaseTool): ...@@ -1268,7 +1335,7 @@ class SimulationTool(BaseTool):
'getAvailableInventoryStat') 'getAvailableInventoryStat')
def getAvailableInventoryStat(self, **kw): def getAvailableInventoryStat(self, **kw):
""" """
Returns statistics of current inventory grouped by section or site Returns statistics of available inventory grouped by section or site
""" """
return self.getInventoryStat(simulation_period='Available', **kw) return self.getInventoryStat(simulation_period='Available', **kw)
......
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
<value> <value>
<tuple> <tuple>
<string>delivery</string> <string>delivery</string>
<string>resource</string>
<string>order</string> <string>order</string>
<string>parent</string> <string>parent</string>
<string>resource</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
...@@ -121,6 +121,7 @@ ...@@ -121,6 +121,7 @@
<string>my_codification</string> <string>my_codification</string>
<string>my_int_index</string> <string>my_int_index</string>
<string>my_translated_validation_state_title</string> <string>my_translated_validation_state_title</string>
<string>my_quantity</string>
</list> </list>
</value> </value>
</item> </item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>display_width</string>
<string>precision</string>
<string>enabled</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_quantity</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>display_width</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<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>precision</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>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_quantity</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>precision</string> </key>
<value> <int>15</int> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: max(15,int(field.getTemplateField().get_value(\'display_width\')))</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: (lambda x: x.getPortalType() == \'Base Category\' and x.getId() == \'quantity_unit\')(here.getParent().getParent())</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -118,6 +118,12 @@ ...@@ -118,6 +118,12 @@
<dictionary/> <dictionary/>
</value> </value>
</item> </item>
<item>
<key> <string>quantity_unit</string> </key>
<value>
<dictionary/>
</value>
</item>
<item> <item>
<key> <string>section_filtered</string> </key> <key> <string>section_filtered</string> </key>
<value> <value>
...@@ -189,6 +195,7 @@ ...@@ -189,6 +195,7 @@
<string>precision</string> <string>precision</string>
<string>inventory_list</string> <string>inventory_list</string>
<string>statistic</string> <string>statistic</string>
<string>quantity_unit</string>
<string>stock_table_id</string> <string>stock_table_id</string>
</list> </list>
</value> </value>
...@@ -198,6 +205,12 @@ ...@@ -198,6 +205,12 @@
</object> </object>
</value> </value>
</item> </item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>allow_simple_one_argument_traversal</string> </key> <key> <string>allow_simple_one_argument_traversal</string> </key>
<value> <value>
...@@ -223,6 +236,7 @@ output_simulation_state:list\r\n ...@@ -223,6 +236,7 @@ output_simulation_state:list\r\n
precision\r\n precision\r\n
inventory_list\r\n inventory_list\r\n
statistic\r\n statistic\r\n
quantity_unit\r\n
stock_table_id=stock</string> </value> stock_table_id=stock</string> </value>
</item> </item>
<item> <item>
...@@ -267,10 +281,18 @@ SELECT\n ...@@ -267,10 +281,18 @@ SELECT\n
<dtml-if expr="precision is not None">\n <dtml-if expr="precision is not None">\n
SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS inventory,\n SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS inventory,\n
SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS total_quantity,\n SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS total_quantity,\n
<dtml-if quantity_unit>\n
SUM(ROUND(<dtml-var stock_table_id>.quantity * measure.quantity, <dtml-var precision>))\n
/ <dtml-sqlvar quantity_unit type=float> AS converted_quantity,\n
</dtml-if>\n
SUM(ROUND(<dtml-var stock_table_id>.total_price, <dtml-var precision>)) AS total_price\n SUM(ROUND(<dtml-var stock_table_id>.total_price, <dtml-var precision>)) AS total_price\n
<dtml-else>\n <dtml-else>\n
SUM(<dtml-var stock_table_id>.quantity) AS inventory,\n SUM(<dtml-var stock_table_id>.quantity) AS inventory,\n
SUM(<dtml-var stock_table_id>.quantity) AS total_quantity,\n SUM(<dtml-var stock_table_id>.quantity) AS total_quantity,\n
<dtml-if quantity_unit>\n
ROUND(SUM(<dtml-var stock_table_id>.quantity * measure.quantity)\n
/ <dtml-sqlvar quantity_unit type=float>, 12) AS converted_quantity,\n
</dtml-if>\n
SUM(<dtml-var stock_table_id>.total_price) AS total_price\n SUM(<dtml-var stock_table_id>.total_price) AS total_price\n
</dtml-if>\n </dtml-if>\n
<dtml-if inventory_list>\n <dtml-if inventory_list>\n
...@@ -340,6 +362,12 @@ WHERE\n ...@@ -340,6 +362,12 @@ WHERE\n
<dtml-if selection_report>\n <dtml-if selection_report>\n
AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\n AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\n
</dtml-if>\n </dtml-if>\n
\n
<dtml-if quantity_unit>\n
AND concat(<dtml-var stock_table_id>.variation_text,\'\\n\') REGEXP measure.variation\n
</dtml-if>\n
\n
\n
<dtml-if group_by_expression>\n <dtml-if group_by_expression>\n
GROUP BY\n GROUP BY\n
<dtml-var group_by_expression>\n <dtml-var group_by_expression>\n
...@@ -392,10 +420,18 @@ SELECT\n ...@@ -392,10 +420,18 @@ SELECT\n
<dtml-if expr="precision is not None">\n <dtml-if expr="precision is not None">\n
SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS inventory,\n SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS inventory,\n
SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS total_quantity,\n SUM(ROUND(<dtml-var stock_table_id>.quantity, <dtml-var precision>)) AS total_quantity,\n
<dtml-if quantity_unit>\n
SUM(ROUND(<dtml-var stock_table_id>.quantity * measure.quantity, <dtml-var precision>))\n
/ <dtml-sqlvar quantity_unit type=float> AS converted_quantity,\n
</dtml-if>\n
SUM(ROUND(<dtml-var stock_table_id>.total_price, <dtml-var precision>)) AS total_price\n SUM(ROUND(<dtml-var stock_table_id>.total_price, <dtml-var precision>)) AS total_price\n
<dtml-else>\n <dtml-else>\n
SUM(<dtml-var stock_table_id>.quantity) AS inventory,\n SUM(<dtml-var stock_table_id>.quantity) AS inventory,\n
SUM(<dtml-var stock_table_id>.quantity) AS total_quantity,\n SUM(<dtml-var stock_table_id>.quantity) AS total_quantity,\n
<dtml-if quantity_unit>\n
ROUND(SUM(<dtml-var stock_table_id>.quantity * measure.quantity)\n
/ <dtml-sqlvar quantity_unit type=float>, 12) AS converted_quantity,\n
</dtml-if>\n
SUM(<dtml-var stock_table_id>.total_price) AS total_price\n SUM(<dtml-var stock_table_id>.total_price) AS total_price\n
</dtml-if>\n </dtml-if>\n
<dtml-if inventory_list>\n <dtml-if inventory_list>\n
...@@ -465,6 +501,12 @@ WHERE\n ...@@ -465,6 +501,12 @@ WHERE\n
<dtml-if selection_report>\n <dtml-if selection_report>\n
AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\n AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\n
</dtml-if>\n </dtml-if>\n
\n
<dtml-if quantity_unit>\n
AND concat(<dtml-var stock_table_id>.variation_text,\'\\n\') REGEXP measure.variation\n
</dtml-if>\n
\n
\n
<dtml-if group_by_expression>\n <dtml-if group_by_expression>\n
GROUP BY\n GROUP BY\n
<dtml-var group_by_expression>\n <dtml-var group_by_expression>\n
......
825 826
\ No newline at end of file \ No newline at end of file
<catalog_method>
<item key="sql_clear_catalog" type="int">
<value>1</value>
</item>
</catalog_method>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_arg</string> </key>
<value>
<object>
<klass>
<global name="Args" module="Shared.DC.ZRDB.Aqueduct"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_data</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_keys</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_drop_measure</string> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>DROP TABLE IF EXISTS measure</string> </value>
</item>
<item>
<key> <string>template</string> </key>
<value>
<object>
<klass>
<global name="__newobj__" module="copy_reg"/>
</klass>
<tuple>
<global name="SQL" module="Shared.DC.ZRDB.DA"/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string encoding="cdata"><![CDATA[
<string>
]]></string> </value>
</item>
<item>
<key> <string>_vars</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>globals</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>raw</string> </key>
<value> <string>DROP TABLE IF EXISTS measure</string> </value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_uncatalog_object" type="int">
<value>1</value>
</item>
</catalog_method>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_arg</string> </key>
<value>
<object>
<klass>
<global name="Args" module="Shared.DC.ZRDB.Aqueduct"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_data</string> </key>
<value>
<dictionary>
<item>
<key> <string>uid</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>_keys</string> </key>
<value>
<list>
<string>uid</string>
</list>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z0_uncatalog_measure</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-comment>\n
JM: Since unindexing a measure triggers the reindexing of the related\n
resource (what will clean the measure table - cf z0_catalog_measure_list),\n
is it required to delete according to uid column?\n
The test against metric_type_uid is there in case we delete a metric_type_uid\n
category that is used as an implicit measure.\n
</dtml-comment>\n
DELETE FROM measure\n
WHERE <dtml-sqltest uid op=eq type=int>\n
OR <dtml-sqltest uid op=eq type=int column="metric_type_uid">\n
]]></string> </value>
</item>
<item>
<key> <string>template</string> </key>
<value>
<object>
<klass>
<global name="__newobj__" module="copy_reg"/>
</klass>
<tuple>
<global name="SQL" module="Shared.DC.ZRDB.DA"/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string encoding="cdata"><![CDATA[
<string>
]]></string> </value>
</item>
<item>
<key> <string>_vars</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>globals</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-comment>\n
JM: Since unindexing a measure triggers the reindexing of the related\n
resource (what will clean the measure table - cf z0_catalog_measure_list),\n
is it required to delete according to uid column?\n
The test against metric_type_uid is there in case we delete a metric_type_uid\n
category that is used as an implicit measure.\n
</dtml-comment>\n
DELETE FROM measure\n
WHERE <dtml-sqltest uid op=eq type=int>\n
OR <dtml-sqltest uid op=eq type=int column="metric_type_uid">\n
]]></string> </value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_catalog_object_list" type="int">
<value>1</value>
</item>
<item key="_is_filtered_archive" type="int">
<value>1</value>
</item>
<item key="_filter_expression_archive" type="str">
<value>python: here.getPortalType() in here.getPortalResourceTypeList()</value>
</item>
<item key="_filter_type_archive" type="tuple">
</item>
</catalog_method>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_arg</string> </key>
<value>
<object>
<klass>
<global name="Args" module="Shared.DC.ZRDB.Aqueduct"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_data</string> </key>
<value>
<dictionary>
<item>
<key> <string>getMeasureRowList</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>uid</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>_keys</string> </key>
<value>
<list>
<string>uid</string>
<string>getMeasureRowList</string>
</list>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>uid\n
getMeasureRowList</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_catalog_measure_list</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM `measure` WHERE\n
<dtml-sqltest uid column="resource_uid" type="int" multiple>;\n
\n
<dtml-let measure_list="[]">\n
<dtml-in getMeasureRowList prefix="loop">\n
<dtml-call expr="loop_item and measure_list.extend(loop_item)">\n
</dtml-in>\n
\n
<dtml-if measure_list>\n
<dtml-var sql_delimiter>\n
\n
INSERT INTO `measure`\n
VALUES\n
<dtml-in measure_list prefix="loop">\n
(\n
<dtml-sqlvar expr="loop_item[0]" type="int">,\n
<dtml-sqlvar expr="loop_item[1]" type="int">,\n
<dtml-sqlvar expr="loop_item[2]" type="string">,\n
<dtml-sqlvar expr="loop_item[3]" type="int">,\n
<dtml-sqlvar expr="loop_item[4]" type="float">\n
)\n
<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
</item>
<item>
<key> <string>template</string> </key>
<value>
<object>
<klass>
<global name="__newobj__" module="copy_reg"/>
</klass>
<tuple>
<global name="SQL" module="Shared.DC.ZRDB.DA"/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string encoding="cdata"><![CDATA[
<string>
]]></string> </value>
</item>
<item>
<key> <string>_vars</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>globals</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
DELETE FROM `measure` WHERE\n
<dtml-sqltest uid column="resource_uid" type="int" multiple>;\n
\n
<dtml-let measure_list="[]">\n
<dtml-in getMeasureRowList prefix="loop">\n
<dtml-call expr="loop_item and measure_list.extend(loop_item)">\n
</dtml-in>\n
\n
<dtml-if measure_list>\n
<dtml-var sql_delimiter>\n
\n
INSERT INTO `measure`\n
VALUES\n
<dtml-in measure_list prefix="loop">\n
(\n
<dtml-sqlvar expr="loop_item[0]" type="int">,\n
<dtml-sqlvar expr="loop_item[1]" type="int">,\n
<dtml-sqlvar expr="loop_item[2]" type="string">,\n
<dtml-sqlvar expr="loop_item[3]" type="int">,\n
<dtml-sqlvar expr="loop_item[4]" type="float">\n
)\n
<dtml-unless sequence-end>,</dtml-unless>\n
</dtml-in>\n
\n
</dtml-if>\n
</dtml-let>\n
]]></string> </value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<catalog_method>
<item key="sql_clear_catalog" type="int">
<value>1</value>
</item>
</catalog_method>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_arg</string> </key>
<value>
<object>
<klass>
<global name="Args" module="Shared.DC.ZRDB.Aqueduct"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_data</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_keys</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_create_measure</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>CREATE TABLE `measure` (\n
`uid` BIGINT UNSIGNED NOT NULL,\n
`resource_uid` BIGINT UNSIGNED NOT NULL,\n
`variation` VARCHAR(255),\n
`metric_type_uid` BIGINT UNSIGNED NOT NULL,\n
`quantity` REAL NOT NULL,\n
PRIMARY KEY (`uid`, `variation`),\n
KEY (`metric_type_uid`)\n
) TYPE=InnoDB;\n
</string> </value>
</item>
<item>
<key> <string>template</string> </key>
<value>
<object>
<klass>
<global name="__newobj__" module="copy_reg"/>
</klass>
<tuple>
<global name="SQL" module="Shared.DC.ZRDB.DA"/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string encoding="cdata"><![CDATA[
<string>
]]></string> </value>
</item>
<item>
<key> <string>_vars</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>globals</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>raw</string> </key>
<value> <string>CREATE TABLE `measure` (\n
`uid` BIGINT UNSIGNED NOT NULL,\n
`resource_uid` BIGINT UNSIGNED NOT NULL,\n
`variation` VARCHAR(255),\n
`metric_type_uid` BIGINT UNSIGNED NOT NULL,\n
`quantity` REAL NOT NULL,\n
PRIMARY KEY (`uid`, `variation`),\n
KEY (`metric_type_uid`)\n
) TYPE=InnoDB;\n
</string> </value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_arg</string> </key>
<value>
<object>
<klass>
<global name="Args" module="Shared.DC.ZRDB.Aqueduct"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_data</string> </key>
<value>
<dictionary>
<item>
<key> <string>table_0</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>_keys</string> </key>
<value>
<list>
<string>table_0</string>
</list>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string>table_0</string> </value>
</item>
<item>
<key> <string>cache_time_</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>class_file_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>class_name_</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_hook</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>erp5_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>z_related_metric_type</string> </value>
</item>
<item>
<key> <string>max_cache_</string> </key>
<value> <int>100</int> </value>
</item>
<item>
<key> <string>max_rows_</string> </key>
<value> <int>1000</int> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-var table_0>.resource_uid = resource.uid
]]></string> </value>
</item>
<item>
<key> <string>template</string> </key>
<value>
<object>
<klass>
<global name="__newobj__" module="copy_reg"/>
</klass>
<tuple>
<global name="SQL" module="Shared.DC.ZRDB.DA"/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string encoding="cdata"><![CDATA[
<string>
]]></string> </value>
</item>
<item>
<key> <string>_vars</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>globals</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>raw</string> </key>
<value> <string encoding="cdata"><![CDATA[
<dtml-var table_0>.resource_uid = resource.uid
]]></string> </value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<key>item_node_category_uid | category/category_uid/z_related_node_uid_from_item</key> <key>item_node_category_uid | category/category_uid/z_related_node_uid_from_item</key>
<key>item_resource_category_uid | category/category_uid/z_related_resource_uid_from_item</key> <key>item_resource_category_uid | category/category_uid/z_related_resource_uid_from_item</key>
<key>item_section_category_uid | category/category_uid/z_related_section_uid_from_item</key> <key>item_section_category_uid | category/category_uid/z_related_section_uid_from_item</key>
<key>metric_type_uid | measure/metric_type_uid/z_related_metric_type</key>
<key>parent_description | catalog/description/z_related_parent</key> <key>parent_description | catalog/description/z_related_parent</key>
<key>parent_float_index | catalog/float_index/z_related_parent</key> <key>parent_float_index | catalog/float_index/z_related_parent</key>
<key>parent_int_index | catalog/int_index/z_related_parent</key> <key>parent_int_index | catalog/int_index/z_related_parent</key>
......
107 108
\ No newline at end of file \ No newline at end of file
...@@ -6,6 +6,7 @@ erp5_mysql_innodb/z0_drop_fulltext ...@@ -6,6 +6,7 @@ erp5_mysql_innodb/z0_drop_fulltext
erp5_mysql_innodb/z0_drop_inventory erp5_mysql_innodb/z0_drop_inventory
erp5_mysql_innodb/z0_drop_inventory_stock erp5_mysql_innodb/z0_drop_inventory_stock
erp5_mysql_innodb/z0_drop_item erp5_mysql_innodb/z0_drop_item
erp5_mysql_innodb/z0_drop_measure
erp5_mysql_innodb/z0_drop_movement erp5_mysql_innodb/z0_drop_movement
erp5_mysql_innodb/z0_drop_portal_ids erp5_mysql_innodb/z0_drop_portal_ids
erp5_mysql_innodb/z0_drop_predicate erp5_mysql_innodb/z0_drop_predicate
...@@ -20,6 +21,7 @@ erp5_mysql_innodb/z0_uncatalog_fulltext ...@@ -20,6 +21,7 @@ erp5_mysql_innodb/z0_uncatalog_fulltext
erp5_mysql_innodb/z0_uncatalog_inventory erp5_mysql_innodb/z0_uncatalog_inventory
erp5_mysql_innodb/z0_uncatalog_inventory_stock erp5_mysql_innodb/z0_uncatalog_inventory_stock
erp5_mysql_innodb/z0_uncatalog_item erp5_mysql_innodb/z0_uncatalog_item
erp5_mysql_innodb/z0_uncatalog_measure
erp5_mysql_innodb/z0_uncatalog_movement erp5_mysql_innodb/z0_uncatalog_movement
erp5_mysql_innodb/z0_uncatalog_predicate erp5_mysql_innodb/z0_uncatalog_predicate
erp5_mysql_innodb/z0_uncatalog_predicate_category erp5_mysql_innodb/z0_uncatalog_predicate_category
...@@ -30,6 +32,7 @@ erp5_mysql_innodb/z_catalog_fulltext_list ...@@ -30,6 +32,7 @@ erp5_mysql_innodb/z_catalog_fulltext_list
erp5_mysql_innodb/z_catalog_inventory_list erp5_mysql_innodb/z_catalog_inventory_list
erp5_mysql_innodb/z_catalog_inventory_stock_list erp5_mysql_innodb/z_catalog_inventory_stock_list
erp5_mysql_innodb/z_catalog_item_list erp5_mysql_innodb/z_catalog_item_list
erp5_mysql_innodb/z_catalog_measure_list
erp5_mysql_innodb/z_catalog_movement_category_list erp5_mysql_innodb/z_catalog_movement_category_list
erp5_mysql_innodb/z_catalog_movement_list erp5_mysql_innodb/z_catalog_movement_list
erp5_mysql_innodb/z_catalog_non_movement_category_list erp5_mysql_innodb/z_catalog_non_movement_category_list
...@@ -50,6 +53,7 @@ erp5_mysql_innodb/z_create_fulltext ...@@ -50,6 +53,7 @@ erp5_mysql_innodb/z_create_fulltext
erp5_mysql_innodb/z_create_inventory erp5_mysql_innodb/z_create_inventory
erp5_mysql_innodb/z_create_inventory_stock erp5_mysql_innodb/z_create_inventory_stock
erp5_mysql_innodb/z_create_item erp5_mysql_innodb/z_create_item
erp5_mysql_innodb/z_create_measure
erp5_mysql_innodb/z_create_movement erp5_mysql_innodb/z_create_movement
erp5_mysql_innodb/z_create_portal_ids erp5_mysql_innodb/z_create_portal_ids
erp5_mysql_innodb/z_create_predicate erp5_mysql_innodb/z_create_predicate
...@@ -72,6 +76,7 @@ erp5_mysql_innodb/z_related_base_category_id ...@@ -72,6 +76,7 @@ erp5_mysql_innodb/z_related_base_category_id
erp5_mysql_innodb/z_related_career_skill erp5_mysql_innodb/z_related_career_skill
erp5_mysql_innodb/z_related_explanation erp5_mysql_innodb/z_related_explanation
erp5_mysql_innodb/z_related_grand_parent erp5_mysql_innodb/z_related_grand_parent
erp5_mysql_innodb/z_related_metric_type
erp5_mysql_innodb/z_related_mirror_section_uid_from_stock erp5_mysql_innodb/z_related_mirror_section_uid_from_stock
erp5_mysql_innodb/z_related_node_uid_from_stock erp5_mysql_innodb/z_related_node_uid_from_stock
erp5_mysql_innodb/z_related_parent erp5_mysql_innodb/z_related_parent
......
...@@ -41,4 +41,5 @@ parent_reference | catalog/reference/z_related_parent ...@@ -41,4 +41,5 @@ parent_reference | catalog/reference/z_related_parent
parent_description | catalog/description/z_related_parent parent_description | catalog/description/z_related_parent
parent_portal_type | catalog/portal_type/z_related_parent parent_portal_type | catalog/portal_type/z_related_parent
translated_causality_state | translation/translated_message/z_related_translated_causality_state translated_causality_state | translation/translated_message/z_related_translated_causality_state
translated_causality_state_title | translation/translated_message/z_related_translated_causality_state_title translated_causality_state_title | translation/translated_message/z_related_translated_causality_state_title
\ No newline at end of file metric_type_uid | measure/metric_type_uid/z_related_metric_type
\ No newline at end of file
...@@ -58,7 +58,15 @@ class InventoryAPITestCase(ERP5TypeTestCase): ...@@ -58,7 +58,15 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'group/test_group/A2/B1/C2', 'group/test_group/A2/B1/C2',
'group/test_group/A2/B2/C1', 'group/test_group/A2/B2/C1',
'group/test_group/A2/B2/C2', ) 'group/test_group/A2/B2/C2', )
VARIATION_CATEGORIES = ( 'colour/red',
'colour/green',
'colour/blue',
'size/big',
'size/small',
'industrial_phase/phase1',
'industrial_phase/phase2', )
def getTitle(self): def getTitle(self):
"""Title of the test.""" """Title of the test."""
return 'Inventory API' return 'Inventory API'
...@@ -181,7 +189,7 @@ class InventoryAPITestCase(ERP5TypeTestCase): ...@@ -181,7 +189,7 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'group/anotherlevel', 'group/anotherlevel',
'product_line/level1/level2', 'product_line/level1/level2',
# we create a huge group category for consolidation tests # we create a huge group category for consolidation tests
) + self.GROUP_CATEGORIES ) + self.GROUP_CATEGORIES + self.VARIATION_CATEGORIES
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
""" erp5_trade is required for transit_simulation_state """ erp5_trade is required for transit_simulation_state
...@@ -2085,6 +2093,110 @@ class TestInventoryDocument(InventoryAPITestCase): ...@@ -2085,6 +2093,110 @@ class TestInventoryDocument(InventoryAPITestCase):
_aq_reset() _aq_reset()
class TestUnitConversion(InventoryAPITestCase):
QUANTITY_UNIT_CATEGORIES = {
'unit': {'unit': 1, 'a_few': None},
'length': {'m': 1, 'in': .0254},
'mass': {'kg': 1, 't': 1000, 'g': .001},
}
METRIC_TYPE_CATEGORIES = (
'unit',
'unit/0',
'unit/1',
'unit/2',
'mass/net',
'mass/nutr/lipid',
)
def afterSetUp(self):
InventoryAPITestCase.afterSetUp(self)
self.resource.setQuantityUnitList(('unit/unit', 'length/in'))
self.other_resource.setQuantityUnit('mass/g')
keys = ('metric_type', 'quantity_unit', 'quantity', 'default_metric_type')
for resource, measure_list in {
self.resource: (
('mass/net', 'mass/kg', .123, None),
('mass/nutr/lipid', 'mass/g', 45, True),
),
self.other_resource: (
# default measure (only useful to set the metric type)
('mass/net', None, 1, True),
# Bad measures
('unit', 'unit/unit', 123, None), ## duplicate
('unit', 'unit/unit', 123, None), #
('unit/0', 'unit/a_few', 123, None), ## incomplete
('unit/1', 'unit/unit', None, None), #
('unit/2', None, 123, None), #
(None, 'mass/kg', 123, None), #
(None, None, None, None), ## empty
)}.iteritems():
for measure in measure_list:
kw = dict((keys[i], v) for i, v in enumerate(measure) if v is not None)
resource.newContent(portal_type='Measure', **kw)
self.resource.setOptionalVariationBaseCategory('industrial_phase')
self.resource.setVariationBaseCategoryList(('colour', 'size'))
self.resource.setVariationCategoryList(self.VARIATION_CATEGORIES)
m = self.resource.getDefaultMeasure('mass/t')
m.setMeasureVariationBaseCategory('colour')
for colour, quantity in ('green', 43), ('red', 56):
m.newContent(portal_type='Measure Cell', quantity=quantity) \
._setMembershipCriterionCategory('colour/' + colour)
self._safeTic()
def getNeededCategoryList(self):
category_list = ['metric_type/' + c for c in self.METRIC_TYPE_CATEGORIES]
for level1, level2 in self.QUANTITY_UNIT_CATEGORIES.iteritems():
quantity = 'quantity_unit/%s/' % level1
category_list.extend(quantity + unit for unit in level2)
category_list += InventoryAPITestCase.getNeededCategoryList(self)
return category_list
def createCategories(self):
InventoryAPITestCase.createCategories(self)
quantity_unit = self.getCategoryTool().quantity_unit
for quantity_id, unit_dict in self.QUANTITY_UNIT_CATEGORIES.iteritems():
quantity_value = quantity_unit[quantity_id]
for unit_id, unit_scale in unit_dict.iteritems():
if unit_scale is not None:
quantity_value[unit_id].setProperty('quantity', unit_scale)
def testConvertedInventoryList(self):
def makeMovement(quantity, resource, *variation, **kw):
m = self._makeMovement(quantity=quantity, resource_value=resource,
source_value=self.node, destination_value=self.mirror_node, **kw)
if variation:
m.setVariationCategoryList(variation)
self._safeTic()
makeMovement(2, self.resource, 'colour/green', 'size/big')
makeMovement(789, self.other_resource)
makeMovement(-13, self.resource, 'colour/red', 'size/small',
'industrial_phase/phase1', 'industrial_phase/phase2')
def simulation(metric_type, **kw):
return self.getSimulationTool().getConvertedInventoryList(
metric_type=metric_type, node_uid=self.node.getUid(),
ignore_group_by=1, inventory_list=0, **kw)[0].converted_quantity
for i in range(3):
self.assertEquals(None, simulation('unit/%i' % i))
self.assertEquals(None, simulation('unit', simulation_period='Current'))
self.assertEquals(11, simulation('unit'))
self.assertEquals(11 * 123 - 789,
simulation('mass/net', quantity_unit=.001))
self.assertEquals((11 * 123 - 789) / 1e6,
simulation('mass/net', quantity_unit='mass/t'))
self.assertEquals(13 * .056 - 2 * .043, simulation('mass/nutr/lipid'))
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestInventory)) suite.addTest(unittest.makeSuite(TestInventory))
...@@ -2094,6 +2206,7 @@ def test_suite(): ...@@ -2094,6 +2206,7 @@ def test_suite():
suite.addTest(unittest.makeSuite(TestNextNegativeInventoryDate)) suite.addTest(unittest.makeSuite(TestNextNegativeInventoryDate))
suite.addTest(unittest.makeSuite(TestTrackingList)) suite.addTest(unittest.makeSuite(TestTrackingList))
suite.addTest(unittest.makeSuite(TestInventoryDocument)) suite.addTest(unittest.makeSuite(TestInventoryDocument))
suite.addTest(unittest.makeSuite(TestUnitConversion))
return suite return suite
# vim: foldmethod=marker # vim: foldmethod=marker
...@@ -2505,3 +2505,102 @@ def getCommonTimeZoneList(): ...@@ -2505,3 +2505,102 @@ def getCommonTimeZoneList():
""" Get common (country/capital(major cities) format) timezones list """ """ Get common (country/capital(major cities) format) timezones list """
from pytz import common_timezones from pytz import common_timezones
return common_timezones return common_timezones
#####################################################
# Processing of ZRDB.Results objects
#####################################################
from Shared.DC.ZRDB.Results import Results
def mergeZRDBResults(results, key_column, edit_result):
"""
Merge several ZRDB.Results into a single ZRDB.Results. It's done in 3 steps:
1. Rename columns of every table (cf 1st parameter).
2. Merge all source tables into a intermediate sparse table.
Each processed row is identified according to the columns specified in the
2nd parameter: Rows with the same values in the specified columns are
merged together, otherwise they are stored separately.
3. Convert the intermediate table into a ZRDB.Results structure.
Cell values are copied or created according the 3rd parameter.
By default, values aren't modified and empty cells are set to None.
results - List of ZRDB.Results to merge. Each item can also be a tuple
(ZRDB.Results, rename_map) : the columns are renamed before
any other processing, according to rename_map (dict).
key_column - 2 rows are merged if and only if there is the same value in
the common column(s) specified by key_column.
key_column can be either a string or a sequence of strings.
() can be passed to merge 1-row tables.
edit_result - Map { column_name: function | defaut_value } allowing to edit
values (or specify default values) for certain columns in the
resulting table:
- function (lambda row, column_name: new_value)
- default_value is interpreted as
(lambda row, column: row.get(column, default_value))
Note that whenever a row doesn't have a matching row in every
other table, the merged result before editing may contain
incomplete rows. get_value also allows you to fill these rows
with specific values, instead of the default 'None' value.
"""
if isinstance(key_column,str):
key_column = key_column,
## Variables holding the resulting table:
items = [] # list of columns: each element is an item (cf ZRDB.Results)
column_list = [] # list of columns:
# each element is a pair (column name, get_value)
data = [] # list of rows of maps column_name => value
## For each key, record the row number in 'data'
index = {}
## Set of columns already seen
column_set = set()
for r in results:
## Step 1
if isinstance(r, Results):
rename = {}
else:
r, rename = r
new_column_list = []
columns = {}
for i, column in enumerate(r._searchable_result_columns()):
name = column['name']
name = rename.get(name, name)
if name is None:
continue
columns[name] = i
if name not in column_set:
column_set.add(name)
new_column_list.append(i)
column = column.copy()
column['name'] = name
items.append(column)
# prepare step 3
get_value = edit_result.get(name)
column_list += (name, hasattr(get_value, '__call__') and get_value or
(lambda row, column, default=get_value: row.get(column, default))),
## Step 2
try:
index_pos = [ columns[rename.get(name,name)] for name in key_column ]
except KeyError:
raise KeyError("Missing '%s' column in source table" % name)
for row in r:
key = tuple(row[i] for i in index_pos)
if key in index: # merge the row to an existing one
merged_row = data[index[key]]
else: # new row
index[key] = len(data)
merged_row = {}
data.append(merged_row)
for column, i in columns.iteritems():
merged_row[column] = row[i]
## Step 3
return Results((items, [
[ get_value(row, column) for column, get_value in column_list ]
for row in data
]))
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