From 9b2c1763a47672544588b6ba937a425b31396c8f Mon Sep 17 00:00:00 2001
From: Jean-Paul Smets <jp@nexedi.com>
Date: Sun, 8 Feb 2004 19:30:40 +0000
Subject: [PATCH] Global Udate to Latest Coramy Optimizations

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@441 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/Coramy/Document/Invoice.py            |   2 +
 product/Coramy/Document/Item.py               |  22 +-
 product/Coramy/Document/Modele.py             |   8 +-
 .../Coramy/skins/coramy_custom/seb_test.py    |  18 +-
 .../Coramy/skins/coramy_custom/test_jps.py    |  35 +-
 .../PortalSimulation_zGetResourceList.zsql    |  17 +-
 .../SQLDict_createMessageTable.zsql           |  16 +-
 .../skins/coramy_erp5/SQLDict_delMessage.zsql |  10 +-
 .../coramy_erp5/SQLDict_processMessage.zsql   |  14 +-
 .../coramy_erp5/SQLDict_readMessage.zsql      |  14 +-
 .../coramy_erp5/SQLDict_readMessageList.zsql  |  16 +-
 .../coramy_erp5/SQLDict_writeMessage.zsql     |  12 +-
 .../folder_workflow_status_modify.py          |   1 +
 .../Delivery_zSearchResource.zsql             |   2 +-
 .../PieceTissu_searchConsumedList.zsql        |   6 +-
 .../PieceTissu_zGetAvailableItemList.zsql     |  27 +-
 .../Resource_zGetAggregateList.zsql           |  10 +-
 ...roductionOrder_getDeliveryCellPrintList.py |  50 ++-
 .../coramy_mrp/InventoryMP_fastAddLine.py     |   2 +-
 .../skins/coramy_mrp/PieceTissu_fastInput.py  |   4 +
 .../coramy_mrp/PieceTissu_fastInputRetour.py  |   8 +-
 .../PieceTissu_searchByResource.form          |   4 +-
 ...ortalSimulation_activateRequirementList.py |  46 +-
 .../PortalSimulation_buildRequirementOrder.py |  15 +-
 .../PortalSimulation_updateAssetPrice.py      |  12 -
 .../Resource_zGetInventoryList.zsql           |   4 +-
 ...ionTool_zGetCoramyFutureInventoryList.zsql |   8 +-
 .../coramy_mrp/ZeroStock_buildOrderList.py    |  24 +-
 .../skins/coramy_mrp/item_tissu_list.form     |   7 +-
 .../skins/coramy_mrp/item_tissu_view.form     |  24 +
 ...nsformedComponent_getCorrespondanceList.py |  19 +-
 .../transformation_correspondances_print.pt   |   2 +-
 .../Container_printExtandLabel.py             |   2 +
 .../coramy_trade/Container_printMetoLabel.py  |   2 +
 .../coramy_trade/Container_sendExtandEdi.py   |   2 +-
 .../DeliveryLine_getTargetQuantityList.py     |  25 +-
 .../Delivery_exportContainerList.py           |   5 +-
 .../coramy_trade/default_pdf_template.pt      | 417 +++++++++++++-----
 .../purchase_packing_list_view.form           |   4 +-
 .../coramy_trade/sales_invoice_list.form      |   6 +-
 .../coramy_trade/sales_packing_list_print.pt  |   5 +-
 product/ERP5/Document/Amount.py               |  18 +-
 product/ERP5/Document/Container.py            |  14 +
 product/ERP5/Document/DeliveryCell.py         |  39 +-
 product/ERP5/Document/InventoryCell.py        |  80 +++-
 product/ERP5/Document/InventoryLine.py        |  95 +++-
 product/ERP5/Document/Invoice.py              |  36 +-
 product/ERP5/Document/Movement.py             |  78 ++--
 product/ERP5/Document/Order.py                |  39 ++
 product/ERP5/Document/PackingList.py          |   1 +
 product/ERP5/Document/Resource.py             |  25 +-
 product/ERP5/Document/Transformation.py       |   2 +-
 product/ERP5/Document/ZeroStockRule.py        |   2 +-
 product/ERP5/ERP5Globals.py                   |   3 +-
 product/ERP5/Extensions/InventoryBrain.py     | 100 ++---
 product/ERP5/Interface/__init__.py            |   2 +-
 product/ERP5/TargetSolver/SplitAndDefer.py    |   1 +
 product/ERP5/Variated.py                      |  17 +-
 .../sale_invoice_transaction_view.form        |   4 +-
 product/ERP5/skins/erp5_core/base_edit.py     |   5 +-
 .../skins/erp5_core/base_update_relation.py   |   4 +-
 product/ERP5/skins/erp5_core/doFavorite.py    |  19 +-
 .../skins/erp5_core/workflow_status_modify.py |   1 +
 .../skins/erp5_html_style/list_menu_box.pt    |   4 +-
 .../sale_invoice_transaction_view.form        |   4 +-
 product/ERP5Form/ListBox.py                   |   3 +-
 product/ERP5Form/PDFTemplate.py               |   4 +-
 product/ERP5Form/SelectionTool.py             |   8 +
 product/ERP5Type/ZopePatch.py                 |   2 +
 product/ZSQLCatalog/SQLCatalog.py             |   2 +-
 product/ZSQLCatalog/zsqlbrain.py              |  18 +-
 71 files changed, 1123 insertions(+), 434 deletions(-)

diff --git a/product/Coramy/Document/Invoice.py b/product/Coramy/Document/Invoice.py
index 08e30b3bd8..4ce28ca855 100755
--- a/product/Coramy/Document/Invoice.py
+++ b/product/Coramy/Document/Invoice.py
@@ -60,7 +60,9 @@ class Invoice(ERP5Invoice):
                       , PropertySheet.Movement
                       , PropertySheet.Amount
                       , PropertySheet.Reference
+                      , PropertySheet.TradeCondition
                       , PropertySheet.PaymentCondition
+                      , PropertySheet.Comment
                       )
 
     # Factory Type Information
diff --git a/product/Coramy/Document/Item.py b/product/Coramy/Document/Item.py
index 108b1211c3..e15c08c7f8 100755
--- a/product/Coramy/Document/Item.py
+++ b/product/Coramy/Document/Item.py
@@ -155,4 +155,24 @@ Un item sert a assurer la tracabilite des choses dans ERP5."""
       sub_quantity = 0
       for sub_item in sub_item_list :
         sub_quantity += sub_item.getQuantity()
-      return self.getQuantity() - sub_quantity
\ No newline at end of file
+      return self.getQuantity() - sub_quantity
+      
+    security.declareProtected(Permissions.ModifyPortalContent, 'getLastLocationTitle')
+    def getLastLocationTitle(self):
+      """
+        Returns the last location of this item or empty string
+      """
+      related_movement_list = self.PieceTissu_zGetAggregateRelatedMovementList()
+      if len(related_movement_list) > 0 :
+        last_movement = related_movement_list[0]
+        quantity = last_movement.quantity
+        inventory = last_movement.inventory
+        if inventory is not None :
+          last_location_title = last_movement.destination_title
+        elif quantity >= 0 :
+          last_location_title = last_movement.destination_title
+        else :
+          last_location_title = ''
+        return last_location_title
+      else :
+        return ''
diff --git a/product/Coramy/Document/Modele.py b/product/Coramy/Document/Modele.py
index feb37a5c10..9e225269ab 100755
--- a/product/Coramy/Document/Modele.py
+++ b/product/Coramy/Document/Modele.py
@@ -168,8 +168,14 @@ un modele..."""
       """
         return PRI for Modèle
       """
-      for pri in self.contentValues({'portal_type': 'Set Mapped Value'}):
+      for pri in self.contentValues(filter={'portal_type': 'Set Mapped Value'}):
         if 'pri' in pri.getMappedValuePropertyList():
           if pri.test(context):
             return pri.getProperty('pri')
       return None
+
+    def _updateIndustrialPrice(self):
+      pass
+      #self.modele_compute_pri(batch_mode=1)
+
+
diff --git a/product/Coramy/skins/coramy_custom/seb_test.py b/product/Coramy/skins/coramy_custom/seb_test.py
index 7a0378af61..b6d812d34c 100755
--- a/product/Coramy/skins/coramy_custom/seb_test.py
+++ b/product/Coramy/skins/coramy_custom/seb_test.py
@@ -7,4 +7,20 @@
 ##parameters=
 ##title=
 ##
-return context
+organisation_list = context.object_action_list(selection_name='organisations_selection')
+
+request = context.REQUEST
+tab = '\t'
+cr = '\n'
+export = ''
+del_list = []
+
+for modele_item in organisation_list :
+  ligne_modele = ''
+  modele=modele_item.getObject()
+
+  if int(modele.getId()) >= 726 :
+    del_list.append(modele.getId())
+
+context.getPortalObject().organisation.deleteContent(del_list)
+return len(del_list)
diff --git a/product/Coramy/skins/coramy_custom/test_jps.py b/product/Coramy/skins/coramy_custom/test_jps.py
index 16dcd1a079..21c2334f5e 100755
--- a/product/Coramy/skins/coramy_custom/test_jps.py
+++ b/product/Coramy/skins/coramy_custom/test_jps.py
@@ -7,22 +7,25 @@
 ##parameters=
 ##title=
 ##
-selection = context.portal_selections.getSelectionFor('purchase_packing_list_selection',REQUEST=context.REQUEST)
-delivery_list = selection(context=context)
-request = context.REQUEST
+# Collect movements in Zero Stock applied rule
+zs_movement_list = [context.portal_simulation.zero_stock['modele-137H401_coloris-modele-137H401-1_taille-adulte-52']]
 
-for delivery_item in delivery_list:
-  delivery = delivery_item.getObject()
+# keep only movements with a Modele resource
+movement_list = []
+for movement in zs_movement_list :
+  try :
+    if movement.getResourceValue().getPortalType() == 'Modele' :
+      movement_list.append(movement)
+  except :
+    pass
 
-  if delivery is not None :
-    order_list = delivery.getCausalityValueList()
-    if len(order_list) > 0 :
-      order = order_list[0]
-      # what's the gestionaire of this order
-      user_name = ''
-      # are we on a sales order or puchase order ?
-      if order.getPortalType() == 'Purchase Order' :
-        user_name = order.getDestinationAdministrationPersonTitle().replace(' ','_')
-        delivery.assign_gestionaire_designe_roles(user_name = user_name)
+# Parse movements into a root group
+root_group = context.portal_simulation.collectMovement(movement_list)
+order_list = context.portal_simulation.buildOrderList(root_group)
 
-return 'fait'
+# update produced orders
+for order in order_list:
+  order.autoPlan()
+  order.purchase_order_apply_condition()
+
+return "fait"
diff --git a/product/Coramy/skins/coramy_erp5/PortalSimulation_zGetResourceList.zsql b/product/Coramy/skins/coramy_erp5/PortalSimulation_zGetResourceList.zsql
index d5c8a69176..59d5d4579b 100755
--- a/product/Coramy/skins/coramy_erp5/PortalSimulation_zGetResourceList.zsql
+++ b/product/Coramy/skins/coramy_erp5/PortalSimulation_zGetResourceList.zsql
@@ -1,23 +1,16 @@
 <dtml-comment>
 title:
 connection_id:MySQL
-max_rows:1000
-max_cache:100
+max_rows:100000
+max_cache:0
 cache_time:0
 class_name:
 class_file:
 </dtml-comment>
-<params>section
-strict_membership</params>
+<params></params>
 SELECT DISTINCT
 	movement.resource_uid,
+	catalog.relative_url AS resource_relative_url,
 	movement.variation_text
 FROM
-	movement, stock, catalog as section, category
-WHERE
-	stock.uid = movement.uid
-AND	stock.section_uid = section.uid
-AND	section.uid = category.category_uid
-AND	category.base_category_uid = <dtml-sqlvar "portal_categories.group.getUid()" type="int">
-AND	section.relative_url = <dtml-sqlvar section type="string">
-<dtml-if strict_membership>AND	category.strict_membership=1</dtml-if>
\ No newline at end of file
+	movement LEFT JOIN catalog ON (catalog.uid = movement.resource_uid)
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_createMessageTable.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_createMessageTable.zsql
index 79b7a07c29..890ab6a159 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_createMessageTable.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_createMessageTable.zsql
@@ -8,16 +8,18 @@ class_name:
 class_file:
 </dtml-comment>
 <params></params>
-# Host: 
-# Database: test
-# Table: 'stock'
-# 
 CREATE TABLE `message` (
+  `uid` int(11) NOT NULL auto_increment,
   `path` VARCHAR(255),
   `method_id` VARCHAR(40),
+  `processing_node` INT DEFAULT -1,
+  `processing` INT DEFAULT 0,
+  `priority` INT DEFAULT 0,
   `message` BLOB,
-  `processing_node` INT DEFAULT NULL,
+  PRIMARY KEY  (`uid`),
   KEY `path` (`path`),
-  KEY `processing_node` (`processing_node`),
   KEY `method_id` (`method_id`),
-) TYPE = InnoDB; 
\ No newline at end of file
+  KEY `processing_node` (`processing_node`),
+  KEY `processing` (`processing`),
+  KEY `priority` (`priority`),
+) TYPE = InnoDB;
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_delMessage.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_delMessage.zsql
index b75a63d246..bfefd52843 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_delMessage.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_delMessage.zsql
@@ -7,11 +7,9 @@ cache_time:0
 class_name:
 class_file:
 </dtml-comment>
-<params>path
-method_id</params>
+<params>uid:list</params>
 DELETE FROM
-  message
+	message
 WHERE
-  path = <dtml-sqlvar path type="string">
-<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
-  
\ No newline at end of file
+<dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else> OR </dtml-if>
+</dtml-in>
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_processMessage.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_processMessage.zsql
index 25a0c3422c..fa0e19ecd6 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_processMessage.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_processMessage.zsql
@@ -1,17 +1,15 @@
 <dtml-comment>
 title:
 connection_id:MySQL
-max_rows:1000
-max_cache:100
+max_rows:1
+max_cache:0
 cache_time:0
 class_name:
 class_file:
 </dtml-comment>
-<params>path
-method_id
-processing_node</params>
+<params>uid</params>
 UPDATE message
-SET processing_node=<dtml-sqlvar processing_node type="int">
+SET processing=1
 WHERE
-  path = <dtml-sqlvar path type="string">
-<dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
\ No newline at end of file
+<dtml-in uid>uid = <dtml-sqlvar sequence-item type="int"><dtml-if sequence-end><dtml-else>
+ OR </dtml-if></dtml-in>
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_readMessage.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_readMessage.zsql
index 85d687f7a7..dcc09df313 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_readMessage.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_readMessage.zsql
@@ -7,8 +7,14 @@ cache_time:0
 class_name:
 class_file:
 </dtml-comment>
-<params></params>
+<params>processing_node
+priority</params>
 SELECT * FROM
-  message
-WHERE 
-  processing_node is NULL
\ No newline at end of file
+    message
+WHERE
+    processing <> 1
+<dtml-if processing_node> AND processing_node = <dtml-sqlvar processing_node type="int"></dtml-if>
+<dtml-if priority> AND priority = <dtml-sqlvar priority type="int"> </dtml-if> 
+
+ORDER BY
+    priority
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_readMessageList.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_readMessageList.zsql
index 8ba47984dc..b584c64a23 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_readMessageList.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_readMessageList.zsql
@@ -8,12 +8,16 @@ class_name:
 class_file:
 </dtml-comment>
 <params>path
-method_id</params>
+method_id
+processing_node
+priority</params>
 SELECT * FROM
-  message
-<dtml-if "path or method_id"> 
+    message
 WHERE
-<dtml-if path>  path = <dtml-sqlvar path type="string"></dtml-if>
+    processing <> 1
+<dtml-if processing_node>AND processing_node = <dtml-sqlvar processing_node type="int"> </dtml-if>
+<dtml-if priority>AND priority = <dtml-sqlvar priority type="int"> </dtml-if>
+<dtml-if path>AND path = <dtml-sqlvar path type="string"></dtml-if>
 <dtml-if method_id>AND method_id = <dtml-sqlvar method_id type="string"></dtml-if>
-</dtml-if>
-  
\ No newline at end of file
+GROUP BY
+     path, method_id, processing_node, processing
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/SQLDict_writeMessage.zsql b/product/Coramy/skins/coramy_erp5/SQLDict_writeMessage.zsql
index c0b07320f1..a7a9511202 100755
--- a/product/Coramy/skins/coramy_erp5/SQLDict_writeMessage.zsql
+++ b/product/Coramy/skins/coramy_erp5/SQLDict_writeMessage.zsql
@@ -9,7 +9,13 @@ class_file:
 </dtml-comment>
 <params>path
 method_id
