diff --git a/product/ERP5/Document/Invoice.py b/product/ERP5/Document/Invoice.py
index 2b5c15c20f91cc49f7a4ffadd608fa294bac47d7..c45d48ab8d5b10c80fb630903216ab86e880ea2f 100755
--- a/product/ERP5/Document/Invoice.py
+++ b/product/ERP5/Document/Invoice.py
@@ -30,6 +30,7 @@ from AccessControl import ClassSecurityInfo
 from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
 from Products.CMFCore.utils import getToolByName
 from Products.ERP5.Document.AccountingTransaction import AccountingTransaction
+from zLOG import LOG
 
 class Invoice(AccountingTransaction):
     # CMF Type Definition
@@ -61,60 +62,6 @@ class Invoice(AccountingTransaction):
                       , PropertySheet.Folder
                       )
 
-    # CMF Factory Type Information
-    factory_type_information = \
-      {    'id'             : portal_type
-         , 'meta_type'      : meta_type
-         , 'description'    : """\
-An order..."""
-         , 'icon'           : 'invoice_icon.gif'
-         , 'product'        : 'ERP5'
-         , 'factory'        : 'addInvoice'
-         , 'immediate_view' : 'invoice_view'
-         , 'allow_discussion'     : 1
-         , 'allowed_content_types': ('Movement', 'Order Line',
-                                      )
-         , 'filter_content_types' : 1
-         , 'global_allow'   : 1
-         , 'actions'        :
-        ( { 'id'            : 'view'
-          , 'name'          : 'View'
-          , 'category'      : 'object_view'
-          , 'action'        : 'invoice_view'
-          , 'permissions'   : (
-              Permissions.View, )
-          }
-        , { 'id'            : 'list'
-          , 'name'          : 'Object Contents'
-          , 'category'      : 'object_action'
-          , 'action'        : 'folder_contents'
-          , 'permissions'   : (
-              Permissions.View, )
-          }
-        , { 'id'            : 'print'
-          , 'name'          : 'Print'
-          , 'category'      : 'object_print'
-          , 'action'        : 'invoice_print'
-          , 'permissions'   : (
-              Permissions.View, )
-          }
-        , { 'id'            : 'metadata'
-          , 'name'          : 'Metadata'
-          , 'category'      : 'object_view'
-          , 'action'        : 'metadata_edit'
-          , 'permissions'   : (
-              Permissions.View, )
-          }
-        , { 'id'            : 'translate'
-          , 'name'          : 'Translate'
-          , 'category'      : 'object_action'
-          , 'action'        : 'translation_template_view'
-          , 'permissions'   : (
-              Permissions.TranslateContent, )
-          }
-        )
-      }
-
     security.declareProtected(Permissions.AccessContentsInformation, 'getTotalPrice')
     def getTotalPrice(self):
       """
@@ -137,3 +84,135 @@ An order..."""
         Returns the total net price for this invoice
       """
       return self.Invoice_zGetTotalNetPrice()
+
+    def buildInvoiceTransactionList(self):
+      """
+        Retrieve all invoices transaction lines into the simulation
+      """
+      reindexable_movement_list = []
+
+      parent_simulation_line_list = []
+      for o in self.contentValues(filter={'portal_type':'Invoice Line'}) :
+        parent_simulation_line_list += [x for x in o.getDeliveryRelatedValueList() \
+                                        if x.getPortalType()=='Simulation Movement']
+      invoice_transaction_rule_list = []
+      simulation_line_list = []
+      for o in parent_simulation_line_list:
+        for rule in o.objectValues():
+          invoice_transaction_rule_list.append(rule)
+          simulation_line_list += rule.objectValues()
+      LOG('buildInvoiceTransactionList simulation_line_list',0,simulation_line_list)
+      from Products.ERP5.MovementGroup import CategoryMovementGroup
+      class_list = [CategoryMovementGroup, ]
+      root_group = self.portal_simulation.collectMovement(simulation_line_list,class_list=class_list)
+
+      if root_group is not None:
+        LOG('buildInvoiceTransactionList root_group.group_list',0,root_group.group_list)
+        for category_group in root_group.group_list:
+          LOG('buildInvoiceTransactionList category_group.group_list',0,category_group.group_list)
+          # we don't want to overwrite the Invoice Lines
+          existing_invoice_line_id_list = self.contentIds(
+              filter={'portal_type':self.getPortalInvoiceMovementTypeList()})
+          # sum quantities and add lines to invoice
+          quantity = 0
+          for movement in category_group.movement_list :
+            quantity += movement.getQuantity()
+          # Guess an unused name for the new movement
+          orig_group_id = category_group.movement_list[0].getId()
+          if orig_group_id in existing_invoice_line_id_list :
+            n = 1
+            while '%s_%s' % (orig_group_id, n) in existing_invoice_line_id_list :
+              n += 1
+            group_id = '%s_%s' % (orig_group_id, n)
+          else :
+            group_id = orig_group_id
+          existing_invoice_line_id_list.append(group_id)
+
+          # add sum of movements to invoice
+          sale_invoice_transaction_line_item = getattr(self, group_id, None)
+          if sale_invoice_transaction_line_item is None :
+            self.newContent(portal_type = 'Sale Invoice Transaction Line'
+              , id = group_id
+              , source = category_group.movement_list[0].getSource()
+              , destination = category_group.movement_list[0].getDestination()
+              , quantity = quantity
+            )
+          else :
+            sale_invoice_transaction_line_item.edit(source = category_group.movement_list[0].getSource()
+              , destination = category_group.movement_list[0].getDestination()
+              , quantity = quantity
+            )
+
+          # What do we really need to update in the simulation movement ?
+          for movement in category_group.movement_list :
+            if movement.getPortalType() == 'Simulation Movement' :
+              movement._setDeliveryValue(sale_invoice_transaction_line_item)
+              reindexable_movement_list.append(movement)
+
+      # we now reindex the movements we modified
+      for movement in reindexable_movement_list :
+        movement.immediateReindexObject()
+      return self
+
+    def buildPaymentTransactionList(self):
+      """
+        Retrieve all payments transaction lines into the simulation
+
+        For this rule, we don't want to group anything : legally, we need to have every payment matching the quantity of a sale invoice.
+
+        Warning : this code is not good, it is too simple, but is here to fulfill a very specific need at the moment.
+      """
+      reindexable_movement_list = []
+      payment_transaction_list = []
+
+      parent_simulation_line_list = []
+      for o in self.contentValues(filter={'portal_type':'Sale Invoice Transaction Line'}) :
+        parent_simulation_line_list += [x for x in o.getDeliveryRelatedValueList() \
+                                        if x.getPortalType()=='Simulation Movement']
+      payment_transaction_rule_list = []
+      simulation_line_list = []
+      for o in parent_simulation_line_list:
+        for rule in o.objectValues():
+          payment_transaction_rule_list.append(rule)
+          simulation_line_list += rule.objectValues()
+      LOG('buildPaymentTransactionList simulation_line_list',0,simulation_line_list)
+
+      # create payment transaction
+      accounting_module = self.accounting
+      payment_type = 'Payment Transaction'
+      payment_id = str(accounting_module.generateNewId())
+      payment_transaction = accounting_module.newContent(portal_type = payment_type
+          , id = payment_id
+          , source = self.getSource()
+          , source_payment = self.getSourcePayment()
+          , source_section = self.getSourceSection()
+          , destination = self.getDestination()
+          , destination_payment = self.getDestinationPayment()
+          , destination_section = self.getDestinationSection()
+          )
+      LOG('buildPaymentTransactionList payment_transaction', 0, repr(( payment_transaction )))
+
+      # fill quantity in lines
+      for movement in simulation_line_list :
+      
+          quantity = movement.getQuantity()
+          movement_id = movement.getId()
+
+          payment_transaction_line = getattr(payment_transaction, movement_id, None)
+          if payment_transaction_line is None :
+            payment_transaction.newContent(portal_type = 'Accounting Transaction Line'
+              , id = movement_id
+              , quantity = quantity
+            )
+          else :
+            payment_transaction_line.setQuantity(quantity)
+
+          # What do we really need to update in the simulation movement ?
+          if movement.getPortalType() == 'Simulation Movement' :
+            movement._setDeliveryValue(payment_transaction_line)
+            reindexable_movement_list.append(movement)
+
+      # we now reindex the movements we modified
+      for movement in reindexable_movement_list :
+        movement.immediateReindexObject()
+      return self