diff --git a/product/ERP5/tests/testAccountingRules.py b/product/ERP5/tests/testAccountingRules.py
index 69dbc84c08ff2e6ac50fbdd2b82f527373176837..cf7fca6d8a3a23c4348292a4676a889c30356c8a 100644
--- a/product/ERP5/tests/testAccountingRules.py
+++ b/product/ERP5/tests/testAccountingRules.py
@@ -92,7 +92,7 @@ class TestAccountingRulesMixin:
   def getBusinessTemplateList(self):
     """  Return the list of business templates. """
     return ('erp5_base','erp5_pdm', 'erp5_trade', 'erp5_accounting',
-        'erp5_invoicing')
+        'erp5_invoicing', 'erp5_simplified_invoicing')
 
   def getAccountModule(self):
     return getattr(self.getPortal(), 'account',
diff --git a/product/ERP5/tests/testAdvancedInvoicing.py b/product/ERP5/tests/testAdvancedInvoicing.py
new file mode 100644
index 0000000000000000000000000000000000000000..4da645630dd329c88c24e56e76d91c146912c90e
--- /dev/null
+++ b/product/ERP5/tests/testAdvancedInvoicing.py
@@ -0,0 +1,1087 @@
+##############################################################################
+#
+# Copyright (c) 2009 Nexedi KK and Contributors. All Rights Reserved.
+#          Tatuya Kamada <tatuya@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+# USA.
+#
+##############################################################################
+"""
+  Tests invoice and invoice transaction creation from simulation.
+  Most test-cases are based on the testInvoice.py.
+"""
+
+import transaction
+from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+from Products.ERP5Type.tests.utils import FileUpload
+from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
+from Products.ERP5OOo.OOoUtils import OOoParser
+from AccessControl.SecurityManagement import newSecurityManager
+from DateTime import DateTime
+from Acquisition import aq_parent
+from zLOG import LOG
+from Products.ERP5Type.tests.Sequence import SequenceList
+from testPackingList import TestPackingListMixin
+from testAccountingRules import TestAccountingRulesMixin
+from testInvoice import TestInvoiceMixin, TestSaleInvoice, TestSaleInvoiceMixin
+
+class TestAdvancedInvoice(TestSaleInvoiceMixin, ERP5TypeTestCase):
+  """Test methods for sale and purchase invoice.
+  Subclasses must defines portal types to use.
+  """
+  quiet = 1
+  RUN_ALL_TESTS = 1
+  PACKING_LIST_DEFAULT_SEQUENCE = \
+  """
+  stepCreateEntities
+  stepCreateCurrency
+  stepCreateSaleInvoiceTransactionRule
+  stepCreateOrder
+  stepSetOrderProfile
+  stepSetOrderPriceCurrency
+  stepCreateNotVariatedResource
+  stepTic
+  stepCreateOrderLine
+  stepSetOrderLineResource
+  stepSetOrderLineDefaultValues
+  stepOrderOrder
+  stepTic
+  stepCheckDeliveryBuilding
+  stepConfirmOrder
+  stepTic
+  stepCheckOrderRule
+  stepCheckOrderSimulation
+  stepCheckDeliveryBuilding
+  stepAddPackingListContainer
+  stepAddPackingListContainerLine
+  stepSetContainerLineFullQuantity
+  stepTic
+  stepCheckPackingListIsPacked
+  """
+  
+  INVOICE_DEFAULT_SEQUENCE = PACKING_LIST_DEFAULT_SEQUENCE + \
+  """
+  stepStartPackingList
+  stepTic
+  stepStartRelatedInvoice
+  stepTic
+  """
+
+  TWO_PACKING_LIST_DEFAULT_SEQUENCE = \
+  """
+  stepCreateEntities
+  stepCreateCurrency
+  stepCreateSaleInvoiceTransactionRule
+  stepCreateOrder
+  stepSetOrderProfile
+  stepSetOrderPriceCurrency
+  stepCreateNotVariatedResource
+  stepTic
+  stepCreateOrderLine
+  stepSetOrderLineResource
+  stepSetOrderLineDefaultValues
+  stepOrderOrder
+  stepTic
+  stepCheckDeliveryBuilding
+  stepConfirmOrder
+  stepTic
+  stepCheckOrderRule
+  stepCheckOrderSimulation
+  stepCheckDeliveryBuilding
+  stepDecreasePackingListLineQuantity
+  stepCheckPackingListIsCalculating
+  stepTic
+  stepCheckPackingListIsDiverged
+  stepSplitAndDeferPackingList
+  stepTic
+  stepCheckPackingListIsSolved
+  stepCheckPackingListSplitted
+  stepAddPackingListContainer
+  stepAddPackingListContainerLine
+  stepSetContainerLineFullQuantity
+  stepTic
+  stepCheckPackingListIsPacked
+  stepDefineNewPackingListContainer
+  stepTic
+  stepCheckNewPackingListIsPacked
+  """
+
+  invoice_portal_type = 'Sale Invoice'
+  invoice_line_portal_type = 'Invoice Line'
+  invoice_cell_portal_type = 'Invoice Cell'
+  invoice_module_name = 'sale_invoice_module'
+  invoice_transaction_line_portal_type = 'Sale Invoice Transaction Line'
+  
+  def getBusinessTemplateList(self):
+    return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
+            'erp5_invoicing', 'erp5_advanced_invoicing', 'erp5_apparel')
+
+  def stepStartRelatedInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(
+      portal_type=self.invoice_portal_type)
+    self.assertNotEquals(invoice, None)
+    invoice.start()
+    self.assertEquals('started', invoice.getSimulationState())
+
+  def stepAddInvoiceTransactionLines(self, sequence=None, sequence_list=[]):
+    """
+    add some invoice and accounting lines to the invoice
+    """
+    invoice = sequence.get('invoice')
+    invoice.newContent(portal_type=self.invoice_line_portal_type,
+        resource_value=sequence.get('resource'), quantity=3, price=555)
+    invoice_transaction = invoice.getCausalityRelatedValue()
+    invoice_transaction.newContent(portal_type=self.invoice_transaction_line_portal_type,
+                                   id ='receivable', source='account_module/customer',
+                                   destination='account_module/supplier', quantity=-1665)
+    invoice_transaction.newContent(portal_type='Sale Invoice Transaction Line',
+                                   id='income', source='account_module/sale',
+                                   destination='account_module/purchase', quantity=1665)
+
+  def stepAddInvoiceLinesManyTransactions(self, sequence=None, sequence_list=[]):
+    """
+    add some invoice and accounting lines to the invoice
+    """
+    invoice = sequence.get('invoice')
+    invoice_line = invoice.newContent(portal_type='Invoice Line')
+    invoice_line.edit(resource_value=sequence.get('resource'), quantity=3,
+        price=555)
+
+    invoice_transaction = invoice.getCausalityRelatedValue()
+    transaction_line_1 = invoice_transaction.newContent(portal_type=self.invoice_transaction_line_portal_type)
+    transaction_line_2 = invoice_transaction.newContent(portal_type=self.invoice_transaction_line_portal_type)
+    transaction.commit()
+    self.tic()
+    transaction_line_1.edit(id ='receivable', source='account_module/customer',
+        destination='account_module/supplier', quantity=-1665)
+    transaction_line_2.edit(
+        id='income', source='account_module/sale',
+        destination='account_module/purchase', quantity=1665)
+
+  def stepChangeQuantityDoubledOnInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(portal_type=self.invoice_portal_type)
+    self.assertNotEquals(invoice, None)
+    invoice_line_list = invoice.getMovementList()
+    self.assertEquals(1, len(invoice_line_list))
+    invoice_line = invoice_line_list[0]
+    new_quantity = invoice_line.getQuantity() * 2
+    invoice_line.setQuantity(new_quantity)
+    sequence.edit(invoice_line_doubled_quantity=new_quantity)
+
+
+  def stepAcceptDecisionOnInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(portal_type=self.invoice_portal_type)
+    builder_list = invoice.getBuilderList()
+    self.assertEquals(2, len(builder_list))
+    divergence_list = invoice.getDivergenceList()
+    for builder in builder_list:
+      builder.solveDivergence(invoice.getRelativeUrl(),
+                              divergence_to_accept_list=divergence_list)
+
+  def stepCheckDivergenceOnInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(portal_type=self.invoice_portal_type)
+    self.assertEquals('solved', invoice.getCausalityState())
+    new_quantity = sequence.get('invoice_line_doubled_quantity')
+    self.assertEquals([], invoice.getDivergenceList())
+
+    invoice_line_list = invoice.getMovementList()
+    self.assertEquals(1, len(invoice_line_list))
+    invoice_line = invoice_line_list[0]
+    self.assertEquals(new_quantity, invoice_line.getQuantity())
+    self.assertEquals(new_quantity,
+          invoice_line.getDeliveryRelatedValue(portal_type='Simulation Movement'
+              ).getQuantity())
+
+  def stepCheckDivergedOnPackingList(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    self.assertEquals('diverged', packing_list.getCausalityState())
+
+  def stepCheckSolvedOnPackingList(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    self.assertEquals('solved', packing_list.getCausalityState())
+
+  def stepCheckDivergedQuantityOnInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(portal_type=self.invoice_portal_type)
+    self.assertTrue(invoice.isDivergent())
+    divergence_list = invoice.getDivergenceList()
+    self.assertEquals(1, len(divergence_list))
+
+    divergence = divergence_list[0]
+    self.assertEquals('quantity', divergence.tested_property)
+
+  def stepCheckDivergedQuantityOnPackingList(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    divergence_list = packing_list.getDivergenceList()
+    self.assertEquals(1, len(divergence_list))
+
+    divergence = divergence_list[0]
+    self.assertEquals('quantity', divergence.tested_property)
+
+  def stepAdoptPrevisionOnPackingList(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    divergence_list = packing_list.getDivergenceList()
+    for builder in packing_list.getBuilderList():
+      builder.solveDivergence(packing_list.getRelativeUrl(),
+                              divergence_to_adopt_list=divergence_list)
+
+  def stepAdoptPrevisionOnInvoice(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue()
+ 
+    divergence_list = invoice.getDivergenceList()
+    builder_list = invoice.getBuilderList()
+    self.assertEquals(2, len(builder_list))
+    for builder in builder_list:
+      builder.solveDivergence(invoice.getRelativeUrl(),
+                              divergence_to_adopt_list=divergence_list)
+               
+  def test_CreatingAccountingTransactionThroughInvoice(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """test creating simple invoice and accounting transaction"""
+    if not run: return
+    sequence_list = SequenceList()
+    sequence = sequence_list.addSequenceString(self.INVOICE_DEFAULT_SEQUENCE)
+    sequence_list.play(self, quiet=quiet)
+    
+    packing_list = sequence.get('packing_list')
+    self.assertEquals('solved', packing_list.getCausalityState())
+    invoice = packing_list.getCausalityRelatedValue()
+    self.assertEquals(self.invoice_portal_type, invoice.getPortalType())
+    self.assertEquals('solved', invoice.getCausalityState())
+    self.assertEquals([], invoice.getDivergenceList())
+
+    invoice_transaction  = invoice.getCausalityRelatedValue()
+    self.assertNotEquals(invoice_transaction, None)
+    self.assertEquals('draft', invoice_transaction.getCausalityState())
+    
+  def test_AcceptQuantityDivergenceOnInvoiceWithStoppedPackingList(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """Accept divergence with stopped packing list"""
+    if not run: return
+    sequence_list = SequenceList()
+    sequence = sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepTic
+      stepSetReadyPackingList
+      stepTic
+      stepStartPackingList
+      stepStopPackingList
+      stepTic
+      stepChangeQuantityDoubledOnInvoice
+      stepTic
+      stepCheckDivergedQuantityOnInvoice
+      stepAcceptDecisionOnInvoice
+      stepTic
+      stepCheckDivergenceOnInvoice
+      stepCheckSolvedOnPackingList
+      """)
+
+    sequence_list.play(self, quiet=quiet)
+    packing_list = sequence.get('packing_list')
+    self.assertEquals([], packing_list.getDivergenceList())
+    self.assertEquals('solved', packing_list.getCausalityState())
+ 
+  def test_AdoptQuantityDivergenceOnInvoiceLineWithStoppedPackingList(self, quiet=quiet,
+                                                                      run=RUN_ALL_TESTS):
+    """Adopt quantity with stopped packing list"""
+    if not run: return
+    sequence_list = SequenceList()
+    sequence = sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE + \
+      """
+      stepStartPackingList
+      stepStopPackingList
+      stepTic
+      stepChangeQuantityDoubledOnInvoice
+      stepTic
+      stepCheckDivergedQuantityOnInvoice
+      stepAdoptPrevisionOnInvoice
+      stepTic
+      """)
+    sequence_list.play(self, quiet=quiet)
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue()
+    self.assertEquals([], invoice.getDivergenceList())
+    self.assertEquals('solved', invoice.getCausalityState())
+
+    self.assertEquals(1,
+        len(invoice.getMovementList(portal_type=self.invoice_line_portal_type)))
+    invoice_line = invoice.getMovementList(portal_type=self.invoice_line_portal_type)[0]
+    self.assertEquals(99.0, invoice_line.getQuantity())
+    self.assertEquals(555.0, invoice_line.getPrice())
+    self.assertEquals(99.0,
+          invoice_line.getDeliveryRelatedValue(portal_type='Simulation Movement'
+              ).getQuantity())
+    self.assertEquals([], packing_list.getDivergenceList())
+    self.assertEquals('solved', packing_list.getCausalityState())
+
+  def test_PackingListEditAndInvoiceRule(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Delivery Rule should not be applied on packing list lines created\
+    from Order.
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Packing List Edit')
+    sequence_list = SequenceList()
+    sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepEditPackingList
+      stepCheckDeliveryRuleNotAppliedOnPackingListEdit
+      stepCheckInvoicesConsistency
+      """)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_InvoiceViewAsODT(self):
+    """Create ODT printout """
+    resource = self.portal.getDefaultModule(
+        self.resource_portal_type).newContent(
+                    portal_type=self.resource_portal_type,
+                    title='Resource',)
+    client = self.portal.organisation_module.newContent(
+                              portal_type='Organisation', title='Client')
+    vendor = self.portal.organisation_module.newContent(
+                              portal_type='Organisation', title='Vendor')
+    invoice = self.portal.getDefaultModule(self.invoice_portal_type).newContent(
+                              portal_type=self.invoice_portal_type,
+                              start_date=DateTime(2008, 12, 31),
+                              title='Invoice',
+                              source_value=vendor,
+                              source_section_value=vendor,
+                              destination_value=client,
+                              destination_section_value=client)
+    line = invoice.newContent(portal_type=self.invoice_line_portal_type,
+                            resource_value=resource,
+                            quantity=10,
+                            price=3)
+    invoice.confirm()
+    transaction.commit()
+    self.tic()
+
+    odt = invoice.Invoice_viewAsODT()
+    from Products.ERP5OOo.tests.utils import Validator
+    odf_validator = Validator()
+    err_list = odf_validator.validate(odt)
+    if err_list:
+      self.fail(''.join(err_list))
+
+
+class TestAdvancedSaleInvoice(TestAdvancedInvoice):
+  quiet = 1
+  RUN_ALL_TESTS = 1
+  login = TestAdvancedInvoice.login
+  
+  def stepCheckInvoicesAndTransactionsConsistency(self, sequence=None, sequence_list=None,
+                                                  **kw):
+    """
+    - to check transaction lines match invoice lines
+    """
+    invoice_list = self.getPortal()[self.invoice_module_name].objectValues()
+    for invoice in invoice_list:
+      state_list = \
+          list(self.getPortal().getPortalCurrentInventoryStateList())
+      state_list.append('cancelled')
+      if invoice.getSimulationState() in state_list:
+        invoice_line_list = invoice.contentValues(
+            portal_type=self.invoice_line_portal_type)
+        expected_price = 0.0
+        for line in invoice_line_list:
+          expected_price += line.getTotalPrice()
+        invoice_transaction  = invoice.getCausalityRelatedValue()
+        if invoice_transaction.getSimulationState() in state_list:
+          invoice_transaction_line_list = invoice_transaction.contentValues(
+            portal_type=self.invoice_transaction_line_portal_type)
+          self.assertEquals(3, len(invoice_transaction_line_list))
+          
+          for line_id, line_source, line_dest, line_ratio in \
+                  self.transaction_line_definition_list:
+            for line in invoice_transaction.contentValues(
+                portal_type=self.invoice_transaction_line_portal_type):
+              if line.getSource() == 'account_module/%s' % line_source and \
+                     line.getDestination() == 'account_module/%s' % line_dest:
+                break
+              else:
+                self.fail('No line found that matches %s' % line_id)
+              resource_precision = line.getResourceValue().getQuantityPrecision()
+              self.assertEquals(round(line.getQuantity(), resource_precision),
+                                round(expected_price * line_ratio, resource_precision))
+
+  def stepRemoveDateMovementGroupForAdvancedTransactionBuilder(self, sequence=None, sequence_list=None, **kw):
+    """
+    Remove DateMovementGroup
+    """
+    portal = self.getPortal()
+    builder = portal.portal_deliveries.advanced_sale_invoice_transaction_builder
+    delivery_movement_group_list = builder.getDeliveryMovementGroupList()
+    uf = self.getPortal().acl_users
+    uf._doAddUser('admin', '', ['Manager'], [])
+    user = uf.getUserById('admin').__of__(uf)
+    newSecurityManager(None, user)
+    for movement_group in delivery_movement_group_list:
+      if movement_group.getPortalType() == 'Property Movement Group':
+        # it contains 'start_date' and 'stop_date' only, so we remove
+        # movement group itself.
+        builder.deleteContent(movement_group.getId())
+        builder.newContent(
+          portal_type = 'Parent Explanation Movement Group',
+          collect_order_group='delivery',
+          int_index=len(delivery_movement_group_list)+1
+          )
+        user = uf.getUserById('test_invoice_user').__of__(uf)
+        newSecurityManager(None, user)
+                                                                            
+  def test_01_TwoInvoicesFromTwoPackingList(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    This test was created for the following bug:
+        - an order is created and confirmed
+        - the packing list is split
+        - the 2 packing list are delivered (at different date)
+        - 2 invoices are built, then we set the same date on both of them
+        - the accounting rules are generated and put in only one invoice !!,
+          so we have an invoice with twice the number of accounting rules
+          and an invoice with no accounting rules. both invoices are wrong
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Two Invoices from Two Packing List')
+    sequence_list = SequenceList()
+    sequence_list.addSequenceString(
+      self.TWO_PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepSetReadyPackingList
+      stepSetReadyNewPackingList
+      stepTic
+      stepStartPackingList
+      stepStartNewPackingList
+      stepTic
+      stepCheckTwoInvoices
+      stepRemoveDateMovementGroupForAdvancedTransactionBuilder
+      stepStartTwoInvoices
+      stepTic
+      stepCheckInvoicesAndTransactionsConsistency
+      """)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_02_InvoiceDeletePackingListLine(self, quiet=quiet,
+      run=RUN_ALL_TESTS):
+    """
+    Checks that deleting a Packing List Line still creates a correct
+    Invoice
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Packing List Line Delete')
+    sequence_list = SequenceList()
+    for base_sequence in (self.PACKING_LIST_TWO_LINES_DEFAULT_SEQUENCE, ) :
+      sequence_list.addSequenceString(
+        base_sequence +
+    """
+    stepDeletePackingListLine
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepTic
+    stepCheckInvoiceBuilding
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_03_InvoiceDecreaseQuantity(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Change the quantity of a Invoice Line,
+    check that the invoice is divergent,
+    then split and defer, and check everything is solved
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Invoice Decrease Qantity')
+    sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+    """
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+
+    stepDecreaseInvoiceLineQuantity
+    stepCheckInvoiceIsDivergent
+    stepCheckInvoiceIsCalculating
+    stepTic
+    stepCheckInvoiceIsDiverged
+    stepSplitAndDeferInvoice
+    stepTic
+
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+    stepCheckInvoiceSplitted
+
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """
+    self.playSequence(sequence, quiet=quiet)
+
+  def test_04_InvoiceChangeStartDateFail(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Change the start_date of a Invoice Line,
+    check that the invoice is divergent,
+    then accept decision, and check Packing list is divergent
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Invoice Change Sart Date')
+    sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+    """
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+
+    stepChangeInvoiceStartDate
+    stepCheckInvoiceIsDivergent
+    stepCheckInvoiceIsCalculating
+    stepTic
+    stepCheckInvoiceIsDiverged
+    stepUnifyStartDateWithDecisionInvoice
+    stepTic
+
+    stepCheckInvoiceNotSplitted
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+
+    stepCheckPackingListIsDivergent
+    """
+    self.playSequence(sequence, quiet=quiet)
+
+  def test_05_AcceptDecisionOnPackingList(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    - Increase or Decrease the quantity of a Packing List line
+    - Accept Decision on Packing List
+    - Packing List must not be divergent and use new quantity
+    - Invoice must not be divergent and use new quantity
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('InvoiceAcceptDecisionOnPackingList')
+    end_sequence = \
+    """
+    stepSetContainerFullQuantity
+    stepCheckPackingListIsCalculating
+    stepTic
+    stepCheckPackingListIsDiverged
+    stepAcceptDecisionQuantity
+    stepTic
+    stepCheckPackingListIsSolved
+    stepCheckPackingListNotSplitted
+
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+
+    stepStopPackingList
+    stepTic
+    stepDeliverPackingList
+    stepTic
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+
+    stepStartInvoice
+    stepTic
+    stepStopInvoice
+    stepTic
+    stepDeliverInvoice
+    stepTic
+    stepCheckInvoiceNotSplitted
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """
+
+    mid_sequence_list = ["""
+    stepCheckInvoicingRule
+    stepDecreasePackingListLineQuantity
+    """, """
+    stepCheckInvoicingRule
+    stepIncreasePackingListLineQuantity
+    """]
+
+    sequence_list = SequenceList()
+    for seq in mid_sequence_list:
+      sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+          seq + end_sequence
+      sequence_list.addSequenceString(sequence)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_06_AcceptDecisionOnPackingListAndInvoice(self, quiet=quiet,
+      run=RUN_ALL_TESTS):
+    """
+    - Increase or Decrease the quantity of a Packing List line
+    - Accept Decision on Packing List
+    - Packing List must not be divergent and use new quantity
+    - Put old quantity on Invoice
+    - Accept Decision on Invoice
+    - Packing List must not be divergent and use new quantity
+    - Invoice must not be divergent and use old quantity
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('InvoiceAcceptDecisionOnPackingListAndInvoice')
+    mid_sequence = \
+    """
+    stepSetContainerFullQuantity
+    stepCheckPackingListIsCalculating
+    stepTic
+    stepCheckPackingListIsDiverged
+    stepAcceptDecisionQuantity
+    stepTic
+    stepCheckPackingListIsSolved
+    stepCheckPackingListNotSplitted
+
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+
+    stepStopPackingList
+    stepTic
+    stepDeliverPackingList
+    stepTic
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+    """
+    end_sequence = \
+    """
+    stepCheckInvoiceIsDiverged
+    stepAcceptDecisionQuantityInvoice
+    stepTic
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+    stepStartInvoice
+    stepTic
+    stepStopInvoice
+    stepTic
+    stepDeliverInvoice
+    stepTic
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+    stepCheckInvoiceNotSplitted
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """
+
+    mid_sequence_list = [("""
+    stepCheckInvoicingRule
+    stepDecreasePackingListLineQuantity
+    """, """
+    stepIncreaseInvoiceLineQuantity
+    stepTic
+    """), ("""
+    stepCheckInvoicingRule
+    stepIncreasePackingListLineQuantity
+    """, """
+    stepDecreaseInvoiceLineQuantity
+    stepTic
+    """)]
+
+    sequence_list = SequenceList()
+    for seq1, seq2 in mid_sequence_list:
+      sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+          seq1 + mid_sequence + seq2 + end_sequence
+      sequence_list.addSequenceString(sequence)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_07_SplitAndDeferInvoice(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    - Accept Order, Accept Packing List
+    - Decrease quantity on Invoice
+    - Split and defer Invoice
+    - Accept Invoice
+    - Accept splitted Invoice
+    - Packing List must not be divergent and use old quantity
+    - Invoice must not be divergent and use new quantity
+    - splitted Invoice must not be divergent and use old - new quantity
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('InvoiceSplitAndDeferInvoice')
+    sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+    """
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+    stepStopPackingList
+    stepTic
+    stepDeliverPackingList
+    stepTic
+    stepCheckPackingListIsSolved
+    stepCheckPackingListNotSplitted
+
+    stepDecreaseInvoiceLineQuantity
+    stepCheckInvoiceIsDivergent
+    stepCheckInvoiceIsCalculating
+    stepTic
+    stepCheckInvoiceIsDiverged
+    stepSplitAndDeferInvoice
+    stepTic
+    stepStartInvoice
+    stepTic
+    stepStopInvoice
+    stepTic
+    stepDeliverInvoice
+    stepTic
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+    stepCheckInvoiceSplitted
+   
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+
+    stepSwitchInvoices
+
+    stepStartInvoice
+    stepTic
+    stepStopInvoice
+    stepTic
+    stepDeliverInvoice
+    stepTic
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """
+    self.playSequence(sequence, quiet=quiet)
+
+  def test_08_AcceptDecisionOnInvoice(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    - Accept Order, Accept Packing List
+    - Increase or Decrease quantity on Invoice
+    - Accept Decision on Invoice
+    - Accept Invoice
+    - Packing List must not be divergent and use old quantity
+    - Invoice must not be divergent and use new quantity
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('InvoiceAcceptDecisionOnInvoice')
+    mid_sequence = \
+    """
+    stepSetReadyPackingList
+    stepTic
+    stepStartPackingList
+    stepCheckInvoicingRule
+    stepCheckInvoiceTransactionRule
+    stepTic
+    stepCheckInvoiceBuilding
+    stepStopPackingList
+    stepTic
+    stepDeliverPackingList
+    stepTic
+    stepCheckPackingListIsSolved
+    stepCheckPackingListNotSplitted
+    """
+    end_sequence = \
+    """
+    stepCheckInvoiceIsDivergent
+    stepCheckInvoiceIsCalculating
+    stepTic
+    stepCheckInvoiceIsDiverged
+    stepAcceptDecisionQuantityInvoice
+    stepTic
+    stepStartInvoice
+    stepTic
+    stepStopInvoice
+    stepTic
+    stepDeliverInvoice
+    stepTic
+
+    stepCheckPackingListIsNotDivergent
+    stepCheckPackingListIsSolved
+    stepCheckInvoiceTransactionRule
+
+    stepCheckInvoiceNotSplitted
+    stepCheckInvoiceIsNotDivergent
+    stepCheckInvoiceIsSolved
+
+    stepRebuildAndCheckNothingIsCreated
+    stepCheckInvoicesConsistency
+    """
+
+    mid_sequence_list = ["""
+    stepDecreaseInvoiceLineQuantity
+    """, """
+    stepIncreaseInvoiceLineQuantity
+    """]
+
+    sequence_list = SequenceList()
+    for seq in mid_sequence_list:
+      sequence = self.PACKING_LIST_DEFAULT_SEQUENCE + \
+          mid_sequence + seq + end_sequence
+      sequence_list.addSequenceString(sequence)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_09_Reference(self, quiet=quiet, run=RUN_ALL_TESTS):
+    if not run: return
+    if not quiet:
+      self.logMessage('test Reference')
+
+    # A reference is set automatically on Sale Invoice Transaction
+    supplier = self.portal.organisation_module.newContent(
+                            portal_type='Organisation',
+                            title='Supplier')
+    client = self.portal.organisation_module.newContent(
+                            portal_type='Organisation',
+                            title='Client')
+    currency = self.portal.currency_module.newContent(
+                            portal_type='Currency')
+    invoice = self.portal.accounting_module.newContent(
+                    portal_type='Sale Invoice Transaction',
+                    start_date=DateTime(),
+                    price_currency_value=currency,
+                    resource_value=currency,
+                    source_section_value=supplier,
+                    destination_section_value=client)
+    self.portal.portal_workflow.doActionFor(invoice, 'confirm_action')
+
+    # We could generate a better reference here.
+    self.assertEquals('1', invoice.getReference())
+
+  def test_10_ManuallyAddedMovements(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Checks that adding invoice lines and accounting lines to one invoice
+    generates correct simulation
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Invoice with Manually Added Movements')
+    sequence_list = SequenceList()
+    sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+          """
+          stepSetReadyPackingList
+          stepTic
+          stepStartPackingList
+          stepCheckInvoicingRule
+          stepTic
+          stepCheckInvoiceBuilding
+          stepRebuildAndCheckNothingIsCreated
+          stepCheckInvoicesConsistency
+          stepStartInvoice
+          stepTic
+          stepAddInvoiceTransactionLines
+          stepTic
+          stepCheckSimulationTrees
+          """)
+    sequence_list.play(self, quiet=quiet)
+
+
+  def test_11_ManuallyAddedMovementsManyTransactions(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Checks that adding invoice lines and accounting lines
+    generates correct simulation
+
+    In this case checks what is happening, where movements are added in
+    one transaction and edited in another
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Invoice with Manually Added Movements in separate transactions')
+    sequence_list = SequenceList()
+    sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepSetReadyPackingList
+      stepTic
+      stepStartPackingList
+      stepCheckInvoicingRule
+      stepTic
+      stepCheckInvoiceBuilding
+      stepRebuildAndCheckNothingIsCreated
+      stepCheckInvoicesConsistency
+      stepTic
+      stepCheckInvoiceIsSolved
+      stepStartInvoice
+      stepTic
+      stepAddInvoiceLinesManyTransactions
+      stepTic
+      stepCheckSimulationTrees
+      """)
+    sequence_list.play(self, quiet=quiet)
+
+  def test_12_compareInvoiceAndPackingList(self, quiet=quiet, run=RUN_ALL_TESTS):
+    """
+    Checks that a Simple Invoice is created from a Packing List
+    """
+    if not run: return
+    if not quiet:
+      self.logMessage('Compare Simple Invoice and Packing List')
+    sequence_list = SequenceList()
+    sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepSetReadyPackingList
+      stepTic
+      stepStartPackingList
+      stepCheckInvoicingRule
+      stepTic
+      stepCheckInvoiceBuilding
+      stepCheckInvoicesConsistency
+      stepCheckPackingListInvoice
+      """)
+    sequence_list.play(self, quiet=quiet)
+
+
+  def test_13_acceptQuantityDivergenceOnInvoiceWithStartedPackingList(
+    self, quiet=quiet, run=RUN_ALL_TESTS):
+    if not run: return
+    if not quiet:
+      self.logMessage('Accept Quantity Divergence on Invoice')
+
+    sequence_list = SequenceList()
+    sequence = sequence_list.addSequenceString(
+      self.PACKING_LIST_DEFAULT_SEQUENCE +
+      """
+      stepSetReadyPackingList
+      stepTic
+      stepStartPackingList
+      stepTic
+      stepChangeQuantityDoubledOnInvoice
+      stepTic
+      stepCheckDivergedQuantityOnInvoice
+      stepAcceptDecisionOnInvoice
+      stepTic
+      stepCheckDivergenceOnInvoice
+      stepCheckDivergedOnPackingList
+      stepCheckDivergedQuantityOnPackingList
+      stepAdoptPrevisionOnPackingList
+      stepTic
+      """)
+    
+    sequence_list.play(self, quiet=quiet)
+    packing_list = sequence.get('packing_list')
+    invoice = packing_list.getCausalityRelatedValue(portal_type=self.invoice_portal_type)
+    self.assertEquals('solved', packing_list.getCausalityState())
+    self.assertEquals('solved', invoice.getCausalityState())
+
+class TestAdvancedPurchaseInvoice(TestAdvancedInvoice):
+  """Tests for purchase invoice.
+  """
+  resource_portal_type = 'Product'
+  order_portal_type = 'Purchase Order'
+  order_line_portal_type = 'Purchase Order Line'
+  order_cell_portal_type = 'Purchase Order Cell'
+  packing_list_portal_type = 'Purchase Packing List'
+  packing_list_line_portal_type = 'Purchase Packing List Line'
+  packing_list_cell_portal_type = 'Purchase Packing List Cell'
+  invoice_portal_type = 'Purchase Invoice'
+  invoice_transaction_line_portal_type = 'Purchase Invoice Transaction Line'
+  invoice_line_portal_type = 'Invoice Line'
+  invoice_cell_portal_type = 'Invoice Cell'
+  invoice_module_name = 'sale_invoice_module'
+
+  login = TestAdvancedInvoice.login
+  
+  PACKING_LIST_DEFAULT_SEQUENCE = \
+  """
+  stepCreateEntities
+  stepCreateCurrency
+  stepCreateSaleInvoiceTransactionRule
+  stepCreateOrder
+  stepSetOrderProfile
+  stepSetOrderPriceCurrency
+  stepCreateNotVariatedResource
+  stepTic
+  stepCreateOrderLine
+  stepSetOrderLineResource
+  stepSetOrderLineDefaultValues
+  stepOrderOrder
+  stepTic
+  stepCheckDeliveryBuilding
+  stepConfirmOrder
+  stepTic
+  stepCheckOrderRule
+  stepCheckOrderSimulation
+  stepCheckDeliveryBuilding
+  stepTic
+  """
+
+  INVOICE_DEFAULT_SEQUENCE = PACKING_LIST_DEFAULT_SEQUENCE + \
+  """
+  stepReceivePackingList
+  stepTic
+  stepStartRelatedInvoice
+  stepTic
+  """
+
+  def stepReceivePackingList(self, sequence=None, sequence_list=None, **kw):
+    packing_list = sequence.get('packing_list')
+    packing_list.setReady()
+    packing_list.start()
+    packing_list.stop()
+    self.assertEquals('stopped', packing_list.getSimulationState())
+    transaction.commit()
+
+import unittest
+def test_suite():
+  suite = unittest.TestSuite()
+  suite.addTest(unittest.makeSuite(TestAdvancedSaleInvoice))
+  suite.addTest(unittest.makeSuite(TestAdvancedPurchaseInvoice))
+  return suite
diff --git a/product/ERP5/tests/testBPMCore.py b/product/ERP5/tests/testBPMCore.py
index 75be32ea5f143e8141628aeea39c8fc5c5284598..02f0628aa870677298fa23bb7fdff1952f71ec79 100644
--- a/product/ERP5/tests/testBPMCore.py
+++ b/product/ERP5/tests/testBPMCore.py
@@ -47,7 +47,7 @@ class TestBPMMixin(ERP5TypeTestCase):
 
   def getBusinessTemplateList(self):
     return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
-      'erp5_invoicing', 'erp5_mrp', 'erp5_bpm')
+      'erp5_invoicing', 'erp5_simplified_invoicing', 'erp5_mrp', 'erp5_bpm')
 
   default_discount_ratio = -0.05 # -5%
   default_tax_ratio = 0.196 # 19,6%
diff --git a/product/ERP5/tests/testConversionInSimulation.py b/product/ERP5/tests/testConversionInSimulation.py
index 5edb12f2657c55616607ef12a3dd6eb9ece20959..058ed71b5440958a51ac453f3e133f197ee155e2 100644
--- a/product/ERP5/tests/testConversionInSimulation.py
+++ b/product/ERP5/tests/testConversionInSimulation.py
@@ -181,7 +181,8 @@ class TestConversionInSimulation(AccountingTestCase,ERP5TypeTestCase):
 	     'erp5_trade',
             'erp5_accounting',
 	    'erp5_accounting_ui_test',
-	    'erp5_invoicing'
+	    'erp5_invoicing',
+            'erp5_simplified_invoicing'
             )
   def createInvoiceTransactionRule(self, resource=None):
     return UnrestrictedMethod(
diff --git a/product/ERP5/tests/testERP5Budget.py b/product/ERP5/tests/testERP5Budget.py
index c1a74529f806717c6e569f551485ec8bbc7da5c7..795f2fd1ca80626d5e681f5dca748ac41ca4fbd2 100644
--- a/product/ERP5/tests/testERP5Budget.py
+++ b/product/ERP5/tests/testERP5Budget.py
@@ -59,7 +59,7 @@ class TestBudget(ERP5TypeTestCase):
       Return the list of required business templates.
     """
     return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
-            'erp5_invoicing', 'erp5_budget')
+            'erp5_invoicing', 'erp5_simplified_invoicing', 'erp5_budget')
 
   def login(self, quiet=QUIET, run=RUN_ALL_TEST):
     """
diff --git a/product/ERP5/tests/testImmobilisation.py b/product/ERP5/tests/testImmobilisation.py
index 908b7f227dea1d50cee6679464b22bcb3bbec32b..bb58f11ff0ce0dd3bd25c01a0e96513c31ba65ae 100644
--- a/product/ERP5/tests/testImmobilisation.py
+++ b/product/ERP5/tests/testImmobilisation.py
@@ -82,6 +82,7 @@ class TestImmobilisationMixin(ERP5TypeTestCase):
             "erp5_pdm",# Needed by accounting
             "erp5_accounting",
             "erp5_invoicing",
+            "erp5_simplified_invoicing",
             "erp5_apparel", # In order to use items
             "erp5_immobilisation",
             )
diff --git a/product/ERP5/tests/testInvoice.py b/product/ERP5/tests/testInvoice.py
index ef5c824196c54865821de35dfb5ef2c6afe13290..0d45b39914602dcea6d55955afeb731ead4056b1 100644
--- a/product/ERP5/tests/testInvoice.py
+++ b/product/ERP5/tests/testInvoice.py
@@ -83,7 +83,7 @@ class TestInvoiceMixin(TestPackingListMixin,
 
   def getBusinessTemplateList(self):
     return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
-            'erp5_invoicing', 'erp5_apparel')
+            'erp5_invoicing', 'erp5_simplified_invoicing', 'erp5_apparel')
 
   def createCategories(self):
     """Create the categories for our test. """
diff --git a/product/ERP5/tests/testInvoiceVAT.py b/product/ERP5/tests/testInvoiceVAT.py
index de275f02fc3fa7f212af14d0c8056fe159363985..72a8edf137b56c4ba8b66bb60f5731e0383d0423 100644
--- a/product/ERP5/tests/testInvoiceVAT.py
+++ b/product/ERP5/tests/testInvoiceVAT.py
@@ -142,7 +142,7 @@ class TestInvoiceVAT(ERP5TypeTestCase):
   def getBusinessTemplateList(self):
     """ """
     return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
-            'erp5_invoicing')
+            'erp5_invoicing', 'erp5_simplified_invoicing')
   
   def _makeAccount(self, **kw):
     """Creates an Account."""
diff --git a/product/ERP5/tests/testPayroll.py b/product/ERP5/tests/testPayroll.py
index 777052e0ba8a01cd0750ed7d483b83cd40cbcf7a..d53f641da6ac66d89a06654457905a9c46f52b3b 100644
--- a/product/ERP5/tests/testPayroll.py
+++ b/product/ERP5/tests/testPayroll.py
@@ -152,7 +152,8 @@ class TestPayrollMixin(ERP5ReportTestCase, TestBPMMixin):
   def getBusinessTemplateList(self):
     """ """
     return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
-            'erp5_invoicing', 'erp5_mrp', 'erp5_bpm', 'erp5_payroll')
+            'erp5_invoicing', 'erp5_simplified_invoicing', 'erp5_mrp', 
+            'erp5_bpm', 'erp5_payroll')
 
   def createService(self):
     module = self.portal.getDefaultModule(portal_type='Service')
diff --git a/product/ERP5/tests/testTradeCondition.py b/product/ERP5/tests/testTradeCondition.py
index 1404f49e64491eadade58113d984f4fc12a86ba3..8d002b78c9c564dddb7c7efc5e73302dd6b802ff 100644
--- a/product/ERP5/tests/testTradeCondition.py
+++ b/product/ERP5/tests/testTradeCondition.py
@@ -37,7 +37,8 @@ class TradeConditionTestCase(ERP5TypeTestCase):
   """Tests for Trade Conditions and Tax
   """
   def getBusinessTemplateList(self):
-    return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting', 'erp5_invoicing')
+    return ('erp5_base', 'erp5_pdm', 'erp5_trade', 'erp5_accounting',
+            'erp5_invoicing', 'erp5_simplified_invoicing')
 
   size_category_list = ['small', 'big']
   def afterSetUp(self):