-message</params>
+message
+priority</params>
 INSERT INTO message
-VALUES
- (<dtml-sqlvar path type="string">,<dtml-sqlvar method_id type="string">,<dtml-sqlvar message type="string">,NULL);
\ No newline at end of file
+SET
+	path = <dtml-sqlvar path type="string">,
+	method_id = <dtml-sqlvar method_id type="string">,
+	processing_node = -1,
+	processing = -1,
+	priority = <dtml-sqlvar priority type="int">,
+	message = <dtml-sqlvar message type="string">
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_erp5/folder_workflow_status_modify.py b/product/Coramy/skins/coramy_erp5/folder_workflow_status_modify.py
index 7d3a65eb85..3cce15d2b3 100755
--- a/product/Coramy/skins/coramy_erp5/folder_workflow_status_modify.py
+++ b/product/Coramy/skins/coramy_erp5/folder_workflow_status_modify.py
@@ -30,6 +30,7 @@ try:
     action_list = o.portal_workflow.getActionsFor(o)
     action_list = filter(lambda x:x.has_key('id'), action_list )
     action_id_list = map(lambda x:x['id'], action_list)
+    # If the user is not allowed to do this transition, it will not be in action_list 
     if workflow_action in action_id_list:
       o.portal_workflow.doActionFor(
           o,
diff --git a/product/Coramy/skins/coramy_list_method/Delivery_zSearchResource.zsql b/product/Coramy/skins/coramy_list_method/Delivery_zSearchResource.zsql
index e32a1d7f86..0657b61692 100755
--- a/product/Coramy/skins/coramy_list_method/Delivery_zSearchResource.zsql
+++ b/product/Coramy/skins/coramy_list_method/Delivery_zSearchResource.zsql
@@ -11,7 +11,7 @@ class_file:zsqlbrain.py
 variante_id_list=""
 sort_on
 portal_type</params>
-SELECT DISTINCT catalog.id, catalog.relative_url, catalog.path, catalog.Description, catalog.simulation_state, catalog.default_destination_title
+SELECT DISTINCT catalog.id, catalog.uid, catalog.relative_url, catalog.path, catalog.Description, catalog.simulation_state, catalog.default_destination_title
 FROM catalog, catalog AS line
 <dtml-if expr="_.len(resource_id_list)>0">
 , catalog AS resource
diff --git a/product/Coramy/skins/coramy_list_method/PieceTissu_searchConsumedList.zsql b/product/Coramy/skins/coramy_list_method/PieceTissu_searchConsumedList.zsql
index c6cb7d4d2b..f68a928652 100755
--- a/product/Coramy/skins/coramy_list_method/PieceTissu_searchConsumedList.zsql
+++ b/product/Coramy/skins/coramy_list_method/PieceTissu_searchConsumedList.zsql
@@ -20,6 +20,10 @@ AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()
 LEFT JOIN stock
 ON (stock.uid = category.uid)
 
+LEFT JOIN movement
+ON (movement.uid = category.uid)
+
 WHERE item.portal_type = "Piece Tissu"
 AND stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()">
-AND  stock.quantity < 0
\ No newline at end of file
+AND stock.quantity < 0
+AND movement.inventory IS NULL
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_list_method/PieceTissu_zGetAvailableItemList.zsql b/product/Coramy/skins/coramy_list_method/PieceTissu_zGetAvailableItemList.zsql
index 6b29340792..ba56364ea9 100755
--- a/product/Coramy/skins/coramy_list_method/PieceTissu_zGetAvailableItemList.zsql
+++ b/product/Coramy/skins/coramy_list_method/PieceTissu_zGetAvailableItemList.zsql
@@ -17,6 +17,23 @@ SELECT DISTINCT
 	item.uid, item.id, item.path, item.Description, item.simulation_state, item.default_destination_title
 FROM
 	catalog AS item
+
+LEFT JOIN category
+ON (category.category_uid=item.uid
+AND category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">)
+
+LEFT JOIN stock
+ON (stock.uid = category.uid)
+
+LEFT JOIN movement
+ON (movement.uid = category.uid)
+
+LEFT JOIN movement AS next_movement
+ON (next_movement.resource_uid = movement.resource_uid
+AND next_movement.variation_text = movement.variation_text
+AND next_movement.start_date > movement.start_date
+AND not (next_movement.inventory is NULL))
+
 <dtml-if expr="_.len(resource_id_list)>0">
 , catalog AS resource
 , category AS cat1
@@ -26,9 +43,15 @@ FROM
 , category AS cat2
 </dtml-if>
 
-WHERE item.portal_type = "Piece Tissu"
-<dtml-in PieceTissu_searchConsumedList>AND item.uid <> <dtml-sqlvar uid type="int"> 
+WHERE
+	item.portal_type = "Piece Tissu"
+AND	stock.node_uid = <dtml-var "portal_categories.site.Stock_MP.Gravelines.getUid()">
+AND ( stock.quantity >= 0
+OR (stock.quantity < 0
+AND not (movement.inventory is NULL) ) )
+<dtml-in PieceTissu_searchConsumedList>AND item.uid <> <dtml-sqlvar uid type="int">
 </dtml-in>
+AND next_movement.uid is NULL
 
 <dtml-if expr="_.len(resource_id_list)>0">
 AND ( resource.id LIKE "<dtml-var expr="resource_id_list[0]">"
diff --git a/product/Coramy/skins/coramy_list_method/Resource_zGetAggregateList.zsql b/product/Coramy/skins/coramy_list_method/Resource_zGetAggregateList.zsql
index 3c02864110..bed12eb8ac 100755
--- a/product/Coramy/skins/coramy_list_method/Resource_zGetAggregateList.zsql
+++ b/product/Coramy/skins/coramy_list_method/Resource_zGetAggregateList.zsql
@@ -1,7 +1,7 @@
 <dtml-comment>
 title:
 connection_id:MySQL
-max_rows:1000
+max_rows:750
 max_cache:100
 cache_time:0
 class_name:ZSQLBrain
@@ -15,17 +15,15 @@ resource_uid</params>
 SELECT
 	catalog.*
 FROM
-	catalog, movement, category, stock, catalog as movement_c
+	catalog, movement, category, stock
 WHERE
 	movement.uid = category.uid
+AND	category.category_uid = catalog.uid
+AND	category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">
 AND	stock.uid = movement.uid
 AND	movement.is_accountable = 1
 AND	movement.resource_uid = <dtml-sqlvar resource_uid type="int">
-AND	movement_c.uid = category.uid
-AND	category.category_uid = catalog.uid
-AND	category.base_category_uid = <dtml-var "portal_categories.aggregate.getUid()">
 AND	movement.delivery_uid = <dtml-sqlvar explanation_uid type="int">
 AND	movement.variation_text = <dtml-sqlvar variation_text type="string">
 AND	stock.node_uid = <dtml-sqlvar node_uid type="int">
 AND	stock.section_uid = <dtml-sqlvar section_uid type="int">
-AND	movement.variation_text = <dtml-sqlvar variation_text type="string">
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_manufacturing/ProductionOrder_getDeliveryCellPrintList.py b/product/Coramy/skins/coramy_manufacturing/ProductionOrder_getDeliveryCellPrintList.py
index 0bc81ab581..d94be0ac36 100755
--- a/product/Coramy/skins/coramy_manufacturing/ProductionOrder_getDeliveryCellPrintList.py
+++ b/product/Coramy/skins/coramy_manufacturing/ProductionOrder_getDeliveryCellPrintList.py
@@ -60,15 +60,16 @@ if resource <> None :
       corresp_variation_list = [movement.getTaille()]+['value']
 
     # find taille_client
-    line_taille_client = ' '
-    correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
-    if len(correspondance_list) == 1 :
-      my_correspondance = correspondance_list[0]
-      mapped_value_list = my_correspondance.objectValues()
-      for mapped_value in mapped_value_list :
-        if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) :
-          line_taille_client = mapped_value.getProperty(key='taille_client')
-          break
+    line_taille_client = movement.Amount_getTailleClient()
+
+#     correspondance_list = resource.getSpecialiseValueList(portal_type='Correspondance Tailles')
+#     if len(correspondance_list) == 1 :
+#       my_correspondance = correspondance_list[0]
+#       mapped_value_list = my_correspondance.objectValues()
+#       for mapped_value in mapped_value_list :
+#         if mapped_value.test(my_correspondance.asContext(categories=corresp_variation_list)) :
+#           line_taille_client = mapped_value.getProperty(key='taille_client')
+#           break
 
     try :
      line_quantity = float(movement.getProperty(key='quantity'))
@@ -78,21 +79,22 @@ if resource <> None :
     line_date = order_line.aq_parent.getStopDate()
 
     # find code_article
-    line_code_article = ''
-    variated_reference_list = resource.contentValues(filter={'portal_type':'Variated Reference'})
-    # we search a variated_reference wich define 'code_article'
-    my_variated_reference = None
-    for variated_reference in variated_reference_list :
-      if len(variated_reference.getMappedValuePropertyList()) <> 0 :
-        if variated_reference.getMappedValuePropertyList()[0] == 'code_article' :
-          my_variated_reference = variated_reference
-          break
-    if my_variated_reference is not None :
-      mapped_value_list = my_variated_reference.objectValues()
-      for mapped_value in mapped_value_list :
-        if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) :
-          line_code_article = mapped_value.getProperty(key='code_article')
-          break
+    line_code_article = movement.Amount_getCodeArticleClient()
+    
+#     variated_reference_list = resource.contentValues(filter={'portal_type':'Variated Reference'})
+#     # we search a variated_reference wich define 'code_article'
+#     my_variated_reference = None
+#     for variated_reference in variated_reference_list :
+#       if len(variated_reference.getMappedValuePropertyList()) <> 0 :
+#         if variated_reference.getMappedValuePropertyList()[0] == 'code_article' :
+#           my_variated_reference = variated_reference
+#           break
+#     if my_variated_reference is not None :
+#       mapped_value_list = my_variated_reference.objectValues()
+#       for mapped_value in mapped_value_list :
+#         if mapped_value.test(my_variated_reference.asContext(categories=variation_list)) :
+#           line_code_article = mapped_value.getProperty(key='code_article')
+#           break
 
     line_items = [line_resource,line_coloris,line_morphologie,line_taille,
                   line_taille_client,line_quantity,line_date,line_code_article]
diff --git a/product/Coramy/skins/coramy_mrp/InventoryMP_fastAddLine.py b/product/Coramy/skins/coramy_mrp/InventoryMP_fastAddLine.py
index b0b658495c..4185e70362 100755
--- a/product/Coramy/skins/coramy_mrp/InventoryMP_fastAddLine.py
+++ b/product/Coramy/skins/coramy_mrp/InventoryMP_fastAddLine.py
@@ -18,7 +18,7 @@ try:
   if product_reference_list <> '' :
     product_list += product_reference_list
 
-  if len(supplier_list) > 0 :
+  elif len(supplier_list) > 0 :
     product_raw_list = context.Resource_sqlResourceSupplierSearch(supplier_title_list=supplier_list)
     for product_item in product_raw_list :
       product_list.append(product_item.title)
diff --git a/product/Coramy/skins/coramy_mrp/PieceTissu_fastInput.py b/product/Coramy/skins/coramy_mrp/PieceTissu_fastInput.py
index 70a823d1b8..1ded3b86b4 100755
--- a/product/Coramy/skins/coramy_mrp/PieceTissu_fastInput.py
+++ b/product/Coramy/skins/coramy_mrp/PieceTissu_fastInput.py
@@ -28,6 +28,10 @@ try :
 
     if line.find(text_list[0]) <> (-1) : # quantity
       # create previous item
+      # first check if needed if quantity compatible with parent_item
+      if my_quantity is not None and my_container.getPortalType() == 'Piece Tissu' :
+        if my_quantity >= my_container.getRemainingQuantity() :
+          my_quantity = None
       if my_quantity is not None :
         compteur += 1
         new_id = str(my_container.generateNewId(default = 40000))
diff --git a/product/Coramy/skins/coramy_mrp/PieceTissu_fastInputRetour.py b/product/Coramy/skins/coramy_mrp/PieceTissu_fastInputRetour.py
index c3d470c24e..9ca4f74bbc 100755
--- a/product/Coramy/skins/coramy_mrp/PieceTissu_fastInputRetour.py
+++ b/product/Coramy/skins/coramy_mrp/PieceTissu_fastInputRetour.py
@@ -58,7 +58,9 @@ try :
           except :
             quantity = 0
 
-          if not quantity in (0, 0.0, '0') :
+          if quantity < 0 :
+            error_item_list.append(id_and_weight_list[i*2]+'(quantité trop importante)')
+          elif not quantity in (0, 0.0, '0') :
             # create the new item
             new_id = str(item.generateNewId(default = 40000))
             item.portal_types.constructContent(type_name = 'Piece Tissu',
@@ -81,11 +83,11 @@ try :
               movement_list[0].setItemIdList(new_aggregated_item_id_list)
             compteur += 1
           else :
-            error_item_list.append(id_and_weight_list[i*2]+'(conversion)')
+            error_item_list.append(id_and_weight_list[i*2]+'(conversion kg mètre impossible)')
         else :
           error_item_list.append(id_and_weight_list[i*2]+'(non sortie ou plusieurs sorties)')
       else :
-        error_item_list.append(id_and_weight_list[i*2]+'(quantité)')
+        error_item_list.append(id_and_weight_list[i*2]+'(quantité mal définie)')
     else :
       error_item_list.append(id_and_weight_list[i*2]+'(inconnue)')
 
diff --git a/product/Coramy/skins/coramy_mrp/PieceTissu_searchByResource.form b/product/Coramy/skins/coramy_mrp/PieceTissu_searchByResource.form
index fd8c7870e3..ff90a74274 100755
--- a/product/Coramy/skins/coramy_mrp/PieceTissu_searchByResource.form
+++ b/product/Coramy/skins/coramy_mrp/PieceTissu_searchByResource.form
@@ -86,7 +86,7 @@
         <values>
           <alternate_name></alternate_name>
           <css_class></css_class>
-          <default>Delivery_zSearchResource</default>
+          <default>PieceTissu_zGetAvailableItemList</default>
           <description></description>
           <display_maxwidth></display_maxwidth>
           <display_width type="int">20</display_width>
@@ -95,7 +95,7 @@
           <hidden type="int">1</hidden>
           <max_length></max_length>
           <required type="int">0</required>
-          <title></title>
+          <title>x</title>
           <truncate type="int">0</truncate>
         </values>
         <tales>
diff --git a/product/Coramy/skins/coramy_mrp/PortalSimulation_activateRequirementList.py b/product/Coramy/skins/coramy_mrp/PortalSimulation_activateRequirementList.py
index 4d70a0ce24..a1f0c2187c 100755
--- a/product/Coramy/skins/coramy_mrp/PortalSimulation_activateRequirementList.py
+++ b/product/Coramy/skins/coramy_mrp/PortalSimulation_activateRequirementList.py
@@ -1,19 +1,31 @@
-# Erase existing auto_planned
-order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
-order_id_list = map(lambda x:x.id,order_list)
-object_id_list = context.ordre_fabrication.objectIds()
-order_id_list = filter(lambda x: x in object_id_list, order_id_list)
-context.ordre_fabrication.deleteContent(order_id_list)
+## Script (Python) "PortalSimulation_activateRequirementList"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+if 1:
+  # Erase existing auto_planned
+  order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
+  order_id_list = map(lambda x:x.id,order_list)
+  object_id_list = context.ordre_fabrication.objectIds()
+  order_id_list = filter(lambda x: x in object_id_list, order_id_list)
+  context.ordre_fabrication.deleteContent(order_id_list)
 
-order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()])
-order_id_list = map(lambda x:x.id,order_list)
-object_id_list = context.commande_achat.objectIds()
-order_id_list = filter(lambda x: x in object_id_list, order_id_list)
-context.commande_achat.deleteContent(order_id_list)
+  order_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()])
+  order_id_list = map(lambda x:x.id,order_list)
+  object_id_list = context.commande_achat.objectIds()
+  order_id_list = filter(lambda x: x in object_id_list, order_id_list) 
+  context.commande_achat.deleteContent(order_id_list)
+
+#return "Done"
 
 # Stock sourcing states
-#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
-source_state_list = None
+source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'started', 'stopped', 'delivered', 'invoiced')
+#source_state_list = None
 
 # Get inventory list
 inventory_list = context.SimulationTool_getGroupFutureInventoryList(simulation_state=source_state_list)
@@ -28,9 +40,9 @@ for inventory_item in inventory_list:
     if movement is not None:
       resource = movement.getResourceValue()
       if resource is not None:
