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>
<portal_type id="Component">
<item>Measure</item>
<item>Sale Supply Line</item>
<item>Supply Line</item>
<item>Image</item>
......@@ -9,7 +10,11 @@
<portal_type id="Component Module">
<item>Component</item>
</portal_type>
<portal_type id="Measure">
<item>Measure Cell</item>
</portal_type>
<portal_type id="Product">
<item>Measure</item>
<item>Sale Supply Line</item>
<item>Supply Line</item>
<item>Image</item>
......@@ -46,6 +51,7 @@
<item>Service Individual Variation</item>
<item>Purchase Supply Line</item>
<item>Sale Supply Line</item>
<item>Measure</item>
</portal_type>
<portal_type id="Service Module">
<item>Service</item>
......
......@@ -5,6 +5,9 @@
<item>Supply Line</item>
<item>Image</item>
</portal_type>
<portal_type id="Measure">
<item>Measure Cell</item>
</portal_type>
<portal_type id="Product">
<item>Image</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 @@
<type>Component</type>
<workflow>validation_workflow, edit_workflow</workflow>
</chain>
<chain>
<type>Measure</type>
<workflow>edit_workflow, measure_interaction_workflow</workflow>
</chain>
<chain>
<type>Product</type>
<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 @@
<value>
<list>
<string>title</string>
<string>items</string>
</list>
</value>
</item>
......@@ -63,6 +64,12 @@
<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>
......@@ -86,6 +93,12 @@
<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>
......@@ -100,4 +113,20 @@
</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.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>
<?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
\ No newline at end of file
113
\ No newline at end of file
Component Individual Variation | view
Component Module | converted_inventory_report
Component Module | view
Component | purchase_price_view
Component | sale_price_view
Component | view
Component | view_flow_capacity
Component | view_measure
Preference | pdm_preference
Product Individual Variation | view
Product Module | converted_inventory_report
Product Module | view
Product | purchase_price_view
Product | sale_price_view
Product | view
Product | view_measure
Product | view_stock
Purchase Supply Line | additional_price
Purchase Supply Line | base_price
......@@ -31,10 +36,12 @@ Sale Supply Line | view
Sale Supply Module | view
Sale Supply | view
Service Individual Variation | view
Service Module | converted_inventory_report
Service Module | view
Service | purchase_price_view
Service | sale_price_view
Service | view
Service | view_measure
Supply Line | additional_price
Supply Line | base_price
Supply Line | discount_ratio
......@@ -43,7 +50,6 @@ Supply Line | non_discountable_additional_price
Supply Line | surcharge_ratio
Supply Line | variable_additional_price
Supply Line | view
System Preference | pdm_preference
Transformation Module | view
Transformation Operation | complete_quantity_matrix
Transformation Operation | view
......
......@@ -7,6 +7,7 @@ feature
image
industrial_phase
measure
metric_type
morphology
operation
option
......
Component Module | Component
Component | Component Individual Variation
Component | Image
Component | Measure
Component | Purchase Supply Line
Component | Sale Supply Line
Component | Supply Line
Measure | Measure Cell
Product Module | Product
Product | Image
Product | Measure
Product | Product Individual Variation
Product | Purchase Supply Line
Product | Sale Supply Line
......@@ -21,6 +24,7 @@ Sale Supply Module | Sale Supply
Sale Supply | Sale Supply Line
Sale Supply | Supply Line
Service Module | Service
Service | Measure
Service | Purchase Supply Line
Service | Sale Supply Line
Service | Service Individual Variation
......
......@@ -2,6 +2,7 @@ Component | Image
Component | Purchase Supply Line
Component | Sale Supply Line
Component | Supply Line
Measure | Measure Cell
Product | Image
Product | Purchase Supply Line
Product | Sale Supply Line
......
Component
Component Individual Variation
Component Module
Measure
Measure Cell
Product
Product Individual Variation
Product Module
......
Component | edit_workflow
Component | validation_workflow
Measure | edit_workflow
Measure | measure_interaction_workflow
Product | edit_workflow
Product | validation_workflow
Purchase Supply Line | edit_workflow
......
measure_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):
Price is defined on
"""
result = None
efficiency = self.getEfficiency()
if efficiency != 0:
resource_price = self.getResourcePrice()
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
price = self.getResourcePrice()
quantity = self.getNetConvertedQuantity()
if isinstance(price, (int, float)) and isinstance(quantity, (int, float)):
return quantity * price
# Conversion to standard unit
security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedQuantity')
......@@ -426,25 +419,26 @@ class Amount(Base, Variated):
resource = self.getResourceValue()
quantity_unit = self.getQuantityUnit()
quantity = self.getQuantity()
converted_quantity = None
if resource is not None:
resource_quantity_unit = resource.getDefaultQuantityUnit()
converted_quantity = resource.convertQuantity(quantity, quantity_unit, resource_quantity_unit)
else:
#LOG("ERP5 WARNING:", 100, 'could not convert quantity for %s' % self.getRelativeUrl())
pass
return converted_quantity
if quantity is not None and quantity_unit and resource is not None:
converted = resource.convertQuantity(quantity, quantity_unit,
resource.getDefaultQuantityUnit(),
self.getVariationCategoryList())
# For compatibility, return quantity non-converted if conversion fails.
if converted is not None:
return converted
return quantity
security.declareProtected(Permissions.ModifyPortalContent, 'setConvertedQuantity')
def setConvertedQuantity(self, value):
resource = self.getResourceValue()
quantity_unit = self.getQuantityUnit()
if resource is not None:
resource_quantity_unit = resource.getDefaultQuantityUnit()
quantity = resource.convertQuantity(value, resource_quantity_unit, quantity_unit)
self.setQuantity(quantity)
else:
LOG("ERP5 WARNING:", 100, 'could not set converted quantity for %s' % self.getRelativeUrl())
if value is not None and quantity_unit and resource is not None:
quantity = resource.convertQuantity(value,
resource.getDefaultQuantityUnit(),
quantity_unit,
self.getVariationCategoryList())
if quantity is not None:
return self.setQuantity(quantity)
security.declareProtected(Permissions.AccessContentsInformation, 'getNetQuantity')
def getNetQuantity(self):
......
......@@ -63,7 +63,9 @@ class Currency(Resource):
# Unit conversion
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
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):
# _getPrice is defined in the order / delivery
# Pricing mehod
def _getPrice(self, context):
context = self.asContext(context=context,
quantity=self.getConvertedQuantity())
operand_dict = self.getPriceCalculationOperandDict(context=context)
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):
price = self.getPrice(context=context)
......
......@@ -252,11 +252,6 @@ class Resource(XMLMatrix, Variated):
omit_individual_variation=omit_individual_variation,**kw)
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
security.declareProtected(Permissions.AccessContentsInformation,
'getDefaultDestinationAmountBis')
......@@ -783,3 +778,120 @@ class Resource(XMLMatrix, Variated):
except TypeError:
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:
)
_constraints = (
{ 'id': 'resource_measures_consistency',
'description': '',
'type': 'ResourceMeasuresConsistency',
},
)
_categories = ( 'source', 'destination', 'quantity_unit', 'price_unit',
'weight_unit', 'length_unit', 'height_unit', 'width_unit',
'volume_unit',
......
......@@ -49,6 +49,7 @@ from Products.PythonScripts.Utility import allow_class
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery, QueryMixin
from Shared.DC.ZRDB.Results import Results
from Products.ERP5Type.Utils import mergeZRDBResults
class SimulationTool(BaseTool):
"""
......@@ -878,7 +879,8 @@ class SimulationTool(BaseTool):
default_stock_table='stock',
selection_domain=None, selection_report=None,
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
resources on a single or multiple nodes, grouped by resource,
......@@ -1058,6 +1060,7 @@ class SimulationTool(BaseTool):
assert isinstance(where_query, basestring) and len(where_query)
stock_sql_kw['where_expression'] = '(%s) AND (%s)' % \
(where_query, greater_than_date_query)
LOG(None, 0, 'optimisation_success = True')
# Get initial inventory amount
initial_inventory_line_list = self.Resource_zGetInventoryList(
stock_table_id=EQUAL_DATE_TABLE_ID,
......@@ -1066,7 +1069,8 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain,
selection_report=selection_report, precision=precision,
inventory_list=inventory_list,
statistic=statistic, **inventory_stock_sql_kw)
statistic=statistic, quantity_unit=quantity_unit,
**inventory_stock_sql_kw)
# Get delta inventory
delta_inventory_line_list = self.Resource_zGetInventoryList(
stock_table_id=GREATER_THAN_DATE_TABLE_ID,
......@@ -1075,7 +1079,8 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain,
selection_report=selection_report, precision=precision,
inventory_list=inventory_list,
statistic=statistic, **stock_sql_kw)
statistic=statistic, quantity_unit=quantity_unit,
**stock_sql_kw)
# Match & add initial and delta inventories
if src__:
sql_source_list.extend((initial_inventory_line_list,
......@@ -1104,6 +1109,8 @@ class SimulationTool(BaseTool):
result_column_id_dict['inventory'] = None
result_column_id_dict['total_quantity'] = 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):
"""
Addition columns of 2 lines and return a line with same
......@@ -1189,13 +1196,73 @@ class SimulationTool(BaseTool):
selection_domain=selection_domain,
selection_report=selection_report, precision=precision,
inventory_list=inventory_list, connection_id=connection_id,
statistic=statistic, **stock_sql_kw)
statistic=statistic, quantity_unit=quantity_unit,
**stock_sql_kw)
if src__:
sql_source_list.append(result)
if src__:
result = ';\n-- NEXT QUERY\n'.join(sql_source_list)
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,
'getCurrentInventoryList')
def getCurrentInventoryList(self, omit_transit=1,
......@@ -1268,7 +1335,7 @@ class SimulationTool(BaseTool):
'getAvailableInventoryStat')
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)
......
......@@ -45,9 +45,9 @@
<value>
<tuple>
<string>delivery</string>
<string>resource</string>
<string>order</string>
<string>parent</string>
<string>resource</string>
</tuple>
</value>
</item>
......
......@@ -121,6 +121,7 @@
<string>my_codification</string>
<string>my_int_index</string>
<string>my_translated_validation_state_title</string>
<string>my_quantity</string>
</list>
</value>
</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 @@
<dictionary/>
</value>
</item>
<item>
<key> <string>quantity_unit</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>section_filtered</string> </key>
<value>
......@@ -189,6 +195,7 @@
<string>precision</string>
<string>inventory_list</string>
<string>statistic</string>
<string>quantity_unit</string>
<string>stock_table_id</string>
</list>
</value>
......@@ -198,6 +205,12 @@
</object>
</value>
</item>
<item>
<key> <string>_owner</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>allow_simple_one_argument_traversal</string> </key>
<value>
......@@ -223,6 +236,7 @@ output_simulation_state:list\r\n
precision\r\n
inventory_list\r\n
statistic\r\n
quantity_unit\r\n
stock_table_id=stock</string> </value>
</item>
<item>
......@@ -267,10 +281,18 @@ SELECT\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 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
<dtml-else>\n
SUM(<dtml-var stock_table_id>.quantity) AS inventory,\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
</dtml-if>\n
<dtml-if inventory_list>\n
......@@ -340,6 +362,12 @@ WHERE\n
<dtml-if selection_report>\n
AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\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
GROUP BY\n
<dtml-var group_by_expression>\n
......@@ -392,10 +420,18 @@ SELECT\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 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
<dtml-else>\n
SUM(<dtml-var stock_table_id>.quantity) AS inventory,\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
</dtml-if>\n
<dtml-if inventory_list>\n
......@@ -465,6 +501,12 @@ WHERE\n
<dtml-if selection_report>\n
AND <dtml-var "portal_selections.buildSQLExpressionFromDomainSelection(selection_report, strict_membership=1)">\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
GROUP BY\n
<dtml-var group_by_expression>\n
......
825
\ No newline at end of file
826
\ 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 @@
<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_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_float_index | catalog/float_index/z_related_parent</key>
<key>parent_int_index | catalog/int_index/z_related_parent</key>
......
107
\ No newline at end of file
108
\ No newline at end of file
......@@ -6,6 +6,7 @@ erp5_mysql_innodb/z0_drop_fulltext
erp5_mysql_innodb/z0_drop_inventory
erp5_mysql_innodb/z0_drop_inventory_stock
erp5_mysql_innodb/z0_drop_item
erp5_mysql_innodb/z0_drop_measure
erp5_mysql_innodb/z0_drop_movement
erp5_mysql_innodb/z0_drop_portal_ids
erp5_mysql_innodb/z0_drop_predicate
......@@ -20,6 +21,7 @@ erp5_mysql_innodb/z0_uncatalog_fulltext
erp5_mysql_innodb/z0_uncatalog_inventory
erp5_mysql_innodb/z0_uncatalog_inventory_stock
erp5_mysql_innodb/z0_uncatalog_item
erp5_mysql_innodb/z0_uncatalog_measure
erp5_mysql_innodb/z0_uncatalog_movement
erp5_mysql_innodb/z0_uncatalog_predicate
erp5_mysql_innodb/z0_uncatalog_predicate_category
......@@ -30,6 +32,7 @@ erp5_mysql_innodb/z_catalog_fulltext_list
erp5_mysql_innodb/z_catalog_inventory_list
erp5_mysql_innodb/z_catalog_inventory_stock_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_list
erp5_mysql_innodb/z_catalog_non_movement_category_list
......@@ -50,6 +53,7 @@ erp5_mysql_innodb/z_create_fulltext
erp5_mysql_innodb/z_create_inventory
erp5_mysql_innodb/z_create_inventory_stock
erp5_mysql_innodb/z_create_item
erp5_mysql_innodb/z_create_measure
erp5_mysql_innodb/z_create_movement
erp5_mysql_innodb/z_create_portal_ids
erp5_mysql_innodb/z_create_predicate
......@@ -72,6 +76,7 @@ erp5_mysql_innodb/z_related_base_category_id
erp5_mysql_innodb/z_related_career_skill
erp5_mysql_innodb/z_related_explanation
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_node_uid_from_stock
erp5_mysql_innodb/z_related_parent
......
......@@ -42,3 +42,4 @@ parent_description | catalog/description/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_title | translation/translated_message/z_related_translated_causality_state_title
metric_type_uid | measure/metric_type_uid/z_related_metric_type
\ No newline at end of file
......@@ -59,6 +59,14 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'group/test_group/A2/B2/C1',
'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):
"""Title of the test."""
return 'Inventory API'
......@@ -181,7 +189,7 @@ class InventoryAPITestCase(ERP5TypeTestCase):
'group/anotherlevel',
'product_line/level1/level2',
# we create a huge group category for consolidation tests
) + self.GROUP_CATEGORIES
) + self.GROUP_CATEGORIES + self.VARIATION_CATEGORIES
def getBusinessTemplateList(self):
""" erp5_trade is required for transit_simulation_state
......@@ -2085,6 +2093,110 @@ class TestInventoryDocument(InventoryAPITestCase):
_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():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestInventory))
......@@ -2094,6 +2206,7 @@ def test_suite():
suite.addTest(unittest.makeSuite(TestNextNegativeInventoryDate))
suite.addTest(unittest.makeSuite(TestTrackingList))
suite.addTest(unittest.makeSuite(TestInventoryDocument))
suite.addTest(unittest.makeSuite(TestUnitConversion))
return suite
# vim: foldmethod=marker
......@@ -2505,3 +2505,102 @@ def getCommonTimeZoneList():
""" Get common (country/capital(major cities) format) timezones list """
from pytz import 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