-        # Only source negative stock
-        print "Activate Build Order for %s for missing quantity %s" % (inventory_item.resource_relative_url, inventory_item.inventory)
-        resource.activate(priority=2).PortalSimulation_buildRequirementOrder(resource=inventory_item.resource_relative_url)
+        if resource.getPortalType() != "Assortiment":
+          # Only source negative stock
+          print "Activate Build Order for %s for missing quantity %s" % (inventory_item.resource_relative_url, inventory_item.inventory)
+          resource.activate(priority=2).PortalSimulation_buildRequirementOrder(resource=inventory_item.resource_relative_url)
 
 return printed
-
diff --git a/product/Coramy/skins/coramy_mrp/PortalSimulation_buildRequirementOrder.py b/product/Coramy/skins/coramy_mrp/PortalSimulation_buildRequirementOrder.py
index 66968d13a2..050d304273 100755
--- a/product/Coramy/skins/coramy_mrp/PortalSimulation_buildRequirementOrder.py
+++ b/product/Coramy/skins/coramy_mrp/PortalSimulation_buildRequirementOrder.py
@@ -7,21 +7,20 @@
 ##parameters=resource=None
 ##title=
 ##
-
-from Products.ERP5Type.Document import newTempMovement
+from Products.ERP5.Document import newTempMovement
 from DateTime import DateTime
 
 # Stock sourcing states
-#source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
-source_state_list = None
+source_state_list = ('auto_planned', 'planned', 'ordered', 'confirmed', 'getting_ready', 'ready', 'delivered', 'started', 'stopped', 'invoiced')
+#source_state_list = None
 
 # Default date
-now_date = DateTime()
+now_date = DateTime(DateTime().Date())
 
 # Get inventory list
 inventory_list = context.SimulationTool_getGroupFutureInventoryList(resource=resource, simulation_state=source_state_list)
 # Commit SQL
-# context.portal_simulation.commitTransaction()
+context.portal_simulation.commitTransaction()
 
 # First, find out which resources are missing
 # and build a dictionnary of quantity, variation
@@ -40,7 +39,7 @@ for inventory_item in inventory_list:
         #LOG('ZeroStockRule WARNING',0,'None movement found')
 
 # Commit SQL
-# context.portal_simulation.commitTransaction()
+context.portal_simulation.commitTransaction()
 
 # A list of resources to create
 to_create = quantity_dict.keys()
@@ -93,4 +92,4 @@ for order in order_list:
   order.autoPlan()
   order.purchase_order_apply_condition()
 
-return printed
\ No newline at end of file
+return printed
diff --git a/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py b/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py
index 778e7288c0..f58476bad8 100755
--- a/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py
+++ b/product/Coramy/skins/coramy_mrp/PortalSimulation_updateAssetPrice.py
@@ -7,24 +7,12 @@
 ##parameters=
 ##title=
 ##
-mlist = context.Resource_zGetMovementHistoryList(resource = ["modele/417P401"],
-		variation_text = """coloris/modele/417P401/1_espace_stuc
-taille/enfant/10 ans""",
-		section_category = "group/Coramy",
-		node_category= "site/Stock_PF",
-                strict_membership = 0,
-                simulation_state = ('delivered', 'started', 'stopped', 'invoiced'))
-
-print map(lambda x:x.relative_url, mlist)
-print "next" 
-
 result = context.portal_simulation.updateAssetPrice(
 		"modele/417P401",
 		"""coloris/modele/417P401/1_espace_stuc
 taille/enfant/10 ans""",
 		"group/Coramy",
 		"site/Stock_PF"
-
 	)
 
 for i in result:
diff --git a/product/Coramy/skins/coramy_mrp/Resource_zGetInventoryList.zsql b/product/Coramy/skins/coramy_mrp/Resource_zGetInventoryList.zsql
index a1dbbdfb3e..3bf2e4096b 100755
--- a/product/Coramy/skins/coramy_mrp/Resource_zGetInventoryList.zsql
+++ b/product/Coramy/skins/coramy_mrp/Resource_zGetInventoryList.zsql
@@ -23,9 +23,11 @@ omit_simulation
 omit_input
 omit_output
 simulation_state
-query</params>
+query
+calculate_asset:int=0</params>
 SELECT
 	SUM(stock.quantity) AS inventory,
+	<dtml-if "calculate_asset != 0"> SUM(stock.total_asset_price) AS asset_price, </dtml-if>
 	node.title AS node_title,
 	node.relative_url AS node_relative_url,
 	section.title AS section_title,
diff --git a/product/Coramy/skins/coramy_mrp/SimulationTool_zGetCoramyFutureInventoryList.zsql b/product/Coramy/skins/coramy_mrp/SimulationTool_zGetCoramyFutureInventoryList.zsql
index 3a208af4e8..7bfb60a0ca 100755
--- a/product/Coramy/skins/coramy_mrp/SimulationTool_zGetCoramyFutureInventoryList.zsql
+++ b/product/Coramy/skins/coramy_mrp/SimulationTool_zGetCoramyFutureInventoryList.zsql
@@ -7,7 +7,9 @@ cache_time:0
 class_name:ZSQLBrain
 class_file:zsqlbrain.py
 </dtml-comment>
-<params>to_date</params>
+<params>to_date
+resource
+simulation_state:list</params>
 SELECT 
         SUM(stock.quantity) as inventory,
 	section.title AS section_title,
@@ -29,7 +31,9 @@ AND	stock.section_uid = section_category.uid
 AND	(node_category.category_uid=<dtml-var "portal_categories.site.Stock_MP.getUid()">
 OR	node_category.category_uid=<dtml-var "portal_categories.site.Stock_PF.getUid()">)
 AND	stock.node_uid = node_category.uid
-<dtml-if to_date>AND	movement.stop_date < <dtml-sqlvar to_date type="string">
+<dtml-if resource>AND	resource.relative_url = <dtml-sqlvar resource type="string">
+</dtml-if><dtml-if to_date> AND	movement.stop_date < <dtml-sqlvar to_date type="string">
+</dtml-if><dtml-if simulation_state> AND (<dtml-in simulation_state> catalog.simulation_state = <dtml-sqlvar sequence-item type="string"><dtml-if sequence-end><dtml-else> OR </dtml-if></dtml-in>)
 </dtml-if>
 GROUP BY
 	resource.uid, movement.variation_text
diff --git a/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py b/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py
index 27ed12f097..4022508e06 100755
--- a/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py
+++ b/product/Coramy/skins/coramy_mrp/ZeroStock_buildOrderList.py
@@ -7,28 +7,35 @@
 ##parameters=
 ##title=
 ##
-if 1:
+return   context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
+
+if 0:
   # Delete all proposed orders
-  for o in context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()]) :
-    realo = o.getObject()
-    realo.aq_parent.deleteContent(realo.getId())
+  #production_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.ordre_fabrication.getUid()])
+  #context.ordre_fabrication.deleteContent(map(lambda b:b.id, production_list))
+  buy_list = context.portal_catalog(simulation_state="auto_planned", parent_uid=[context.commande_achat.getUid()])
+  #return map(lambda b:b.id, buy_list)
+  #context.commande_achat.deleteContent(map(lambda b:b.id, buy_list))
 
   # Empty Zero Stock
   context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
 
+  context.portal_simulation.commitTransaction() # Release any SQL locks
+
   # Expand Zero Stock as many times as needed (1 or 2 for the Coramy case)
   # for i in range(0,1):
-  context.portal_simulation.zero_stock.expand()
+  context.portal_simulation.portal_simulation.zero_stock.expand()
 
 # Collect movements in Zero Stock applied rule
 zs_movement_list = context.portal_simulation.zero_stock.contentValues()
+#return len(zs_movement_list )
+#context.portal_simulation.commitTransaction() # Release any SQL locks
 
 # keep only movements with a Modele resource
 movement_list = []
-for movement in zs_movement_list[0:100] :
+for movement in zs_movement_list:
   resource_value = movement.getResourceValue()
   if resource_value is not None:
-    #if resource_value.getPortalType() == 'Modele' :
     movement_list.append(movement)
 
 # Parse movements into a root group
@@ -40,6 +47,9 @@ for order in order_list:
   order.autoPlan()
   order.purchase_order_apply_condition()
 
+context.portal_simulation.commitTransaction() # Release any SQL locks
+return "Done"
+
 # reEmpty Zero Stock because we don't want to see the zero_stock quantities in the columns future_stock
 context.portal_simulation.zero_stock.deleteContent(context.portal_simulation.zero_stock.contentIds())
 
diff --git a/product/Coramy/skins/coramy_mrp/item_tissu_list.form b/product/Coramy/skins/coramy_mrp/item_tissu_list.form
index c7732d3e14..2da60ef698 100755
--- a/product/Coramy/skins/coramy_mrp/item_tissu_list.form
+++ b/product/Coramy/skins/coramy_mrp/item_tissu_list.form
@@ -15,10 +15,10 @@
 
       <field><id>listbox</id> <type>ListBox</type>
         <values>
-          <all_columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLocation', 'Emplacement')]</all_columns>
+          <all_columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLastLocationTitle', 'Localisation'), ('getLocation', 'Emplacement')]</all_columns>
           <all_editable_columns type="list">[]</all_editable_columns>
           <alternate_name></alternate_name>
-          <columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLocation', 'Emplacement')]</columns>
+          <columns type="list">[('id', 'N\xb0 pi\xe8ce'), ('default_resource_title', 'Tissu'), ('getColoris', 'Coloris'), ('getRemainingQuantity', 'Quantit\xe9'), ('default_source_title', 'Fournisseur'), ('default_source_reference', 'R\xe9f\xe9rence Fournisseur'), ('bain_teinture', 'Bain de teinture'), ('getLaizeUtile', 'Laize utile'), ('getLastLocationTitle', 'Localisation'), ('getLocation', 'Emplacement')]</columns>
           <css_class></css_class>
           <default></default>
           <default_params type="list">[('id', "''")]</default_params>
@@ -31,7 +31,7 @@
           <hidden type="int">0</hidden>
           <lines type="int">30</lines>
           <list_action>list</list_action>
-          <list_method type="method">PieceTissu_zGetAvailableItemList</list_method>
+          <list_method type="method">portal_catalog</list_method>
           <meta_types type="list">[]</meta_types>
           <portal_types type="list">[('Piece Tissu', 'Piece Tissu')]</portal_types>
           <report_root_list type="list">[]</report_root_list>
@@ -45,6 +45,7 @@
           <title>Pièces de tissu</title>
         </values>
         <tales>
+          <list_method>python:here.getPortalObject().portal_skins.local_list_method[here.REQUEST.list_method_id]</list_method>
         </tales>
         <messages>
           <message name="external_validator_failed">The input failed the external validator.</message>
diff --git a/product/Coramy/skins/coramy_mrp/item_tissu_view.form b/product/Coramy/skins/coramy_mrp/item_tissu_view.form
index f0c93e9b59..9b1b1ef999 100755
--- a/product/Coramy/skins/coramy_mrp/item_tissu_view.form
+++ b/product/Coramy/skins/coramy_mrp/item_tissu_view.form
@@ -114,6 +114,30 @@
           <message name="not_float">You did not enter a floating point number.</message>
         </messages>
       </field>
+      <field><id>my_last_location_title</id> <type>StringField</type>
+        <values>
+          <alternate_name></alternate_name>
+          <css_class></css_class>
+          <default></default>
+          <description></description>
+          <display_maxwidth></display_maxwidth>
+          <display_width type="int">20</display_width>
+          <external_validator></external_validator>
+          <extra></extra>
+          <hidden type="int">0</hidden>
+          <max_length></max_length>
+          <required type="int">0</required>
+          <title>Localisation</title>
+          <truncate type="int">0</truncate>
+        </values>
+        <tales>
+        </tales>
+        <messages>
+          <message name="external_validator_failed">The input failed the external validator.</message>
+          <message name="required_not_found">Input is required but no input given.</message>
+          <message name="too_long">Too much input was given.</message>
+        </messages>
+      </field>
       <field><id>my_location</id> <type>StringField</type>
         <values>
           <alternate_name></alternate_name>
diff --git a/product/Coramy/skins/coramy_pdm/TransformedComponent_getCorrespondanceList.py b/product/Coramy/skins/coramy_pdm/TransformedComponent_getCorrespondanceList.py
index 9bf9d16efd..f395c3bf04 100755
--- a/product/Coramy/skins/coramy_pdm/TransformedComponent_getCorrespondanceList.py
+++ b/product/Coramy/skins/coramy_pdm/TransformedComponent_getCorrespondanceList.py
@@ -4,7 +4,7 @@
 ##bind namespace=
 ##bind script=script
 ##bind subpath=traverse_subpath
-##parameters=transformation=None, quantities=1
+##parameters=
 ##title=
 ##
 transformed_component = context
@@ -14,9 +14,8 @@ variation_base_category_list = []
 q_variation_base_category_list = transformed_component.getQVariationBaseCategoryList()
 v_variation_base_category_list = transformed_component.getVVariationBaseCategoryList()
 
-if quantities :
-  for base_category in q_variation_base_category_list :
-    variation_base_category_list.append(base_category)
+for base_category in q_variation_base_category_list :
+  variation_base_category_list.append(base_category)
 
 for base_category in v_variation_base_category_list :
   if not base_category in variation_base_category_list :
@@ -26,7 +25,7 @@ variation_base_category_list.sort()
 variation_list_list = []
 
 for base_category in variation_base_category_list :
-  variation_list = transformation.getVariationCategoryList(base_category_list = base_category)
+  variation_list = context.aq_parent.getVariationCategoryList(base_category_list = base_category)
   variation_list_list.append(variation_list)
 
 cartesian_variation_list = context.cartesianProduct(variation_list_list)
@@ -55,14 +54,6 @@ for variation_list in cartesian_variation_list :
     pretty_variation_2 = '- '
     for my_variation in variation :
       pretty_variation_2 += my_variation+' - '
-    if pretty_variation_2 == '- ' :
-      try :
-        pretty_variation_2 += transformed_component.getVariationCategoryList()[0]
-      except :
-        pass
-    if quantities :
-      correspondance_list.append([pretty_variation_1, quantity, pretty_variation_2])
-    else :
-      correspondance_list.append([pretty_variation_1, '', pretty_variation_2])
+    correspondance_list.append([pretty_variation_1, quantity, pretty_variation_2])
 
 return correspondance_list
diff --git a/product/Coramy/skins/coramy_pdm/transformation_correspondances_print.pt b/product/Coramy/skins/coramy_pdm/transformation_correspondances_print.pt
index 0e53f6df8f..10897cfcd4 100755
--- a/product/Coramy/skins/coramy_pdm/transformation_correspondances_print.pt
+++ b/product/Coramy/skins/coramy_pdm/transformation_correspondances_print.pt
@@ -90,7 +90,7 @@
       <tr>
         <td colspan="3" >
           <table class="border" border="0" width="100%"
-                  tal:define="correspondances_list python:transformed_resource.TransformedComponent_getCorrespondanceList(transformation,quantities=0)">
+                  tal:define="correspondances_list python:transformed_resource.TransformedComponent_getCorrespondanceList()">
           <tr tal:condition="python:len(correspondances_list)==0">
             <td>
               <span tal:repeat="variation_item python:transformed_resource.getVariationCategoryList()">
diff --git a/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py b/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py
index c1031316f4..fa22ab7109 100755
--- a/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py
+++ b/product/Coramy/skins/coramy_trade/Container_printExtandLabel.py
@@ -47,6 +47,8 @@ elif local_user == 'Jocelyne_Olejarz' :
   printer_name = 'Meto_XS40_4'
 elif local_user == 'Nathalie_Wadoux' :
   printer_name = 'Meto_XS40_5'
+elif local_user == 'Chantal_Hannequin' :
+  printer_name = 'Meto_XS40_6'
 else :
   printer_name = 'Meto_XS40_2'
 
diff --git a/product/Coramy/skins/coramy_trade/Container_printMetoLabel.py b/product/Coramy/skins/coramy_trade/Container_printMetoLabel.py
index 4b8427c527..e899b5decc 100755
--- a/product/Coramy/skins/coramy_trade/Container_printMetoLabel.py
+++ b/product/Coramy/skins/coramy_trade/Container_printMetoLabel.py
@@ -22,6 +22,8 @@ elif local_user == 'Jocelyne_Olejarz' :
   printer_name = 'Meto_XS40_4'
 elif local_user == 'Nathalie_Wadoux' :
   printer_name = 'Meto_XS40_5'
+elif local_user == 'Chantal_Hannequin' :
+  printer_name = 'Meto_XS40_6'
 else :
   printer_name = 'Meto_XS40_2'
 
diff --git a/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py b/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py
index 5e87bd7e8b..927e851e85 100755
--- a/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py
+++ b/product/Coramy/skins/coramy_trade/Container_sendExtandEdi.py
@@ -21,7 +21,7 @@ def decoupe(s,width):
         result = s[-width:]
     else:
         #result = string.ljust(s,width)
-        result = (' ' * (width-len(s))) + s
+        result = s + (' ' * (width-len(s)))
         #return ' '+s
     return result
 
diff --git a/product/Coramy/skins/coramy_trade/DeliveryLine_getTargetQuantityList.py b/product/Coramy/skins/coramy_trade/DeliveryLine_getTargetQuantityList.py
index d703d0e305..99c62c1209 100755
--- a/product/Coramy/skins/coramy_trade/DeliveryLine_getTargetQuantityList.py
+++ b/product/Coramy/skins/coramy_trade/DeliveryLine_getTargetQuantityList.py
@@ -20,8 +20,8 @@ def category_property(category, property):
   else :
     return " "
 
-for taille in taille_list :
-  my_taille = 'taille/'+taille
+if len(taille_list) == 0 :
+  my_taille = None
   if coloris is not None and morphologie is not None :
     my_coloris = 'coloris/'+coloris
     my_morphologie = 'morphologie/'+morphologie
@@ -40,5 +40,26 @@ for taille in taille_list :
       target_quantity_list.append(delivery_line.getCell(None, my_taille, base_id='movement').getProperty(key="target_quantity"))
     else :
       target_quantity_list.append(0)
+else :
+  for taille in taille_list :
+    my_taille = 'taille/'+taille
+    if coloris is not None and morphologie is not None :
+      my_coloris = 'coloris/'+coloris
+      my_morphologie = 'morphologie/'+morphologie
+      if delivery_line.getCell(my_coloris, my_taille, my_morphologie, base_id='movement') <> None :
+        target_quantity_list.append(delivery_line.getCell(my_coloris, my_taille, my_morphologie, base_id='movement').getProperty(key="target_quantity"))
+      else :
+        target_quantity_list.append(0)
+    elif coloris is not None :
+      my_coloris = 'coloris/'+coloris
+      if delivery_line.getCell(my_coloris, my_taille, base_id='movement') <> None :
+        target_quantity_list.append(delivery_line.getCell(my_coloris, my_taille, base_id='movement').getProperty(key="target_quantity"))
+      else :
+        target_quantity_list.append(0)
+    else : # coloris is None :
+      if delivery_line.getCell(None, my_taille, base_id='movement') <> None :
+        target_quantity_list.append(delivery_line.getCell(None, my_taille, base_id='movement').getProperty(key="target_quantity"))
+      else :
+        target_quantity_list.append(0)
 
 return target_quantity_list
diff --git a/product/Coramy/skins/coramy_trade/Delivery_exportContainerList.py b/product/Coramy/skins/coramy_trade/Delivery_exportContainerList.py
index 2b92fe4d4b..3172747499 100755
--- a/product/Coramy/skins/coramy_trade/Delivery_exportContainerList.py
+++ b/product/Coramy/skins/coramy_trade/Delivery_exportContainerList.py
@@ -31,7 +31,10 @@ for container_item in container_list :
   ligne_container += str(container.getGrossWeight())+tab
   ligne_container += first_line.getResourceValue().getId()+tab
   ligne_container += delivery.getDestinationSectionTitle()+tab
-  ligne_container += first_line.getColorisValue().getId()+tab
+  if first_line.getColorisValue() is not None :
+    ligne_container += first_line.getColorisValue().getId()+tab
+  else :
+    ligne_container += ''+tab
   ligne_container += first_line.Amount_getTailleClient()+tab
   ligne_container += "Maillot de bain"+tab
   ligne_container += first_line.Amount_getCodeArticleClient()+tab
diff --git a/product/Coramy/skins/coramy_trade/default_pdf_template.pt b/product/Coramy/skins/coramy_trade/default_pdf_template.pt
index 9a173a0156..9ae10f1a2e 100755
--- a/product/Coramy/skins/coramy_trade/default_pdf_template.pt
+++ b/product/Coramy/skins/coramy_trade/default_pdf_template.pt
@@ -10,16 +10,34 @@
           allowsplitting="1"
           tal:define="packing_list python:here.getCausalityValueList(portal_type=['Sale Packing List','Sales Packing List'])[0];
                       invoice_id python:here.getId();
+                      invoice_reference python: here.getReference(0);
                       resource_title python:here.getResourceTitle() or 'Euros';
                       resource_id python:here.getResourceId() or 'EUR';
-                      income python: here.income;
-                      vat python: here.vat;
-                      payable python: here.payable;">
+                      income python: here.Invoice_zGetTotalNetPrice();
+                      vat python: here.Invoice_zGetTotalVat();
+                      payable python: here.getDefaultTotalPrice();
+                      payable python: income + vat;
+                      vad_recoverable python: here.getValueAddedTaxRecoverable();
+                      vad_ratio python: here.getValueAddedTaxRatio(); 
+                      source_decision_title python: here.getSourceDecisionTitle();
+                      payment_mode python: here.getPaymentMode();
+                      payment_term python: here.getPaymentTerm(30);
+                      incoterm python: packing_list.getIncotermId();
+                      delivery_mode python: packing_list.getDeliveryModeTitle().split('/')[-1];
+                      escompte_value python:  here.Invoice_zGetEscompteDescription();
+                      container_number python: len(packing_list.contentValues(filter={'portal_type':'Container'}));
+                      total_price python:here.getDefaultTotalPrice();">
+
+  <!-- due_date python: DateTime.getNextMonth(start_date.month(), start_date.year())  ; -->
   <tal:block
-    tal:define="destination python: packing_list.getDestinationValue();
-                destination_administration python: packing_list.getDestinationAdministrationValue() or packing_list.getDestinationSectionValue();
-                start_date python:packing_list.getStartDate();
+    tal:define="destination python: here.getDestinationValue();
+                destination_administration python: here.getDestinationAdministrationValue() or here.getDestinationSectionValue();
+                DateTime python: modules['DateTime'].DateTime;
+                start_date python:here.getStartDate( packing_list.getTargetStopDate() ) ;
+                due_date python: here.Invoice_zGetDueDate();
                 packing_list_id python:packing_list.getId();
+                code_comptable python: destination_administration.getCodeComptable();
+                eu_vat_code python: destination_administration.getEuVatCode();
                 order python:packing_list.getCausalityValueList(portal_type=['Sale Order','Sales Order'])[0];">
 
     <stylesheet>
@@ -78,7 +96,8 @@
           <stylecmd expr="('RIGHTPADDING', (0,0), (-1,-1), 5)"/>
           <stylecmd expr="('TOPPADDING', (0,0), (-1,-1), 1)"/>
           <stylecmd expr="('BOTTOMPADDING', (0,0), (-1,-1), 1)"/>
-          <stylecmd expr="('ALIGN', (0,0), (-1,-1), 'LEFT')"/>
+          <stylecmd expr="('ALIGN', (0,0), (1,0), 'LEFT')"/>
+          <stylecmd expr="('ALIGN', (2,0), (-1,-1), 'RIGHT')"/>
           <stylecmd expr="('GRID', (0,0), (-1,-1), 0, colors.white)"/>
           <stylecmd expr="('BOX', (0,0), (-1,-1), 0, colors.white)"/>
           <stylecmd expr="('FONT', (0,0), (-1,-1), 'Helvetica', 8)"/>
@@ -132,7 +151,7 @@
 
     </stylesheet>
 
-    <pagetemplate id="FirstPage" nextid="Page" startframe="content">
+    <pagetemplate id="FirstPage" nextid="SecondPage" startframe="content">
       <static>
 
         <!-- Entete CORAMY -->
@@ -159,21 +178,21 @@
 
         <!-- Titre du document (Facture n°) -->
         <infostring align="left" x="6.8cm" y="26cm" size="16"
-          font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n° %s' % invoice_id">
-          Facture n° 105 915
+          font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n° %s' % invoice_reference">
+          Facture n° XXX
         </infostring>
 
         <infostring align="left" x="14cm" y="26cm" size="8"
           font="Helvetica" color="(0,0,0)" tal:content="python: start_date.strftime('Gravelines, le %e/%m/%y')">
-          Gravelines, le 9/07/03
+          Gravelines, le XXX
         </infostring>
 
         <infostring align="left" x="18.5cm" y="26cm" size="8"
           font="Helvetica-Bold" color="(0,0,0)">
-          Folio 1
+          Folio %(page)s
         </infostring>
 
-        <!-- Grand cadre de la fature -->
+        <!-- Grand cadre de la facture -->
         <line x1="1cm" x2="20.5cm" y1="25cm" y2="25cm" width="1"/>
         <line x1="1cm" x2="1cm" y1="25cm" y2="4cm" width="1"/>
         <line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/>
@@ -195,7 +214,7 @@
         </infostring>
         <infostring align="center" x="2.5cm" y="24.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
           tal:content="python: order.getDestinationReference()">
-          7286007
+          DestinationReference XXX
         </infostring>
 
         <infostring align="left" x="1.7cm" y="23.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
@@ -206,7 +225,7 @@
         </infostring>
         <infostring align="center" x="2.5cm" y="23.3cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
           tal:content="python: order.getId()">
-          119 022
+          Order.id XXX
         </infostring>
 
         <infostring align="left" x="1.1cm" y="22.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
@@ -217,33 +236,23 @@
         </infostring>
         <infostring align="center" x="2.5cm" y="22.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
           tal:content="python: packing_list_id">
-          108 301
+          PackingListId XXX
         </infostring>
 
-        <infostring align="left" x="1.1cm" y="21.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="1.7cm" y="21.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Nombre de colis
         </infostring>
-        <infostring align="left" x="1.3cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="1.9cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Kolli anzahl
         </infostring>
-        <infostring align="left" x="1.2cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="1.8cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Nb of parcels
         </infostring>
-        <infostring align="left" x="3.5cm" y="21.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          32
-        </infostring>
-
-        <infostring align="left" x="1.1cm" y="21cm" size="6" font="Helvetica" color="(0,0,0)">
-          Poids brut (kg)
-        </infostring>
-        <infostring align="left" x="1.2cm" y="20.8cm" size="6" font="Helvetica" color="(0,0,0)">
-          Brutto-gewicht
-        </infostring>
-        <infostring align="left" x="1.3cm" y="20.6cm" size="6" font="Helvetica" color="(0,0,0)">
-          Gross weight
+        <infostring align="center" x="2.5cm" y="21.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: container_number">
+          NbrColis XXX
         </infostring>
 
-
         <infostring align="left" x="6cm" y="24.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Livraison / Versand / Delivery
         </infostring>
@@ -279,36 +288,30 @@
         </tal:block>
 
 
-        <infostring align="left" x="4.5cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="4.5cm" y="21.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Commercial
         </infostring>
-        <infostring align="left" x="4.4cm" y="21.5cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="6cm" y="21.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: source_decision_title ">
+          Commercial XXX
+        </infostring>
+        <infostring align="left" x="4.4cm" y="21.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Paiement
         </infostring>
-        <infostring align="left" x="4.6cm" y="21.3cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="4.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Zahlung
         </infostring>
-        <infostring align="left" x="4.5cm" y="21.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="4.5cm" y="20.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Payment
         </infostring>
-        <infostring align="left" x="4.3cm" y="20.7cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
-          Device / Currency / Wahrung
-        </infostring>
-        <infostring align="left" x="5.8cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          Cheque
-        </infostring>
-        <infostring align="left" x="5.8cm" y="21.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          20 jours Net
+        <infostring align="left" x="5.8cm" y="21cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: payment_mode ">
+          payment_modeXXX
         </infostring>
-        <infostring align="left" x="8.5cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
-          tal:content="python: resource_title">
-          Euros
+        <infostring align="left" x="5.8cm" y="20.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: '%i jours Net' % payment_term">
+          payment_termXXX
         </infostring>
-        <infostring align="left" x="10.2cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
-          tal:content="python: resource_id">
-          EUR
-        </infostring>
-
 
         <infostring align="left" x="11.6cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Code comptable
@@ -319,47 +322,50 @@
         <infostring align="left" x="11.6cm" y="20.9cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Conditions d'escompte / Diskont / Discount.
         </infostring>
-        <infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          41REDOU
+        <infostring align="left" x="14cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: code_comptable">
+          CodeComptable XXX
         </infostring>
-        <infostring align="left" x="11.6cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          2,75 sous 20 jours
+        <infostring align="left" x="14cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: eu_vat_code">
+          NoTVAXXX
+        </infostring>
+        <infostring align="left" x="11.6cm" y="20.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: escompte_value">
+          Escompte XXX
         </infostring>
 
 
-        <infostring align="left" x="18.9cm" y="24.6cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
-          Port / Porto
-        </infostring>
-        <infostring align="left" x="19.1cm" y="24.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
-          Freight
-        </infostring>
-        <infostring align="left" x="19cm" y="24cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          Franco
-        </infostring>
-        <infostring align="left" x="18.9cm" y="23.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+
+        <infostring align="left" x="18.9cm" y="24.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Transporteur
         </infostring>
-        <infostring align="left" x="18.6cm" y="23.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="18.6cm" y="24cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Carrier / Spediteur
         </infostring>
-        <infostring align="left" x="18.8cm" y="22.8cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          CORAMY
+        <infostring align="center" x="19.5cm" y="23.6cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: delivery_mode">
+          delivery_modeXXX
         </infostring>
-        <infostring align="left" x="18.6cm" y="22cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="18.6cm" y="23cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Transport
         </infostring>
-        <infostring align="left" x="20cm" y="22cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
+        <infostring align="left" x="20cm" y="23cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
           3
         </infostring>
-        <infostring align="left" x="18.6cm" y="21.4cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="18.6cm" y="22.1cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Transaction
         </infostring>
-        <infostring align="left" x="19.9cm" y="21.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
+        <infostring align="left" x="19.9cm" y="22.1cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
           11
         </infostring>
-        <infostring align="left" x="18.6cm" y="20.8cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
+        <infostring align="left" x="18.6cm" y="21.2cm" size="6" font="Helvetica-Oblique" color="(0,0,0)">
           Livraison
         </infostring>
+        <infostring align="left" x="19.9cm" y="21.2cm" size="8" font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: incoterm">
+          incotermXXX
+        </infostring>
 
         <!-- Détail de la facture -->
         <rectangle x="1cm" y="19.9cm" width="19.5cm" height="0.4cm"
@@ -368,15 +374,15 @@
 
         <infostring align="left" x="2.8cm" y="20cm" size="9"
           font="Helvetica-Oblique" color="(0,0,0)">
-          Denomination des produits
+          Dénomination des produits
         </infostring>
         <infostring align="left" x="10cm" y="20cm" size="9"
           font="Helvetica-Oblique" color="(0,0,0)">
-          Repartition par tailles
+          Répartition par tailles
         </infostring>
         <infostring align="left" x="15.4cm" y="20cm" size="9"
           font="Helvetica-Oblique" color="(0,0,0)">
-          Quantite
+          Quantité
         </infostring>
         <infostring align="left" x="17.1cm" y="20cm" size="9"
           font="Helvetica-Oblique" color="(0,0,0)">
@@ -409,10 +415,12 @@
           font="Helvetica-Oblique" color="(0,0,0)">
           T.V.A.
         </infostring>
-        <infostring align="left" x="9.3cm" y="5.1cm" size="9"
-          font="Helvetica" color="(0,0,0)">
-          19,6%%
-        </infostring>
+        <tal:block tal:condition="python: vad_recoverable">
+          <infostring align="left" x="9.3cm" y="5.1cm" size="9"
+            font="Helvetica" color="(0,0,0)" tal:content="python: '%.1f' % (vad_ratio * 100) + '%%'">
+            19,6%%
+          </infostring>
+        </tal:block>
         <infostring align="left" x="11.2cm" y="5.5cm" size="9"
           font="Helvetica-Oblique" color="(0,0,0)">
           Port
@@ -440,48 +448,249 @@
 
         <infostring align="center" x="2.2cm" y="4.5cm" size="9"
           font="Helvetica" color="(0,0,0)"
-          tal:content="python: '%.2f' % income.getSourceCredit()">
-          14 408,46
+          tal:content="python: '%.2f' % income">
+          income XXX
         </infostring>
-        <infostring align="left" x="6.5cm" y="4.5cm" size="9"
+        <infostring align="center" x="3.8cm" y="4.5cm" size="9"
           font="Helvetica" color="(0,0,0)">
-          14 408,46
+          
         </infostring>
-        <infostring align="center" x="9.7cm" y="4.5cm" size="9"
+        <infostring align="left" x="6.5cm" y="4.5cm" size="9"
           font="Helvetica" color="(0,0,0)"
-          tal:content="python: '%.2f' % vat.getSourceCredit()">
-          2 824,06
+          tal:content="python: '%.2f' % income">
+          
+        </infostring>
+        <tal:block tal:condition="python: vad_recoverable">
+          <infostring align="center" x="9.7cm" y="4.5cm" size="9"
+            font="Helvetica" color="(0,0,0)"
+            tal:content="python: '%.2f' % vat">
+            vat XXX
+          </infostring>
+        </tal:block>
+        <infostring align="left" x="10.7cm" y="4.5cm" size="9"
+          font="Helvetica" color="(0,0,0)">
+          
         </infostring>
         <infostring align="center" x="13.8cm" y="4.5cm" size="10"
           font="Helvetica-Bold" color="(0,0,0)"
-          tal:content="python: '%.2f' % payable.getSourceDebit()">
-          17 232,52
+          tal:content="python: '%.2f' % payable">
+          payable XXX
         </infostring>
         <infostring align="center" x="16cm" y="4.5cm" size="10"
           font="Helvetica-Bold" color="(0,0,0)"
           tal:content="python: resource_id">
-          EUR
+          resource_id XXX 
         </infostring>
         <infostring align="left" x="18cm" y="4.5cm" size="10"
-          font="Helvetica-Bold" color="(0,0,0)">
-          31/07/03
+          font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: due_date.strftime('%e/%m/%y')">
+          due_date XXX
         </infostring>
 
         <infostring align="left" x="1.1cm" y="3.8cm" size="5" font="Helvetica" color="(0,0,0)">
-          En application de la loi du 31/12/1992, nous vous precisons que la presente facture devra etre reglee a la date indiquee ci-dessous. En cas de reglement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionne purra etre deduit du
+          En application de la loi du 31/12/1992, nous vous précisons que la presente facture devra être réglée à la date indiquée ci-dessus. En cas de règlement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionné pourra être déduit du
         </infostring>
         <infostring align="left" x="1.1cm" y="3.5cm" size="5" font="Helvetica" color="(0,0,0)">
-          montant H.T. de la facture, auquel cas le montant de TVA deductible par vous devra etre diminue du montant de celle afférente a l'escompte. Son règlement donnera lieu au versement d'un intérêt moratoire, calcule sur les sommes restant
+          montant H.T. de la facture, auquel cas le montant de TVA déductible par vous devra être diminué du montant de celle afférente à l'escompte. Son règlement donnera lieu au versement d'un intérêt moratoire, calculé sur les sommes restant
         </infostring>
         <infostring align="left" x="1.1cm" y="3.2cm" size="5" font="Helvetica" color="(0,0,0)">
-          dues a cette date de reglement en principal, frais et taxes inclus, et au taux de l'interet legal majore de 5 points, sans que cette penalite puisse etre en toute hypothese inferieure a 1,5 fois le taux de l'interet legal.
+          dues à cette date de règlement en principal, frais et taxes inclus, et au taux de l'intérêt légal majoré de 5 points, sans que cette pénalité puisse être en toute hypothèse inférieure à 1,5 fois le taux de l'intérêt légal.
+        </infostring>
+
+      </static>
+
+      <frame id="content"
+        nextid="content"
+        x="1cm"
+        y="5.8cm"
+        width="19.5cm"
+        height="14.1cm"
+        leftpadding="0.1cm"
+        rightpadding="0.1cm"
+        toppadding="0.2cm"
+        bottompadding="0.5cm"
+        showBoundary="1"/>
+    </pagetemplate>
+
+
+
+
+   <pagetemplate id="SecondPage" nextid="SecondPage" startframe="content">
+      <static>
+
+        <!-- Entete CORAMY -->
+        <infostring align="left" x="1.4cm" y="28cm" size="40"
+          font="Times-Bold" color="(0,0,0)">Coramy</infostring>
+
+        <rectangle x="1cm" y="28cm" width="0.3cm" height="0.4cm"
+          linewidth="0.0" stroke="(1,1,1)" fill="(0.5,0.5,0.5)"/>
+        <rectangle x="6.5cm" y="28cm" width="13.5cm" height="0.4cm"
+          linewidth="0.0" stroke="(1,1,1)" fill="(0.5,0.5,0.5)"/>
+
+        <infostring align="left" x="7cm" y="28.5cm" size="8"
+          font="Helvetica" color="(0,0,0)">
+          5 bis, rue Denis Cordonnier - F.59820 GRAVELINES - Tel. 33(0)3 28 51 91 51 - Fax 33(0)3 28 23 34 96
+        </infostring>
+        <infostring align="left" x="10cm" y="28.1cm" size="8"
+          font="Helvetica" color="(1,1,1)">
+          MAILLOTS DE BAIN - GYM - SWIMSUITS - FITNESS
+        </infostring>
+        <infostring align="left" x="6.8cm" y="27.7cm" size="6"
+          font="Helvetica" color="(0,0,0)">
+          SAS capital de 435.200 EUR - T.V.A. FR 67 611 750 274 - R.C. Dunkerque 611 750 274 - SIRET 611 750 274 00023 - CNUF 15971
+        </infostring>
+
+        <!-- Titre du document (Facture n°) -->
+        <infostring align="left" x="6.8cm" y="26cm" size="16"
+          font="Helvetica-Bold" color="(0,0,0)" tal:content="python: 'Facture n° %s' % invoice_reference">
+          Facture n° XXX
+        </infostring>
+
+        <infostring align="left" x="14cm" y="26cm" size="8"
+          font="Helvetica" color="(0,0,0)" tal:content="python: start_date.strftime('Gravelines, le %e/%m/%y')">
+          Gravelines, le XXX
+        </infostring>
+
+        <infostring align="left" x="18.5cm" y="26cm" size="8"
+          font="Helvetica-Bold" color="(0,0,0)">
+          Folio %(page)s
+        </infostring>
+
+        <!-- Grand cadre de la facture -->
+        <line x1="1cm" x2="20.5cm" y1="25cm" y2="25cm" width="1"/>
+        <line x1="1cm" x2="1cm" y1="25cm" y2="4cm" width="1"/>
+        <line x1="20.5cm" x2="20.5cm" y1="25cm" y2="4cm" width="1"/>
+        <line x1="1cm" x2="20.5cm" y1="4cm" y2="4cm" width="1"/>
+
+        
+        <!-- Détail de la facture -->
+        <rectangle x="1cm" y="24.6cm" width="19.5cm" height="0.4cm"
+          linewidth="0" fill="(0.75,0.75,0.75)"/>
+        <line x1="1cm" x2="20.5cm" y1="24.6cm" y2="24.6cm" width="1"/>
+
+        <infostring align="left" x="2.8cm" y="24.7cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Dénomination des produits
+        </infostring>
+        <infostring align="left" x="10cm" y="24.7cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Répartition par tailles
+        </infostring>
+        <infostring align="left" x="15.4cm" y="24.7cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Quantité
+        </infostring>
+        <infostring align="left" x="17.1cm" y="24.7cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          P.U.H.T.
+        </infostring>
+        <infostring align="left" x="18.8cm" y="24.7cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Total H.T.
+        </infostring>
+
+        <!-- Pied de facture -->
+        <rectangle x="1cm" y="5.0cm" width="19.5cm" height="0.8cm"
+          linewidth="0" fill="(0.75,0.75,0.75)"/>
+        <line x1="1cm" x2="20.5cm" y1="5.8cm" y2="5.8cm" width="1"/>
+        <line x1="1cm" x2="20.5cm" y1="5.0cm" y2="5.0cm" width="1"/>
+
+        <infostring align="left" x="1.5cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Total H.T.
+        </infostring>
+        <infostring align="left" x="3.8cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Port taxable
+        </infostring>
+        <infostring align="left" x="6.2cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Montant taxable
+        </infostring>
+        <infostring align="left" x="9.2cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          T.V.A.
+        </infostring>
+        <tal:block tal:condition="python: vad_recoverable">
+          <infostring align="left" x="9.3cm" y="5.1cm" size="9"
+            font="Helvetica" color="(0,0,0)" tal:content="python: '%.1f' % (vad_ratio * 100) + '%%'">
+            19,6%%
+          </infostring>
+        </tal:block>
+        <infostring align="left" x="11.2cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Port
+        </infostring>
+        <infostring align="left" x="10.7cm" y="5.1cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          non taxable
+        </infostring>
+        <infostring align="left" x="13.8cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Net a payer
+        </infostring>
+        <infostring align="left" x="12.6cm" y="5.1cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Gesamtbetrag / Total amount
+        </infostring>
+        <infostring align="left" x="17.5cm" y="5.5cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Date d'echeance
+        </infostring>
+        <infostring align="left" x="17cm" y="5.1cm" size="9"
+          font="Helvetica-Oblique" color="(0,0,0)">
+          Falligkeitstag / Due date
         </infostring>
 
-        <infostring align="left" x="1.6cm" y="2.7cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          Nos marchandises sont grevees d'une clause de reserve de propriete, reprise dans nos conditions generales de venteindiquees au verso
+        <infostring align="center" x="2.2cm" y="4.5cm" size="9"
+          font="Helvetica" color="(0,0,0)"
+          tal:content="python: '%.2f' % income">
+          income XXX
         </infostring>
-        <infostring align="left" x="4.5cm" y="2.4cm" size="8" font="Helvetica-Bold" color="(0,0,0)">
-          Allegemeine Verkaufsbedingungen auf ruckseite - General sales conditions overleaf
+        <infostring align="center" x="3.8cm" y="4.5cm" size="9"
+          font="Helvetica" color="(0,0,0)">
+          
+        </infostring>
+        <infostring align="left" x="6.5cm" y="4.5cm" size="9"
+          font="Helvetica" color="(0,0,0)"
+          tal:content="python: '%.2f' % income">
+          
+        </infostring>
+        <tal:block tal:condition="python: vad_recoverable">
+          <infostring align="center" x="9.7cm" y="4.5cm" size="9"
+            font="Helvetica" color="(0,0,0)"
+            tal:content="python: '%.2f' % vat">
+            vat XXX
+          </infostring>
+        </tal:block>
+        <infostring align="left" x="10.7cm" y="4.5cm" size="9"
+          font="Helvetica" color="(0,0,0)">
+          
+        </infostring>
+        <infostring align="center" x="13.8cm" y="4.5cm" size="10"
+          font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: '%.2f' % payable">
+          payable XXX
+        </infostring>
+        <infostring align="center" x="16cm" y="4.5cm" size="10"
+          font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: resource_id">
+          resource_id XXX 
+        </infostring>
+        <infostring align="left" x="18cm" y="4.5cm" size="10"
+          font="Helvetica-Bold" color="(0,0,0)"
+          tal:content="python: due_date.strftime('%e/%m/%y')">
+          due_date XXX
+        </infostring>
+
+        <infostring align="left" x="1.1cm" y="3.8cm" size="5" font="Helvetica" color="(0,0,0)">
+          En application de la loi du 31/12/1992, nous vous précisons que la presente facture devra être réglée à la date indiquée ci-dessus. En cas de règlement comptant sous 10 jours, date de facture, l'escompte ci-dessus mentionné pourra être déduit du
+        </infostring>
+        <infostring align="left" x="1.1cm" y="3.5cm" size="5" font="Helvetica" color="(0,0,0)">
+          montant H.T. de la facture, auquel cas le montant de TVA déductible par vous devra être diminué du montant de celle afférente à l'escompte. Son règlement donnera lieu au versement d'un intérêt moratoire, calculé sur les sommes restant
+        </infostring>
+        <infostring align="left" x="1.1cm" y="3.2cm" size="5" font="Helvetica" color="(0,0,0)">
+          dues à cette date de règlement en principal, frais et taxes inclus, et au taux de l'intérêt légal majoré de 5 points, sans que cette pénalité puisse être en toute hypothèse inférieure à 1,5 fois le taux de l'intérêt légal.
         </infostring>
 
       </static>
@@ -491,7 +700,7 @@
         x="1cm"
         y="5.8cm"
         width="19.5cm"
-        height="14.1cm"
+        height="18.8cm"
         leftpadding="0.1cm"
         rightpadding="0.1cm"
         toppadding="0.2cm"
@@ -499,6 +708,10 @@
         showBoundary="1"/>
     </pagetemplate>
 
+
+
+
+
     <pagetemplate id="Page" >
 
       <static>
@@ -522,4 +735,4 @@
     </pagetemplate>
 
   </tal:block>
-</template>
+</template>
\ No newline at end of file
diff --git a/product/Coramy/skins/coramy_trade/purchase_packing_list_view.form b/product/Coramy/skins/coramy_trade/purchase_packing_list_view.form
index 042ee6419d..c39284b2e0 100755
--- a/product/Coramy/skins/coramy_trade/purchase_packing_list_view.form
+++ b/product/Coramy/skins/coramy_trade/purchase_packing_list_view.form
@@ -500,10 +500,10 @@
 
       <field><id>listbox</id> <type>ListBox</type>
         <values>
-          <all_columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('quantity_unit', 'Unit\xe9')]</all_columns>
+          <all_columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('price', 'Prix'), ('quantity_unit', 'Unit\xe9')]</all_columns>
           <all_editable_columns type="list">[]</all_editable_columns>
           <alternate_name></alternate_name>
-          <columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('getPurchaseDeliveryCellSourceReference', 'R\xe9f. fournisseur'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('quantity_unit', 'Unit\xe9')]</columns>
+          <columns type="list">[('resource_title', 'Produit'), ('variation_text', 'Variantes'), ('getPurchaseDeliveryCellSourceReference', 'R\xe9f. fournisseur'), ('quantity', 'Objectif quantit\xe9'), ('target_quantity', 'Quantit\xe9'), ('item_id_list', 'Lots associ\xe9s'), ('price', 'Prix'), ('quantity_unit', 'Unit\xe9')]</columns>
           <css_class></css_class>
           <default></default>
           <default_params type="list">[]</default_params>
diff --git a/product/Coramy/skins/coramy_trade/sales_invoice_list.form b/product/Coramy/skins/coramy_trade/sales_invoice_list.form
index 65085c20b8..f90963633e 100755
--- a/product/Coramy/skins/coramy_trade/sales_invoice_list.form
+++ b/product/Coramy/skins/coramy_trade/sales_invoice_list.form
@@ -15,10 +15,10 @@
 
       <field><id>listbox</id> <type>ListBox</type>
         <values>
-          <all_columns type="list">[('id', 'Commande'), ('default_destination_title', 'Client'), ('buyer_title', 'Acheteur'), ('Description', 'Description'), ('order_state', 'Etat')]</all_columns>
+          <all_columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</all_columns>
           <all_editable_columns type="list">[]</all_editable_columns>
           <alternate_name></alternate_name>
-          <columns type="list">[('id', 'Facture'), ('default_destination_title', 'Client'), ('buyer_title', 'Acheteur'), ('Description', 'Description'), ('order_state', 'Etat')]</columns>
+          <columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</columns>
           <css_class></css_class>
           <default></default>
           <default_params type="list">[('id', "''")]</default_params>
@@ -37,7 +37,7 @@
           <report_root_list type="list">[]</report_root_list>
           <report_tree type="int">0</report_tree>
           <search type="int">1</search>
-          <search_columns type="list">[]</search_columns>
+          <search_columns type="list">[('id', 'Identifiant'), ('reference', 'Num\xe9ro de facture'), ('destination_administration_organisation_title', 'Factur\xe9e \xe0'), ('causality_id', 'Livraison vente'), ('description', 'Description'), ('simulation_state', 'Etat')]</search_columns>
           <select type="int">1</select>
           <selection_name>order_selection</selection_name>
           <sort type="list">[('id', 'id')]</sort>
diff --git a/product/Coramy/skins/coramy_trade/sales_packing_list_print.pt b/product/Coramy/skins/coramy_trade/sales_packing_list_print.pt
index d823588061..cb6ca5a772 100755
--- a/product/Coramy/skins/coramy_trade/sales_packing_list_print.pt
+++ b/product/Coramy/skins/coramy_trade/sales_packing_list_print.pt
@@ -101,7 +101,7 @@
                       <TD align="left" tal:content="python:'coloris '+coloris_list[1][index]"></TD>
                       <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/>
                       <SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2],coloris_list[2][index])">
-                        <TD align = right tal:content="python: '%.0f' %target_quantity"/>
+                        <TD tal:condition="python:taille_qty!=0" align = "right" tal:content="python: '%.0f' %target_quantity"/>
                         <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/>
                       </SPAN>
                       <TD align="right" tal:content="python: '%.0f' %totalizer[2]"/>
@@ -112,7 +112,8 @@
                     <TR><!-- PAS DE COLORIS -->
                       <TD align="left"></TD>
                       <SPAN tal:define="toto python:delivery_line.PT_reset_total_list(totalizer,[2])"/>
-                      <SPAN tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2])">
+                      <SPAN tal:condition="python:taille_qty!=0"
+                      tal:repeat="target_quantity python:delivery_line.DeliveryLine_getTargetQuantityList(taille_list[2])">
                         <TD align = right tal:content="python: '%.0f' %target_quantity"/>
                         <SPAN tal:define="toto python:delivery_line.PT_update_total_list(totalizer,[0,1,2],target_quantity)"/>
                       </SPAN>
diff --git a/product/ERP5/Document/Amount.py b/product/ERP5/Document/Amount.py
index 2e5446d83b..823b86802c 100755
--- a/product/ERP5/Document/Amount.py
+++ b/product/ERP5/Document/Amount.py
@@ -116,17 +116,18 @@ class Amount(Base, Variated):
     self._setVariationValue(variation_value)
     self.reindexObject()
 
+
   security.declareProtected(Permissions.AccessContentsInformation,
-                                              'getVariationRangeCategoryItemList')
+                                                'getVariationRangeCategoryItemList')
   def getVariationRangeCategoryItemList(self, base_category_list = (),
-                              method_id='getTitle', base=1,  current_category=None):
+                                        method_id='getTitle', base=1,  start_with_item=None):
     """
       Returns possible category items for this amount ie.
       the variation of the resource (not the variation range)
     """
     try:
       return self.getDefaultResourceValue().getVariationCategoryItemList(
-             base_category_list, method_id=method_id, base=base, current_category=current_category)
+               base_category_list, method_id=method_id, base=base, start_with_item=start_with_item)
     except:
       # FIXME: method_name vs. method_id, start_with_item vs. start_with_empty, etc. -yo
       return self.portal_categories.getCategoryChildItemList()
@@ -294,7 +295,7 @@ class Amount(Base, Variated):
     """
     quantity = self.getConvertedTargetQuantity()
     efficiency = self.getTargetEfficiency()
-    if efficiency in (0, 0.0, None):
+    if efficiency in (0, 0.0, None, ''):
       efficiency = 1.0
     if quantity not in (None, ''):
       return float(quantity) / efficiency
@@ -425,6 +426,15 @@ class Amount(Base, Variated):
       else:
         return 0.0
 
+  # Inventory
+  security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
+  def getConvertedInventory(self):
+    """
+      provides a default inventory value - None since
+      no inventory was defined.
+    """
+    return None
+
   # Profit and Loss
   security.declareProtected(Permissions.ModifyPortalContent, 'getLostQuantity')
   def getLostQuantity(self):
diff --git a/product/ERP5/Document/Container.py b/product/ERP5/Document/Container.py
index f16f8fa93a..8947ddcb41 100755
--- a/product/ERP5/Document/Container.py
+++ b/product/ERP5/Document/Container.py
@@ -204,3 +204,17 @@ Une ligne tarifaire."""
         more_result += container.getContainerText()
       result = result + '\n'.join(map(lambda x: " %s" % x, more_result.split('\n')))
       return result
+
+    # Used for optimization - requires reindexing using container_uid 
+    security.declareProtected(Permissions.AccessContentsInformation, 'getContainerUid')
+    def getContainerUid(self):
+      return self.getUid()
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getContainerValue')
+    def getContainerValue(self):
+      return self
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getContainer')
+    def getContainer(self):
+      return self.getRelativeUrl()
+
diff --git a/product/ERP5/Document/DeliveryCell.py b/product/ERP5/Document/DeliveryCell.py
index 8fded75deb..bb47e4cd75 100755
--- a/product/ERP5/Document/DeliveryCell.py
+++ b/product/ERP5/Document/DeliveryCell.py
@@ -257,6 +257,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the quantity attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -270,7 +271,17 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # now verify if item can be moved (not already done)
+            last_location_title = object.getLastLocationTitle()
+            if self.getDestinationTitle() != last_location_title or last_location_title == '' :
+              # we can add this item to the list of aggregated items
+              item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -284,6 +295,8 @@ Une ligne tarifaire."""
             quantity += object_item.getQuantity()
           else :
             quantity += object_item.getRemainingQuantity()
+            # we reset the location of the item
+            object_item.setLocation('')
 
         self.setTargetQuantity(quantity)
 
@@ -305,6 +318,30 @@ Une ligne tarifaire."""
       else:
         return Movement.getInventoriatedQuantity(self)
 
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
+    def getStartDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      if self.getSimulationState() in current_inventory_state_list:
+        # When an order is delivered, the target quantity should be considered
+        # rather than the quantity
+        return Movement.getTargetStartDate(self)
+      else:
+        return Movement.getStartDate(self)
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
+    def getStopDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      if self.getSimulationState() in current_inventory_state_list:
+        # When an order is delivered, the target quantity should be considered
+        # rather than the quantity
+        return Movement.getTargetStopDate(self)
+      else:
+        return Movement.getStopDate(self)
+
     # Simulation Consistency Check
     def getRelatedQuantity(self):
       """
diff --git a/product/ERP5/Document/InventoryCell.py b/product/ERP5/Document/InventoryCell.py
index 7f6a092352..bf45af46f8 100755
--- a/product/ERP5/Document/InventoryCell.py
+++ b/product/ERP5/Document/InventoryCell.py
@@ -30,6 +30,8 @@ from Globals import InitializeClass, PersistentMapping
 from Acquisition import aq_base, aq_inner, aq_parent, aq_self
 from AccessControl import ClassSecurityInfo
 
+from Products.ERP5.ERP5Globals import current_inventory_state_list
+
 from Products.CMFCore.WorkflowCore import WorkflowAction
 from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
 
@@ -137,9 +139,9 @@ Une ligne tarifaire."""
       # Update consumption last
       if item_id_list is not None:
         self._setItemIdList(item_id_list)
-      elif produced_item_id_list is not None:
+      if produced_item_id_list is not None :
         self._setProducedItemIdList(produced_item_id_list)
-      elif consumed_item_id_list is not None:
+      if consumed_item_id_list is not None :
         self._setConsumedItemIdList(consumed_item_id_list)
 
     security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' )
@@ -180,6 +182,9 @@ Une ligne tarifaire."""
       quantity = self._baseGetQuantity()
       if quantity not in (0.0, 0, None):
         return quantity
+      # Make sure inventory is defined somewhere (here or parent)
+      if getattr(aq_base(self), 'inventory', None) is None:
+        return 0.0 # No inventory defined, so no quantity
       # Find total of movements in the past - XXX
       resource_value = self.getResourceValue()
       if resource_value is not None:
@@ -189,10 +194,11 @@ Une ligne tarifaire."""
                                     at_date = self.getStartDate(),
                                     variation_text = self.getVariationText(),
                                     node = self.getDestination(),
-                                    section = self.getDestinationSection())
+                                    section = self.getDestinationSection(),
+                                    simulation_state = current_inventory_state_list)
         inventory = self.getInventory()
-        if inventory in (None, ''):
-          return None # Do not change inventory if no inventory value provided
+        if current_inventory in (None, ''):
+          current_inventory = 0.0
         return self.getInventory() - current_inventory
       return self.getInventory()
 
@@ -216,6 +222,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the inventory attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -229,7 +236,14 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -240,7 +254,7 @@ Une ligne tarifaire."""
         quantity = 0
 
         for object_item in item_object_list :
-          quantity += object_item.getQuantity()
+          quantity += object_item.getRemainingQuantity()
 
         self.setInventory(quantity)
 
@@ -252,11 +266,27 @@ Une ligne tarifaire."""
       """
       return Movement.getInventoriatedQuantity(self)
 
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
+    def getStartDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      return Movement.getStartDate(self)
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
+    def getStopDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      return Movement.getStopDate(self)
+
     def _setProducedItemIdList(self, value):
       """
         Computes total_quantity of all given items and stores this total_quantity
         in the quantity attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -270,7 +300,17 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # now verify if item can be moved (not already done)
+            last_location_title = object.getLastLocationTitle()
+            if self.getDestinationTitle() != last_location_title or last_location_title == '' :
+              # we can add this item to the list of aggregated items
+              item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -290,6 +330,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the quantity attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -303,7 +344,17 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # now verify if item can be moved (not already done)
+            last_location_title = object.getLastLocationTitle()
+            if self.getDestinationTitle() == last_location_title or last_location_title == '' :
+              # we can add this item to the list of aggregated items
+              item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -315,6 +366,8 @@ Une ligne tarifaire."""
 
         for object_item in item_object_list :
           quantity += object_item.getRemainingQuantity()
+          # we reset the location of the item
+          object_item.setLocation('')
 
         self.setConsumptionQuantity(quantity)
 
@@ -335,3 +388,12 @@ Une ligne tarifaire."""
         return self.getItemIdList()
       else :
         return []
+
+    # Inventory cataloging
+    security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
+    def getConvertedInventory(self):
+      """
+        provides a default inventory value - None since
+        no inventory was defined.
+      """
+      return self.getInventory() # XXX quantity unit is missing
diff --git a/product/ERP5/Document/InventoryLine.py b/product/ERP5/Document/InventoryLine.py
index 9a23bde13e..89d00c131e 100755
--- a/product/ERP5/Document/InventoryLine.py
+++ b/product/ERP5/Document/InventoryLine.py
@@ -130,6 +130,23 @@ Une ligne tarifaire."""
         )
       }
 
+    def _edit(self, REQUEST=None, force_update = 0, **kw):
+      kw = kw.copy()
+      item_id_list = kw.get('item_id_list', None)
+      if item_id_list is not None: del kw['item_id_list']
+      produced_item_id_list = kw.get('produced_item_id_list', None)
+      if produced_item_id_list is not None: del kw['produced_item_id_list']
+      consumed_item_id_list = kw.get('consumed_item_id_list', None)
+      if consumed_item_id_list is not None: del kw['consumed_item_id_list']
+      DeliveryLine._edit(self, REQUEST=REQUEST, force_update = force_update, **kw)
+      # Update consumption last
+      if item_id_list is not None:
+        self._setItemIdList(item_id_list)
+      if produced_item_id_list is not None :
+        self._setProducedItemIdList(produced_item_id_list)
+      if consumed_item_id_list is not None :
+        self._setConsumedItemIdList(consumed_item_id_list)
+
     security.declareProtected(Permissions.AccessContentsInformation, 'getTotalInventory')
     def getTotalInventory(self):
       """
@@ -153,7 +170,9 @@ Une ligne tarifaire."""
         quantity = self._baseGetQuantity()
         if quantity not in (0.0, 0, None):
           return quantity
-        return self.getInventory()
+        # Make sure inventory is defined somewhere (here or parent)
+        if getattr(aq_base(self), 'inventory', None) is None:
+          return 0.0 # No inventory defined, so no quantity
         # Find total of movements in the past - XXX
         resource_value = self.getResourceValue()
         if resource_value is not None:
@@ -166,8 +185,8 @@ Une ligne tarifaire."""
                         section = self.getDestinationSection(),
                         simulation_state = current_inventory_state_list)
           inventory = self.getInventory()
-          if inventory in (None, ''):
-            return None # Do not change inventory if no inventory value provided
+          if current_inventory in (None, ''):
+            current_inventory = 0.0
           return self.getInventory() - current_inventory
         return self.getInventory()
       else:
@@ -229,6 +248,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the inventory attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -242,7 +262,14 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -262,6 +289,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the quantity attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -275,7 +303,17 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # now verify if item can be moved (not already done)
+            last_location_title = object.getLastLocationTitle()
+            if self.getDestinationTitle() != last_location_title or last_location_title == '' :
+              # we can add this item to the list of aggregated items
+              item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -295,6 +333,7 @@ Une ligne tarifaire."""
         Computes total_quantity of all given items and stores this total_quantity
         in the quantity attribute of the cell
       """
+      previous_item_list = self.getAggregateValueList()
       given_item_id_list = value
       item_object_list = []
       for item in given_item_id_list :
@@ -308,7 +347,17 @@ Une ligne tarifaire."""
           object = None
 
         if object is not None :
-          item_object_list.append(object)
+          # if item was in previous_item_list keep it
+          if object in previous_item_list :
+            # we can add this item to the list of aggregated items
+            item_object_list.append(object)
+          # if new item verify if variated_resource of item == variated_resource of movement
+          elif (self.getResource() == object.getResource()) and (self.getVariationCategoryList() == object.getVariationCategoryList()) :
+            # now verify if item can be moved (not already done)
+            last_location_title = object.getLastLocationTitle()
+            if self.getDestinationTitle() == last_location_title or last_location_title == '' :
+              # we can add this item to the list of aggregated items
+              item_object_list.append(object)
 
       # update item_id_list and build relation
       self.setAggregateValueList(item_object_list)
@@ -320,6 +369,8 @@ Une ligne tarifaire."""
 
         for object_item in item_object_list :
           quantity += object_item.getRemainingQuantity()
+          # we reset the location of the item
+          object_item.setLocation('')
 
         self.setConsumptionQuantity(quantity)
 
@@ -340,3 +391,35 @@ Une ligne tarifaire."""
         return self.getItemIdList()
       else :
         return []
+
+    # Inventory cataloging
+    security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedInventory')
+    def getConvertedInventory(self):
+      """
+        provides a default inventory value - None since
+        no inventory was defined.
+      """
+      return self.getInventory() # XXX quantity unit is missing
+
+    # Required for indexing
+    security.declareProtected(Permissions.AccessContentsInformation, 'getInventoriatedQuantity')
+    def getInventoriatedQuantity(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      return Movement.getInventoriatedQuantity(self)
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStartDate')
+    def getStartDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      return Movement.getStartDate(self)
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getStopDate')
+    def getStopDate(self):
+      """
+        Take into account efficiency in converted target quantity
+      """
+      return Movement.getStopDate(self)
+
diff --git a/product/ERP5/Document/Invoice.py b/product/ERP5/Document/Invoice.py
index 8285623b77..57d1cdf957 100755
--- a/product/ERP5/Document/Invoice.py
+++ b/product/ERP5/Document/Invoice.py
@@ -28,7 +28,7 @@
 
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
-
+from Products.CMFCore.utils import getToolByName
 from AccountingTransaction import AccountingTransaction
 
 class Invoice(AccountingTransaction):
@@ -55,6 +55,9 @@ class Invoice(AccountingTransaction):
                       , PropertySheet.Amount
                       , PropertySheet.Reference
                       , PropertySheet.PaymentCondition
+                      , PropertySheet.ValueAddedTax
+                      , PropertySheet.EcoTax
+                      , PropertySheet.CopyrightTax
                       )
 
     # CMF Factory Type Information
@@ -111,3 +114,34 @@ An order..."""
         )
       }
 
+    security.declareProtected(Permissions.AccessContentsInformation, 'getTotalPrice')
+    def getTotalPrice(self):
+      """
+        Returns the total price for this invoice
+      """
+      aggregate = self.Invoice_zGetTotal()[0]
+      return aggregate.total_price
+
+    security.declareProtected(Permissions.AccessContentsInformation, 'getTotalQuantity')
+    def getTotalQuantity(self):
+      """
+        Returns the total quantity for this invoice
+      """
+      aggregate = self.Invoice_zGetTotal()[0]
+      return aggregate.total_quantity
+    
+    security.declareProtected(Permissions.AccessContentsInformation, 'getTotalNetPrice')
+    def getTotalNetPrice(self):
+      """
+        Returns the total net price for this invoice
+      """
+      return self.Invoice_zGetTotalNetPrice()
+      
+    security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationSate')
+    def getSimulationState(self, id_only=1):
+      """
+        Returns the current state in simulation
+      """
+      portal_workflow = getToolByName(self, 'portal_workflow')
+      wf = portal_workflow.getWorkflowById('sale_invoice_transaction_workflow')
+      return wf._getWorkflowStateOf(self, id_only=id_only )
diff --git a/product/ERP5/Document/Movement.py b/product/ERP5/Document/Movement.py
index 0e07eccd9f..528c7ed74b 100755
--- a/product/ERP5/Document/Movement.py
+++ b/product/ERP5/Document/Movement.py
@@ -315,55 +315,49 @@ a service in a public administration)."""
     """
     return self.getTargetQuantity()
 
+  # Industrial price API
+  security.declareProtected(Permissions.AccessContentsInformation, 'getIndustrialPrice')
+  def getIndustrialPrice(self):
+    """
+      Calculates industrial price in context of this movement
+    """
+    resource = self.getResourceValue()
+    if resource is not None:
+      return resource.getIndustrialPrice(context=self)
+    return None
+
   # Asset price calculation
-  security.declareProtected(Permissions.AccessContentsInformation, 'getAssetPrice')
-  def getAssetPrice(self, exclude_path_list = []):
+  security.declareProtected(Permissions.AccessContentsInformation, 'getSourceTotalAssetPrice')
+  def getSourceTotalAssetPrice(self):
     """
       Returns a price which can be used to calculate stock value (asset)
     """
-    source_value = self.getSourceValue()
-    if not source_value:
-      # This is a production movement
-      return self.getIndustrialPrice()
-    if not source_value.isMemberOf('group/Coramy'):
-      # accountable price
-      return self.getPrice()
-    # This is an internal movement
-    current_asset_price = 0.0
-    current_inventory = 0.0
-    exclude_path_list.append(self.getRelativeUrl()) # Prevent infinite loops
-    for m in self.Movement_zGetPastMovementList(node_uid = self.getSourceUid(), section_uid = self.getDestinationUid(),
-                                                                                        before_date = self.getStartDate()):
-                  # NB we may want to consider instead all movements at the group level
-                  # movements should be sorted by date
-      movement = m.getObject()
-      if movement is not None and m.relative_url not in exclude_path_list:
-        # Only considere non loop movements
-        inventory = m.quantity
-        if inventory >= 0:
-          # We use asset_price inside Coramy Group
-          asset_price = movement.getAssetPrice(exclude_path_list = exclude_path_list) # ???
-          # Update price
-          previous_inventory = current_inventory
-          current_inventory += inventory
-          if current_inventory > 0:
-            # Update price with an average of incoming goods and current goods
-            current_asset_price = ( current_asset_price * previous_inventory + asset_price * inventory ) / float(current_inventory)
-          else:
-            # New price is the price of incoming goods - negative stock has no meaning for asset calculation
-            current_asset_price = asset_price
-        else:
-          # No change in asset_price - accumulate inventory
-          current_inventory += inventory
-
-    return current_asset_price
-
-  security.declareProtected(Permissions.AccessContentsInformation, 'getTotalAssetPrice')
-  def getTotalAssetPrice(self):
+    try:
+      price = self.getSourceAssetPrice()
+      if price is None:
+        return None
+      quantity = self.getQuantity()
+      if quantity is None:
+        return None
+      return quantity * price
+    except:
+      return None
+
+  security.declareProtected(Permissions.AccessContentsInformation, 'getDestinationTotalAssetPrice')
+  def getDestinationTotalAssetPrice(self):
     """
       Returns a price which can be used to calculate stock value (asset)
     """
-    return self.getAssetPrice() * self.getQuantity()
+    try:
+      price = self.getDestinationAssetPrice()
+      if price is None:
+        return None
+      quantity = self.getQuantity()
+      if quantity is None:
+        return None
+      return quantity * price
+    except:
+      return None
 
   # Causality computation
   security.declareProtected(Permissions.View, 'isConvergent')
diff --git a/product/ERP5/Document/Order.py b/product/ERP5/Document/Order.py
index 597a33bcaf..ab09d7f674 100755
--- a/product/ERP5/Document/Order.py
+++ b/product/ERP5/Document/Order.py
@@ -215,11 +215,50 @@ An order..."""
       """
         Sets the order to ordered
         (a Workflow Script is responsible of creating the delivery)
+
+        Confirm is still not creating deliveries XXX - check activities seriously to make sure
+        they are not flushed in case of error
       """
       self._createOrderRule()
+      # At confirm stage, we create deliveries for this order
+      self.activate().buildDeliveryList()
 
     confirm = WorkflowMethod(_confirm, 'confirm')
 
+    security.declareProtected(Permissions.ModifyPortalContent, 'buildDeliveryList')
+    def buildDeliveryList(self):
+      # Make sure there is exactly one applied rule
+      my_applied_rule_list = self.getCausalityRelatedValueList(portal_type='Applied Rule')
+      if len(my_applied_rule_list) != 1:
+        # Make sure we have an order rule
+        self._createOrderRule()
+      # Make sure there is exactly one applied rule
+      my_applied_rule_list = self.getCausalityRelatedValueList(portal_type='Applied Rule')
+      if len(my_applied_rule_list) != 1:
+        # XXX This is an error
+        return
+      applied_rule = my_applied_rule_list[0].getObject()
+      if applied_rule is None:
+        # XXX This is an error
+        return
+      # Make sure applied rule has been reindexed
+      applied_rule.flushActivity(invoke=1)
+      # Make sure there are no more activities on this order related to expand
+      self.flushActivity(invoke=1, method_id='expand') # Make sure expand is finished
+      # Build delivery list on applied rule
+      # Currently, we build it 'again' but we should actually only build
+      # deliveries for orphaned movements
+      if self.getPortalType() == 'Production Order' :
+        delivery_list = self.ProductionOrder_buildDeliveryList() # Coramy specific moved to portal_simulation
+      elif self.getPortalType() in ('Purchase Order', 'Sales Order') :
+        delivery_list = self.order_create_packing_list() # Coramy specific should be moved to portal_simulation
+      #self.informDeliveryList(delivery_list=delivery_list, comment=repr(delivery_list)) # XXX Not ready
+
+    def _informDeliveryList(self, delivery_list=None, comment=None):
+      pass
+
+    informDeliveryList = WorkflowMethod(_informDeliveryList, id='informDeliveryList')
+
     security.declareProtected(Permissions.ModifyPortalContent, 'cancel')
     def cancel(self):
       """
diff --git a/product/ERP5/Document/PackingList.py b/product/ERP5/Document/PackingList.py
index 5993219faa..a21dc8fd0f 100755
--- a/product/ERP5/Document/PackingList.py
+++ b/product/ERP5/Document/PackingList.py
@@ -30,6 +30,7 @@ from Globals import InitializeClass, PersistentMapping
 from AccessControl import ClassSecurityInfo
 from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
 from Products.ERP5.ERP5Globals import movement_type_list, draft_order_state
+from Products.CMFCore.utils import getToolByName
 
 from Delivery import Delivery
 
diff --git a/product/ERP5/Document/Resource.py b/product/ERP5/Document/Resource.py
index ee16b3e9cb..9481417780 100755
--- a/product/ERP5/Document/Resource.py
+++ b/product/ERP5/Document/Resource.py
@@ -406,7 +406,9 @@ a service in a public administration)."""
                                              section=section,
                                              node=node,
                                              node_category=node_category,
-                                             section_category=section_category, **kw)
+                                             section_category=section_category,
+                                             simulation_state=simulation_state,
+                                             **kw)
       return result
 
     security.declareProtected(Permissions.AccessContentsInformation, 'getMovementHistoryStat')
@@ -423,6 +425,7 @@ a service in a public administration)."""
                                              section=section,
                                              node=node,
                                              node_category=node_category,
+                                             simulation_state=simulation_state,
                                              section_category=section_category, **kw)
       return result
 
@@ -494,3 +497,23 @@ a service in a public administration)."""
       return None
 
 
+    # Industrial price API
+    security.declareProtected(Permissions.AccessContentsInformation, 'getIndustrialPrice')
+    def getIndustrialPrice(self, context=None, REQUEST=None, **kw):
+      """
+        Returns industrial price
+      """
+      context = self.asContext(context=context, REQUEST=REQUEST, **kw)
+      result = self._getIndustrialPrice(context)
+      if result is None:
+        self._updateIndustrialPrice()
+        result = self._getIndustrialPrice(context)
+      return result 
+
+    def _getIndustrialPrice(self, context):
+      # Default value is None
+      return None
+
+    def _updateIndustrialPrice(self, context):
+      # Do nothing by default
+      pass
diff --git a/product/ERP5/Document/Transformation.py b/product/ERP5/Document/Transformation.py
index 213d53b808..271c08b282 100755
--- a/product/ERP5/Document/Transformation.py
+++ b/product/ERP5/Document/Transformation.py
@@ -288,7 +288,7 @@ une gamme..."""
       for transformation in transformation_list:
         # Browse each transformed or assorted resource of the current transformation
         for transformed_resource in transformation.objectValues():
-          LOG("for transformed_resource in transformation",0,transformed_resource.getId())
+          #LOG("for transformed_resource in transformation",0,transformed_resource.getId())
           line_item_list, total_base_price, total_source_base_price, \
             total_variated_base_price, total_variated_source_base_price, duration \
             = transformed_resource.getAggregatedAmountList(REQUEST)
diff --git a/product/ERP5/Document/ZeroStockRule.py b/product/ERP5/Document/ZeroStockRule.py
index 865feb0b36..a88c7ff1ab 100755
--- a/product/ERP5/Document/ZeroStockRule.py
+++ b/product/ERP5/Document/ZeroStockRule.py
@@ -186,7 +186,7 @@ An ERP5 Rule..."""
             source = source_section = 'role/Fournisseur'
             destination_section = 'group/Coramy'
             destination = 'site/Stock_MP/Gravelines'
-          movement.edit(target_quantity = movement.getTargetQuantity() + quantity_dict[key])
+          movement._edit(target_quantity = movement.getTargetQuantity() + quantity_dict[key])
           movement._edit( target_start_date = stop_date,
                           target_stop_date = stop_date,
                           source = source,
diff --git a/product/ERP5/ERP5Globals.py b/product/ERP5/ERP5Globals.py
index 5039336632..2014125f92 100755
--- a/product/ERP5/ERP5Globals.py
+++ b/product/ERP5/ERP5Globals.py
@@ -37,7 +37,7 @@ variation_type_list = ('Variation', 'Variante Tissu', 'Variante Modele',
 
 node_type_list = ('Organisation','Person','Category','MetaNode',)
 
-invoice_type_list = ('Invoice', 'Sale Invoice', 'Sales Invoice')
+invoice_type_list = ('Invoice', 'Sale Invoice', 'Sales Invoice', 'Sale Invoice Transaction')
 
 order_type_list = ('Order', 'Project', 'Samples Order',
                    'Production Order', 'Purchase Order', 'Sale Order',
@@ -63,6 +63,7 @@ delivery_type_list = ('Delivery',
 order_or_delivery_type_list = tuple(list(order_type_list) + list(delivery_type_list))
 
 variation_base_category_list = ('coloris', 'taille', 'variante', 'morphologie')
+variation_base_category_id_list = variation_base_category_list # Temp Patch
 
 invoice_movement_type_list = (
                       'Invoice Line',
diff --git a/product/ERP5/Extensions/InventoryBrain.py b/product/ERP5/Extensions/InventoryBrain.py
index 9763d28736..b11ecabdf2 100755
--- a/product/ERP5/Extensions/InventoryBrain.py
+++ b/product/ERP5/Extensions/InventoryBrain.py
@@ -12,7 +12,7 @@
 #
 ##############################################################################
 
-from Products.ERP5.ERP5Globals import default_section_category, current_inventory_state_list, reserved_inventory_state_list
+from Products.ERP5.ERP5Globals import default_section_category, current_inventory_state_list, reserved_inventory_state_list,future_inventory_state_list
 from Products.ZSQLCatalog.zsqlbrain import ZSQLBrain
 from DateTime import DateTime
 from ZTUtils import make_query
@@ -52,7 +52,7 @@ class InventoryBrain(ZSQLBrain):
     """
       Returns current inventory
     """
-    return self.getInventory(ignore_variation=1)
+    return self.getInventory(ignore_variation=1,simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
 
   def getAvailableInventory(self):
     """
@@ -61,24 +61,15 @@ class InventoryBrain(ZSQLBrain):
     at_date=DateTime()
     current = self.getCurrentInventory()
     result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1,
-                                          from_date=at_date, omit_simulation = 1, omit_input = 1,
+                                          omit_simulation = 1, omit_input = 1,
                                           section_category = default_section_category,
-                                          simulation_state = None)
+                                          simulation_state = reserved_inventory_state_list)
     reserved_inventory = None
     if len(result) > 0:
       reserved_inventory = result[0].inventory
     if reserved_inventory is None:
       reserved_inventory = 0.0
-    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid], ignore_variation=1,
-                                          to_date=at_date, omit_simulation = 1, omit_input = 1,
-                                          section_category = default_section_category,
-                                          simulation_state = ('confirmed', 'getting_ready', 'ready'))
-    past_reserved_inventory = None
-    if len(result) > 0:
-      past_reserved_inventory = result[0].inventory
-    if past_reserved_inventory is None:
-      past_reserved_inventory = 0.0
-    return current + reserved_inventory + past_reserved_inventory
+    return current + reserved_inventory 
 
   def getQuantityUnit(self, **kw):
     try:
@@ -123,7 +114,7 @@ class InventoryListBrain(ZSQLBrain):
     """
       Returns current inventory
     """
-    return self.getInventory(ignore_variation=0)
+    return self.getInventory(ignore_variation=0, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
 
   def getAvailableInventory(self):
     """
@@ -132,28 +123,17 @@ class InventoryListBrain(ZSQLBrain):
     at_date=DateTime()
     current = self.getCurrentInventory()
     result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
-                                          from_date=at_date, omit_simulation = 1, omit_input = 1,
+                                          omit_simulation = 1, omit_input = 1,
                                           section=self.section_relative_url,
                                           node=self.node_relative_url,
                                           variation_text = self.variation_text,
-                                          simulation_state = None)
+                                          simulation_state = reserved_inventory_state_list)
     reserved_inventory = None
     if len(result) > 0:
       reserved_inventory = result[0].inventory
     if reserved_inventory is None:
       reserved_inventory = 0.0
-    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
-                                          to_date=at_date, omit_simulation = 1, omit_input = 1,
-                                          section=self.section_relative_url,
-                                          node=self.node_relative_url,
-                                          variation_text = self.variation_text,
-                                          simulation_state = ('confirmed', 'getting_ready', 'ready'))
-    past_reserved_inventory = None
-    if len(result) > 0:
-      past_reserved_inventory = result[0].inventory
-    if past_reserved_inventory is None:
-      past_reserved_inventory = 0.0
-    return current + reserved_inventory + past_reserved_inventory
+    return current + reserved_inventory 
 
   def getQuantity(self, **kw):
     result = self.Delivery_zGetTotal( resource_uid = [self.resource_uid],
@@ -201,12 +181,27 @@ class InventoryListBrain(ZSQLBrain):
                         )
       elif cname_id in ('getCurrentInventory',):
         resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
-        return '%s/Resource_movementHistoryView?%s' % (resource.absolute_url(),
+        return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
           make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index,
                      simulation_state=list(current_inventory_state_list)))
+      elif cname_id in ('getAvailableInventory',):
+          resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
+          return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
+            make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index,omit_simulation = 1, omit_input = 1,
+            simulation_state=list(reserved_inventory_state_list)))
+      elif cname_id in ('getFutureInventory','inventory', ):
+          resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
+          return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
+             make_query(variation_text=self.variation_text, 
+             selection_name=selection_name, selection_index=selection_index, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)))
+      elif cname_id in ('getInventoryAtDate',):
+          resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
+          return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
+                 make_query(variation_text=self.variation_text, to_date=self.at_date,
+                 selection_name=selection_name, selection_index=selection_index, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)))
       else:
         resource = self.portal_categories.unrestrictedTraverse(self.resource_relative_url)
-        return '%s/Resource_movementHistoryView?%s' % (resource.absolute_url(),
+        return '%s/Resource_movementHistoryView?%s&reset=1' % (resource.absolute_url(),
           make_query(variation_text=self.variation_text, selection_name=selection_name, selection_index=selection_index))
     except:
       return ''
@@ -231,13 +226,18 @@ class InventoryListBrain(ZSQLBrain):
       if portal_type == "Simulation Movement":
         order = o.getExplanationValue()
         if order is not None:
-          return "Simulated Order %s" % (order.getId())
+          return "%s %s" % ('Simulated Order', order.getId()) # Tried to use unicode but failed - ListBot must use unicode in % replacements
       else:
         LOG("Delivery Value",0,str(self.path))
         delivery = o.getExplanationValue()
         LOG("Delivery Value",0,str(delivery))
         if delivery is not None:
-          return "%s %s" % (delivery.getPortalType(), delivery.getId())
+          causality = delivery.getCausalityValue()
+          if causality is None:
+            return "%s %s" % (delivery.getPortalType(), delivery.getId())
+          else:
+            return "%s %s (%s %s)" % (delivery.getPortalType(), delivery.getId(),
+                              causality.getPortalType(), causality.getId())
     return "Unknown"
 
 class DeliveryListBrain(InventoryListBrain):
@@ -274,42 +274,22 @@ class DeliveryListBrain(InventoryListBrain):
     at_date=DateTime()
     current = self.getCurrentInventory()
     result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
-                                          from_date=at_date, omit_simulation = 1, omit_input = 1,
+                                          omit_simulation = 1, omit_input = 1,
                                           section_category = default_section_category,
                                           variation_text = self.variation_text,
-                                          simulation_state = None)
+                                          simulation_state = reserved_inventory_state_list )
     reserved_inventory = None
     if len(result) > 0:
       reserved_inventory = result[0].inventory
     if reserved_inventory is None:
       reserved_inventory = 0.0
-    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
-                                          to_date=at_date, omit_simulation = 1, omit_input = 1,
-                                          section_category = default_section_category,
-                                          variation_text = self.variation_text,
-                                          simulation_state = ('confirmed', 'getting_ready', 'ready'))
-    past_reserved_inventory = None 
-    if len(result) > 0:
-      past_reserved_inventory = result[0].inventory
-    if past_reserved_inventory is None:
-      past_reserved_inventory = 0.0
-    return current + reserved_inventory + past_reserved_inventory
+    return current + reserved_inventory 
 
-  def getAvailableInventoryAtDate(self):
+  def getInventoryAtDate(self):
     """
-      Returns available inventory at the date provided by the SQL method
+      Returns inventory at the date provided by the SQL method
     """
     at_date=self.at_date
-    current = self.getCurrentInventory()
-    result = self.Resource_zGetInventory( resource_uid = [self.resource_uid],
-                                          from_date=at_date, omit_simulation = 1, omit_input = 1,
-                                          section_category = default_section_category,
-                                          variation_text = self.variation_text,
-                                          simulation_state = None)
-    reserved_inventory = None
-    if len(result) > 0:
-      reserved_inventory = result[0].inventory
-    if reserved_inventory is None:
-      reserved_inventory = 0.0
-    return current + reserved_inventory
+    LOG("At Date",0,str(at_date))
+    return self.getInventory(at_date=at_date, ignore_variation=0, simulation_state=list(future_inventory_state_list)+list(reserved_inventory_state_list)+list(current_inventory_state_list))
 
diff --git a/product/ERP5/Interface/__init__.py b/product/ERP5/Interface/__init__.py
index 8341bd8c90..5d88c12593 100755
--- a/product/ERP5/Interface/__init__.py
+++ b/product/ERP5/Interface/__init__.py
@@ -1,4 +1,4 @@
+from Coordinate import Coordinate
 from Entity import Entity
 from Predicate import Predicate
-from Coordinate import Coordinate
 from Variated import Variated
\ No newline at end of file
diff --git a/product/ERP5/TargetSolver/SplitAndDefer.py b/product/ERP5/TargetSolver/SplitAndDefer.py
index 0edd1f1c84..e3986f0719 100755
--- a/product/ERP5/TargetSolver/SplitAndDefer.py
+++ b/product/ERP5/TargetSolver/SplitAndDefer.py
@@ -29,6 +29,7 @@
 
 from Products.ERP5.Tool.SimulationTool import registerTargetSolver
 from CopyToTarget import CopyToTarget
+from zLOG import LOG
 
 class SplitAndDefer(CopyToTarget):
   """
diff --git a/product/ERP5/Variated.py b/product/ERP5/Variated.py
index 3a50b80be7..45ea2156ad 100755
--- a/product/ERP5/Variated.py
+++ b/product/ERP5/Variated.py
@@ -67,15 +67,17 @@ class Variated(Base):
     """
     return self._getVariationCategoryList(base_category_list = base_category_list)
 
+
+
   security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList')
   def getVariationCategoryItemList(self, base_category_list = (), base=1,
-                                        method_id='getTitle', current_category=None):
+                                        method_id='getTitle', start_with_item=None):
     """
-      Returns the list of possible variation items
+      Returns the list of possible variations
     """
     variation_category_item_list = []
-    if current_category is not None:
-      variation_category_item_list.append(current_category)
+    if start_with_item is not None:
+      variation_category_item_list.append(start_with_item)
     variation_category_list = self.getVariationCategoryList(base_category_list=base_category_list)
     for variation_category in variation_category_list:
       resource = self.portal_categories.resolveCategory(variation_category)
@@ -85,7 +87,7 @@ class Variated(Base):
       else:
         index = variation_category.find('/') + 1
         label = variation_category[index:]
-      variation_category_item_list.append((value, label))
+      variation_category_item_list.append((label, label))  # We do not know if value is on left or right
     return variation_category_item_list
 
   security.declareProtected(Permissions.ModifyPortalContent, '_setVariationCategoryList')
@@ -127,7 +129,7 @@ class Variated(Base):
 
   security.declareProtected(Permissions.AccessContentsInformation,
                                     'getVariationRangeBaseCategoryItemList')
-  def getVariationRangeBaseCategoryItemList(self, base=1, method_id='getTitle', current_category=None):
+  def getVariationRangeBaseCategoryItemList(self, base=1, method_id='getTitle', start_with_item=None):
       """
         Returns possible variations of the resource
         as a list of tuples (id, title). This is mostly
@@ -188,9 +190,6 @@ class Variated(Base):
       clist = [(None,None)]
     return clist
 
-  # Missing methods
-  # getVariationBaseCategoryItemList
-
   # Help
   security.declareProtected(Permissions.AccessContentsInformation,
                                         'getMatrixVariationRangeBaseCategoryList')
diff --git a/product/ERP5/skins/erp5_accounting/sale_invoice_transaction_view.form b/product/ERP5/skins/erp5_accounting/sale_invoice_transaction_view.form
index 2d2678351e..867cd5f936 100755
--- a/product/ERP5/skins/erp5_accounting/sale_invoice_transaction_view.form
+++ b/product/ERP5/skins/erp5_accounting/sale_invoice_transaction_view.form
@@ -138,7 +138,7 @@
           <hidden type="int">0</hidden>
           <jump_method>base_jump_relation</jump_method>
           <max_length></max_length>
-          <portal_type type="list">[('Sale Packing List', 'Sale Packing List')]</portal_type>
+          <portal_type type="list">[('Sale Packing List', 'Sale Packing List'), ('Sales Packing List', 'Sales Packing List')]</portal_type>
           <required type="int">0</required>
           <title>Packing List</title>
           <truncate type="int">0</truncate>
@@ -408,4 +408,4 @@
       </fields>
     </group>
   </groups>
-</form>
\ No newline at end of file
+</form>
diff --git a/product/ERP5/skins/erp5_core/base_edit.py b/product/ERP5/skins/erp5_core/base_edit.py
index 3b853c5062..a86669445d 100755
--- a/product/ERP5/skins/erp5_core/base_edit.py
+++ b/product/ERP5/skins/erp5_core/base_edit.py
@@ -103,7 +103,10 @@ try:
       o = context.restrictedTraverse(url)
       v.update(gv)
       o.edit(**v)
-      o.flushActivity(invoke = 1) # This is required if we wish to provide immediate display
+      o.flushActivity(method_id="immediateReindexObject",
+                         invoke = 1) # This is required if we wish to provide immediate display
+      o.flushActivity(method_id="recursiveImmediateReindexObject",
+                               invoke = 1) # Requires if we want to display indexed subobject data... but long
       # However it seems it reindexed many many times... XXX
       # Maybe we should build a list of objects we need 
   # Update basic attributes
diff --git a/product/ERP5/skins/erp5_core/base_update_relation.py b/product/ERP5/skins/erp5_core/base_update_relation.py
index 6144c8024c..2e44245ba5 100755
--- a/product/ERP5/skins/erp5_core/base_update_relation.py
+++ b/product/ERP5/skins/erp5_core/base_update_relation.py
@@ -58,7 +58,7 @@ try:
         #if f.get_value('base_category') == base_category:
         k = f.id
         v = getattr(request,k,None)
-        if v in (None, '', 'None', []) and context.getProperty(k[3:]) in (None, '', 'None', []):
+        if v in (None, '', 'None', [], ()) and context.getProperty(k[3:]) in (None, '', 'None', [], ()):
           # The old value is None and the new value is not significant
           # This bug fix is probably temporary since '' means None
           pass
@@ -108,7 +108,7 @@ try:
                                 uids,
                                 object_uid)
     elif len(relation_list) > 0:
-      # If we have only one in the list, we don't want to lost our time by
+      # If we have only one in the list, we don't want to lose our time by
       # selecting it. So we directly do the update
       if len(relation_list) == 1:
           selection_index=None
diff --git a/product/ERP5/skins/erp5_core/doFavorite.py b/product/ERP5/skins/erp5_core/doFavorite.py
index b4e6de1226..7a76543a62 100755
--- a/product/ERP5/skins/erp5_core/doFavorite.py
+++ b/product/ERP5/skins/erp5_core/doFavorite.py
@@ -2,7 +2,24 @@
 
 import string
 
-doAction = favorite_select.split()
+#doAction = favorite_select.split() Previous implementation
+if favorite_select.find('local_roles=') > 0:
+  # Some local roles are defined
+  url_items = favorite_select.split('&') # split parameters
+  new_items = []
+  for item in url_items:
+    if item.find('local_roles=') >= 0:
+      local_roles = item[item.find('local_roles='):].split(';')
+      for role in local_roles:
+        role = role.split('=')
+        if len(role[len(role)-1]) > 0:
+          new_items.append("local_roles:list=%s" % role[len(role)-1])
+    else:
+      new_items.append(item)
+      
+  favorite_select = '&'.join(new_items)
+
+doAction = (favorite_select,)
 doAction0 = doAction[0]
 request = context.REQUEST
 
diff --git a/product/ERP5/skins/erp5_core/workflow_status_modify.py b/product/ERP5/skins/erp5_core/workflow_status_modify.py
index cf7586bdc1..6cc4afc21a 100755
--- a/product/ERP5/skins/erp5_core/workflow_status_modify.py
+++ b/product/ERP5/skins/erp5_core/workflow_status_modify.py
@@ -3,6 +3,7 @@
 from Products.Formulator.Errors import ValidationError, FormValidationError
 
 request=context.REQUEST
+
 try:
   # Validate the form
   form = getattr(context,dialog_id)
diff --git a/product/ERP5/skins/erp5_html_style/list_menu_box.pt b/product/ERP5/skins/erp5_html_style/list_menu_box.pt
index 02b4a56f3c..e0b0c9d0d5 100755
--- a/product/ERP5/skins/erp5_html_style/list_menu_box.pt
+++ b/product/ERP5/skins/erp5_html_style/list_menu_box.pt
@@ -56,7 +56,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
           <img src="/images/pro/images/sepacla.png" alt="|"/>&nbsp;
           <span tal:condition="print_actions">
              <a href="print"
-               tal:attributes="href python:print_actions[0]['url']">
+               tal:attributes="href python:print_actions[0]['url']
+            + '?selection_name=%s&dialog_category=%s&form_id=%s'
+            % (selection_name , 'object_print', form_id) ">
                <img src="/images/pro/images/print.png" title="Print" width="22" height="22"
                 alt="Print" border="0"/>
              </a>&nbsp;
diff --git a/product/ERP5/skins/erp5_trade/sale_invoice_transaction_view.form b/product/ERP5/skins/erp5_trade/sale_invoice_transaction_view.form
index 2b746fffea..f93e77f057 100755
--- a/product/ERP5/skins/erp5_trade/sale_invoice_transaction_view.form
+++ b/product/ERP5/skins/erp5_trade/sale_invoice_transaction_view.form
@@ -209,7 +209,7 @@
           <list_action>folder_contents</list_action>
           <list_method type="method">searchFolder</list_method>
           <meta_types type="list">[]</meta_types>
-          <portal_types type="list">[]</portal_types>
+          <portal_types type="list">[('Sale Invoice Transaction Line','Sale Invoice Transaction Line')]</portal_types>
           <report_root_list type="list">[]</report_root_list>
           <report_tree type="int">0</report_tree>
           <search type="int">0</search>
@@ -326,4 +326,4 @@
       </fields>
     </group>
   </groups>
-</form>
\ No newline at end of file
+</form>
diff --git a/product/ERP5Form/ListBox.py b/product/ERP5Form/ListBox.py
index 128bcdc7d9..7d83517830 100755
--- a/product/ERP5Form/ListBox.py
+++ b/product/ERP5Form/ListBox.py
@@ -1014,8 +1014,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
                 list_body += '<td class="Data">&nbsp;</td>'
           list_body += '</tr>'
 
-        list_html = header + selection_line + list_header + \
-               list_search + list_body + footer
+        list_html = header + selection_line + list_header + list_search + list_body + footer
 
         #Create DomainTree Selector and DomainTree box
 
diff --git a/product/ERP5Form/PDFTemplate.py b/product/ERP5Form/PDFTemplate.py
index 50c637ab9d..56a8a2d16b 100755
--- a/product/ERP5Form/PDFTemplate.py
+++ b/product/ERP5Form/PDFTemplate.py
@@ -132,6 +132,8 @@ class PDFTemplate(ZopePageTemplate):
     def __call__(self, *args, **kwargs):
       doc_xml = ZopePageTemplate.__call__(self, *args, **kwargs)
 
+      batch_mode = kwargs.get('batch_mode', 0)
+
       request = kwargs.get('REQUEST', None)
       if not request:
         request = get_request()
@@ -141,7 +143,7 @@ class PDFTemplate(ZopePageTemplate):
 
       report_tool = getToolByName(self, 'portal_report')
       pdf = report_tool.renderPDF(self.pdf_stylesheet, doc_xml, context=self.pt_getContext()['here'], *args, **kwargs)
-      if request:
+      if request and not batch_mode:
         request.RESPONSE.setHeader('Content-Type','application/pdf')
         request.RESPONSE.setHeader('Content-Length',len(pdf))
         request.RESPONSE.setHeader('Content-Disposition','inline;filename=%s.pdf' % self.id)
diff --git a/product/ERP5Form/SelectionTool.py b/product/ERP5Form/SelectionTool.py
index 6e33492444..cfc5211e78 100755
--- a/product/ERP5Form/SelectionTool.py
+++ b/product/ERP5Form/SelectionTool.py
@@ -69,6 +69,14 @@ class SelectionTool( UniqueObject, SimpleItem ):
                              , 'manage_overview' )
     manage_overview = DTMLFile( 'explainCategoryTool', _dtmldir )
 
+    security.declareProtected(ERP5Permissions.View, 'callSelectionFor')
+    def callSelectionFor(self, selection_name, context=None, REQUEST=None):
+      if context is None: context = self
+      selection = self.getSelectionFor(selection_name, REQUEST=REQUEST)
+      if selection is None:
+        return None
+      return selection(context=context)
+
     security.declareProtected(ERP5Permissions.View, 'getSelectionFor')
     def getSelectionFor(self, selection_name, REQUEST=None):
       """
diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index 830269f480..c78be828a1 100755
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -62,6 +62,7 @@ ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile
 ##############################################################################
 # Properties
 from OFS.PropertyManager import PropertyManager, type_converters
+from OFS.PropertyManager import escape
 
 class ERP5PropertyManager(PropertyManager):
 
@@ -173,6 +174,7 @@ PropertyManager.propertyValues = ERP5PropertyManager.propertyValues
 PropertyManager.propertyItems = ERP5PropertyManager.propertyItems
 PropertyManager._propertyMap = ERP5PropertyManager._propertyMap
 PropertyManager.propdict = ERP5PropertyManager.propdict
+PropertyManager.hasProperty = ERP5PropertyManager.hasProperty
 
 
 ##############################################################################
diff --git a/product/ZSQLCatalog/SQLCatalog.py b/product/ZSQLCatalog/SQLCatalog.py
index ed42cadbe4..0a0922af35 100755
--- a/product/ZSQLCatalog/SQLCatalog.py
+++ b/product/ZSQLCatalog/SQLCatalog.py
@@ -522,7 +522,7 @@ class Catalog(Persistent, Acquisition.Implicit, ExtensionClass.Base):
       else:
         kw['query'] = join(query, ' AND ')
 
-    LOG("Search Query Args:",0,str(kw))
+    #LOG("Search Query Args:",0,str(kw))
 
     # Compute "sort_index", which is a sort index, or none:
     if kw.has_key('sort-on'):
diff --git a/product/ZSQLCatalog/zsqlbrain.py b/product/ZSQLCatalog/zsqlbrain.py
index 2928b2205f..c7e0d6575b 100755
--- a/product/ZSQLCatalog/zsqlbrain.py
+++ b/product/ZSQLCatalog/zsqlbrain.py
@@ -58,7 +58,7 @@ class  ZSQLBrain(Acquisition.Implicit):
     """Try to return the object for this record"""
     try:
       obj = self.aq_parent.unrestrictedTraverse(self.getPath())
-      if not obj:
+      if obj is None:
         if REQUEST is None:
           REQUEST = self.REQUEST
         obj = self.aq_parent.portal_catalog.resolve_url(self.getPath(), REQUEST)
@@ -72,3 +72,19 @@ class  ZSQLBrain(Acquisition.Implicit):
       returns the path stored in the Catalog
     """
     return self.path
+
+  def resolve_url(self, path, REQUEST):
+      """
+        Taken from ZCatalog
+
+        Attempt to resolve a url into an object in the Zope
+        namespace. The url may be absolute or a catalog path
+        style url. If no object is found, None is returned.
+        No exceptions are raised.
+      """
+      script=REQUEST.script
+      if string.find(path, script) != 0:
+        path='%s/%s' % (script, path)
+      try: return REQUEST.resolve_url(path)
+      except: pass
+
-- 
2.30.9