From 768b20d8eb235fdb5d9d06d85502be74fde33d4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Nowak?= <luke@nexedi.com>
Date: Tue, 22 Dec 2009 17:59:56 +0000
Subject: [PATCH]  - move out complex test case to separate test file,
 testTradeModelLine was already big and long test

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@31422 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 .../tests/testComplexTradeModelLineUseCase.py | 684 ++++++++++++++++++
 product/ERP5/tests/testTradeModelLine.py      | 648 -----------------
 2 files changed, 684 insertions(+), 648 deletions(-)
 create mode 100644 product/ERP5/tests/testComplexTradeModelLineUseCase.py

diff --git a/product/ERP5/tests/testComplexTradeModelLineUseCase.py b/product/ERP5/tests/testComplexTradeModelLineUseCase.py
new file mode 100644
index 0000000000..d94a35610f
--- /dev/null
+++ b/product/ERP5/tests/testComplexTradeModelLineUseCase.py
@@ -0,0 +1,684 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
+#          Łukasz Nowak <luke@nexedi.com>
+#          Fabien Morin <fabien@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility 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
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+import unittest
+import transaction
+
+from Products.ERP5Type.tests.utils import createZODBPythonScript
+from Products.ERP5.tests.testTradeModelLine import TestTradeModelLineMixin
+from Products.ERP5.PropertySheet.TradeModelLine import TARGET_LEVEL_DELIVERY
+
+class TestComplexTradeModelLineUseCase(TestTradeModelLineMixin):
+  """This test provides several complex use cases which are seen in the normal
+  shop and make sure that trade model line is capable of real business scene.
+  """
+
+  def createOrder(self):
+    module = self.portal.getDefaultModule(portal_type=self.order_portal_type)
+    return module.newContent(portal_type=self.order_portal_type,
+        title=self.id())
+
+  def createTradeCondition(self):
+    module = self.portal.getDefaultModule(
+        portal_type=self.trade_condition_portal_type)
+    trade_condition = module.newContent(
+        portal_type=self.trade_condition_portal_type,
+        title=self.id())
+    return trade_condition
+
+  def getAmount(self, order, reference, return_object=False):
+    trade_condition = order.getSpecialiseValue()
+    for movement in trade_condition.getAggregatedAmountList(order):
+      if movement.getReference() == reference:
+        if return_object == True:
+          return movement
+        else:
+          return movement.getTotalPrice()
+
+  def appendBaseContributionCategory(self, document, new_category):
+    base_contribution_value_list = document.getBaseContributionValueList()
+    document.setBaseContributionValueList(
+      base_contribution_value_list+[new_category])
+
+  def beforeTearDown(self):
+    # abort any transaction
+    transaction.abort()
+    # put non finished activities into ignored state
+    activity_connection = self.portal.cmf_activity_sql_connection
+    for table in 'message', 'message_queue':
+      activity_connection.manage_test(
+          'delete from %s where processing_node=-2' % table)
+
+    def removeAll(*args):
+      for container in args:
+        container.manage_delObjects(ids=list(container.objectIds()))
+    removeAll(self.portal.sale_order_module,
+              self.portal.purchase_order_module,
+              self.portal.sale_trade_condition_module,
+              self.portal.purchase_trade_condition_module,
+              self.portal.person_module,
+              self.portal.organisation_module,
+              self.portal.service_module,
+              self.portal.product_module,
+              self.portal.currency_module,
+              self.portal.portal_categories.product_line,
+              self.portal.portal_categories.base_amount,
+              self.portal.portal_categories.trade_phase,
+              self.portal.portal_categories.use,
+              self.portal.portal_categories.quantity_unit,
+              )
+
+    self.stepTic()
+
+  def afterSetUp(self):
+    portal = self.portal
+
+    # inherited method
+    self.createCategories()
+
+    self.stepTic()
+
+    # add currency
+    jpy = portal.currency_module.newContent(title='Yen', reference='JPY', base_unit_quantity='1')
+
+    self.stepTic()
+
+    # add organisations
+    my_company = portal.organisation_module.newContent(title='My Company')
+    client_1 = portal.organisation_module.newContent(title='Client 1')
+
+    self.stepTic()
+
+    # add base amount subcategories
+    base_amount = portal.portal_categories.base_amount
+    self.total_price_of_ordered_items = base_amount.newContent(id='total_price_of_ordered_items')
+    self.discount_amount_of_non_vat_taxable = base_amount.newContent(id='discount_amount_of_non_vat_taxable')
+    self.discount_amount_of_vat_taxable = base_amount.newContent(id='discount_amount_of_vat_taxable')
+    self.vat_taxable = base_amount.newContent(id='vat_taxable')
+    self.total_price_without_vat = base_amount.newContent(id='total_price_without_vat')
+    self.total_price_of_vat_taxable = base_amount.newContent(id='total_price_of_vat_taxable')
+    self.discount_amount = base_amount.newContent(id='discount_amount')
+    self.vat_amount = base_amount.newContent(id='vat_amount')
+    self.total_price_with_vat = base_amount.newContent(id='total_price_with_vat')
+    self.poster_present_1dvd = base_amount.newContent(id='poster_present_1dvd')
+    self.poster_present_3cd = base_amount.newContent(id='poster_present_3cd')
+    self.special_discount_3cd = base_amount.newContent(id='special_discount_3cd')
+    # add product line subcategories
+    product_line = portal.portal_categories.product_line
+    audio = product_line.newContent(id='audio')
+    audio_cd = audio.newContent(id='cd')
+    video = product_line.newContent(id='video')
+    video_dvd = video.newContent(id='dvd')
+    other_product = product_line.newContent(id='other')
+    # add a quantity unit subcategory
+    self.unit = portal.portal_categories.quantity_unit.newContent(id='unit')
+
+    self.stepTic()
+
+    # create services
+    self.service_vat = portal.service_module.newContent(title='VAT')
+    self.service_discount = portal.service_module.newContent(title='VAT')
+
+    self.stepTic()
+
+    # create products
+    def addProductDocument(title, product_line_value):
+      return portal.product_module.newContent(
+        title=title,
+        product_line_value=product_line_value,
+        quantity_unit_value=self.unit,
+        base_contribution_value_list=[self.vat_taxable,
+                                      self.total_price_of_ordered_items])
+
+    self.music_album_1 = addProductDocument('Music Album 1', audio_cd)
+    self.movie_dvd_1 = addProductDocument('Movie DVD 1', video_dvd)
+    self.music_album_2 = addProductDocument('Movie Album 2', audio_cd)
+    self.candy = addProductDocument('Candy', other_product)
+    self.poster = addProductDocument('Poster', other_product)
+    self.music_album_3 = addProductDocument('Movie Album 3', audio_cd)
+    self.movie_dvd_2 = addProductDocument('Movie DVD 2', video_dvd)
+    self.music_album_4 = addProductDocument('Movie Album 4', audio_cd)
+
+    self.stepTic()
+
+    # create a trade condition and add several common trade model lines in it.
+    self.trade_condition = self.createTradeCondition()
+    self.trade_condition.edit(
+      source_section_value=my_company,
+      source_value=my_company,
+      source_decision_value=my_company,
+      destination_section_value=client_1,
+      destination_value=client_1,
+      destination_decision_value=client_1,
+      price_currency_value=jpy)
+    self.trade_condition.newContent(
+      portal_type='Trade Model Line',
+      title='Total Price Without VAT',
+      reference='TOTAL_PRICE_WITHOUT_VAT',
+      price=1,
+      quantity=None,
+      efficiency=1,
+      target_level=TARGET_LEVEL_DELIVERY,
+      create_line=True,
+      trade_phase=None,
+      base_application_value_list=[self.discount_amount_of_non_vat_taxable,
+                                   self.discount_amount_of_vat_taxable,
+                                   self.total_price_of_ordered_items],
+      base_contribution_value_list=[self.total_price_without_vat])
+    self.trade_condition.newContent(
+      portal_type='Trade Model Line',
+      title='Total Price Of VAT Taxable',
+      reference='TOTAL_PRICE_OF_VAT_TAXABLE',
+      price=1,
+      quantity=None,
+      efficiency=1,
+      target_level=TARGET_LEVEL_DELIVERY,
+      create_line=True,
+      trade_phase=None,
+      base_application_value_list=[self.discount_amount_of_vat_taxable,
+                                   self.vat_taxable],
+      base_contribution_value_list=[self.total_price_of_vat_taxable])
+    self.trade_condition.newContent(
+      portal_type='Trade Model Line',
+      title='Discount Amount',
+      reference='DISCOUNT_AMOUNT',
+      resource_value=self.service_discount,
+      price=1,
+      quantity=None,
+      efficiency=1,
+      target_level=TARGET_LEVEL_DELIVERY,
+      create_line=True,
+      trade_phase_value=portal.portal_categories.trade_phase.default.invoicing,
+      base_application_value_list=[self.discount_amount_of_vat_taxable,
+                                   self.discount_amount_of_non_vat_taxable],
+      base_contribution_value_list=[self.discount_amount])
+    self.trade_condition.newContent(
+      portal_type='Trade Model Line',
+      title='VAT Amount',
+      reference='VAT_AMOUNT',
+      resource_value=self.service_vat,
+      price=0.05,
+      quantity=None,
+      efficiency=1,
+      target_level=TARGET_LEVEL_DELIVERY,
+      create_line=True,
+      trade_phase_value=portal.portal_categories.trade_phase.default.invoicing,
+      base_application_value_list=[self.discount_amount_of_vat_taxable,
+                                   self.vat_taxable],
+      base_contribution_value_list=[self.vat_amount])
+    self.trade_condition.newContent(
+      portal_type='Trade Model Line',
+      title='Total Price With VAT',
+      reference='TOTAL_PRICE_WITH_VAT',
+      price=1,
+      quantity=None,
+      efficiency=1,
+      target_level=TARGET_LEVEL_DELIVERY,
+      create_line=True,
+      trade_phase=None,
+      base_application_value_list=[self.vat_amount,
+                                   self.total_price_without_vat],
+      base_contribution_value_list=[self.total_price_with_vat])
+
+    self.stepTic()
+
+  def test_usecase1(self):
+    """
+    Use case 1 : Buy 3 CDs or more, get 10% off them.
+
+    1 CD   5000 yen
+    1 CD   3000 yen
+    1 Candy 100 yen
+    1 CD   2400 yen
+    discount (5000+3000+2400) * 0.1 = 1040 yen
+    """
+    createZODBPythonScript(
+      self.portal.portal_skins.custom,
+      'TradeModelLine_calculate3CD10PercentDiscount',
+      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
+      """\
+total_quantity = sum([movement.getQuantity()
+                      for movement in aggregated_movement_list])
+if total_quantity >= 3:
+  return current_movement
+else:
+  return None
+""")
+    order = self.createOrder()
+    order.edit(specialise_value=self.trade_condition)
+    order.Order_applyTradeCondition(order.getSpecialiseValue())
+    order.newContent(portal_type='Trade Model Line',
+                     reference='3CD_AND_10PERCENT_DISCOUNT_OFF_THEM',
+                     resource_value=self.service_discount,
+                     price=-0.1,
+                     quantity=None,
+                     efficiency=1,
+                     target_level=TARGET_LEVEL_DELIVERY,
+                     calculation_script_id='TradeModelLine_calculate3CD10PercentDiscount',
+                     create_line=True,
+                     trade_phase=None,
+                     base_application_value_list=[self.special_discount_3cd],
+                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
+
+    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_1,
+                                    quantity=1,
+                                    price=5000)
+    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
+    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_2,
+                                    quantity=1,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_2, self.special_discount_3cd)
+    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.candy,
+                                    quantity=1,
+                                    price=100)
+
+    self.stepTic()
+
+    # check the current amount
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 8100)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 405)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 8505)
+    # add one more cd, then total is 3. the special discount will be applied.
+    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_3,
+                                    quantity=1,
+                                    price=2400)
+    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
+
+    self.stepTic()
+
+    # check again
+    self.assertEqual(self.getAmount(order, '3CD_AND_10PERCENT_DISCOUNT_OFF_THEM'),
+                     -1040)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 9460)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 473)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 9933)
+
+  def test_usecase2(self):
+    """
+    Use case 2 : Buy 3 CDs or more, get 500 yen off.
+
+    1 CD  5000 yen
+    1 CD  3000 yen
+    1 DVD 3000 yen
+    1 CD  2400 yen
+    discount 500 yen
+    """
+    createZODBPythonScript(
+      self.portal.portal_skins.custom,
+      'TradeModelLine_calculate3CD500YenDiscount',
+      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
+      """\
+total_quantity = sum([movement.getQuantity() for movement in aggregated_movement_list])
+if total_quantity >= 3:
+  current_movement.setQuantity(-500)
+  return current_movement
+else:
+  return None
+""")
+    order = self.createOrder()
+    order.edit(specialise_value=self.trade_condition)
+    order.Order_applyTradeCondition(order.getSpecialiseValue())
+    order.newContent(portal_type='Trade Model Line',
+                     reference='3CD_AND_500YEN_OFF',
+                     resource_value=self.service_discount,
+                     price=1,
+                     quantity=None,
+                     efficiency=1,
+                     target_level=TARGET_LEVEL_DELIVERY,
+                     calculation_script_id='TradeModelLine_calculate3CD500YenDiscount',
+                     create_line=True,
+                     trade_phase=None,
+                     base_application_value_list=[self.special_discount_3cd],
+                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
+
+    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_1,
+                                    quantity=1,
+                                    price=5000)
+    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
+    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_2,
+                                    quantity=1,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_2, self.special_discount_3cd)
+    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.movie_dvd_1,
+                                    quantity=1,
+                                    price=3000)
+
+    self.stepTic()
+
+    # check the current amount
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11000)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 550)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11550)
+    # add one more cd, then total is 3. the special discount will be applied.
+    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_3,
+                                    quantity=1,
+                                    price=2400)
+    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
+    # check again
+    self.assertEqual(self.getAmount(order, '3CD_AND_500YEN_OFF'), -500)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12900)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 645)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 13545)
+
+  def test_usecase3(self):
+    """
+    Use case 3 : Buy 3 CDs or more, get 10% off total.
+
+    1 CD  5000 yen
+    1 DVD 3000 yen
+    1 CD  3000 yen
+    1 CD  2400 yen
+    discount (5000+3000+3000+2400) * 0.1 = 1340 yen
+    """
+    createZODBPythonScript(
+      self.portal.portal_skins.custom,
+      'TradeModelLine_calculate3CD10PercentDiscountFromTotal',
+      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
+      '''\
+special_discount_3cd = context.portal_categories.base_amount.special_discount_3cd
+total_quantity = sum([movement.getQuantity() for movement in current_aggregated_amount_list
+                      if special_discount_3cd in movement.getBaseContributionValueList()])
+if total_quantity >= 3:
+  return current_movement
+else:
+  return None
+''')
+    order = self.createOrder()
+    order.edit(specialise_value=self.trade_condition)
+    order.Order_applyTradeCondition(order.getSpecialiseValue())
+    order.newContent(portal_type='Trade Model Line',
+                     reference='3CD_10PERCENT_OFF_FROM_TOTAL',
+                     resource_value=self.service_discount,
+                     price=-0.1,
+                     quantity=None,
+                     efficiency=1,
+                     target_level=TARGET_LEVEL_DELIVERY,
+                     calculation_script_id='TradeModelLine_calculate3CD10PercentDiscountFromTotal',
+                     create_line=True,
+                     trade_phase=None,
+                     base_application_value_list=[self.total_price_of_ordered_items],
+                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
+
+    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_1,
+                                    quantity=1,
+                                    price=5000)
+    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
+    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.movie_dvd_1,
+                                    quantity=1,
+                                    price=3000)
+    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_2,
+                                    quantity=1,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_3, self.special_discount_3cd)
+
+    self.stepTic()
+
+    # check the current amount
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11000)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 550)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11550)
+    # add one more cd, then total is 3. the special discount will be applied.
+    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_3,
+                                    quantity=1,
+                                    price=2400)
+    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
+    # check again
+    self.assertEqual(self.getAmount(order, '3CD_10PERCENT_OFF_FROM_TOTAL'),
+                     -1340)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12060)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 603)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 12663)
+
+  def test_usecase4(self):
+    """
+    Use case 4 : Buy 3 CDs or 1 DVD, get 1 poster free.
+
+    2 CD     6000 yen
+    1 DVD    3000 yen
+    1 Poster    0 yen
+    """
+    createZODBPythonScript(
+      self.portal.portal_skins.custom,
+      'TradeModelLine_calculate3CDOr1DVDForPoster',
+      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
+      '''\
+poster_present_3cd = context.portal_categories.base_amount.poster_present_3cd
+poster_present_1dvd = context.portal_categories.base_amount.poster_present_1dvd
+
+total_quantity_3cd = sum([movement.getQuantity() for movement in aggregated_movement_list
+                          if poster_present_3cd in movement.getBaseContributionValueList()])
+total_quantity_1dvd = sum([movement.getQuantity() for movement in aggregated_movement_list
+                           if poster_present_1dvd in movement.getBaseContributionValueList()])
+if (total_quantity_3cd >= 3 or total_quantity_1dvd >= 1):
+  current_movement.setQuantity(1)
+  return current_movement
+else:
+  return None
+''')
+    order = self.createOrder()
+    order.edit(specialise_value=self.trade_condition)
+    order.Order_applyTradeCondition(order.getSpecialiseValue())
+    order.newContent(portal_type='Trade Model Line',
+                     reference='3CD_OR_1DVD_GET_1_POSTER_FREE',
+                     resource_value=self.poster,
+                     price=0,
+                     quantity=None,
+                     efficiency=1,
+                     target_level=TARGET_LEVEL_DELIVERY,
+                     calculation_script_id='TradeModelLine_calculate3CDOr1DVDForPoster',
+                     create_line=True,
+                     trade_phase=None,
+                     base_application_value_list=[self.poster_present_1dvd,
+                                                  self.poster_present_3cd])
+
+    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_4,
+                                    quantity=2,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_1, self.poster_present_3cd)
+
+    self.stepTic()
+
+    # check the current amount
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 6000)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 300)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 6300)
+    self.assertEqual(self.getAmount(order, '3CD_OR_1DVD_GET_1_POSTER_FREE'),
+                     None)
+    # add 1 dvd, then 1 poster will be given.
+    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.movie_dvd_1,
+                                    quantity=1,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_2, self.poster_present_1dvd)
+
+    self.stepTic()
+    
+    # check again
+    one_free_poster_amount = self.getAmount(order,
+                                            '3CD_OR_1DVD_GET_1_POSTER_FREE',
+                                            return_object=True)
+    self.assertEqual(one_free_poster_amount.getTotalPrice(), 0)
+    self.assertEqual(one_free_poster_amount.getQuantity(), 1)
+    self.assertEqual(one_free_poster_amount.getPrice(), 0)
+    self.assertEqual(one_free_poster_amount.getResourceValue(), self.poster)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 9000)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 450)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 9450)
+
+    # even if we buy 3 CDs and 1 DVD, only one poster will be given.
+    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_3,
+                                    quantity=1,
+                                    price=2400)
+    self.appendBaseContributionCategory(order_line_3, self.poster_present_3cd)
+
+    self.stepTic()
+
+    # check again
+    one_free_poster_amount = self.getAmount(order,
+                                            '3CD_OR_1DVD_GET_1_POSTER_FREE',
+                                            return_object=True)
+    self.assertEqual(one_free_poster_amount.getTotalPrice(), 0)
+    self.assertEqual(one_free_poster_amount.getQuantity(), 1)
+    self.assertEqual(one_free_poster_amount.getPrice(), 0)
+    self.assertEqual(one_free_poster_amount.getResourceValue(), self.poster)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11400)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 570)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11970)
+
+  def test_usecase5(self):
+    """
+    Use case 5 : Buy 3 CDs or more, 1 highest priced DVD in ordered 15% off.
+
+    1 DVD    3000 yen
+    1 DVD    1000 yen
+    2 CD    10000 yen
+    1 CD     3000 yen
+    discount 3000 * 0.15 = 450 yen
+    """
+    createZODBPythonScript(
+      self.portal.portal_skins.custom,
+      'TradeModelLine_calculate3CD15PercentDiscountOf1HighestPricedDVD',
+      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
+      '''\
+total_quantity = sum([movement.getQuantity() for movement in aggregated_movement_list])
+if total_quantity >= 3:
+  price_dvd_list = []
+  product_line_dvd = context.portal_categories.product_line.video.dvd
+  for movement in current_aggregated_amount_list:
+    resource = movement.getResourceValue()
+    if resource.getProductLineValue() == product_line_dvd:
+      price_dvd_list.append((movement.getPrice(), movement))
+  if price_dvd_list:
+    price_dvd_list.sort()
+    highest_priced_dvd_movement = price_dvd_list[-1][1]
+    total_price = highest_priced_dvd_movement.getTotalPrice()
+
+    from Products.ERP5Type.Document import newTempSimulationMovement
+    causality_value_list = list(aggregated_movement_list) + [highest_priced_dvd_movement]
+    temporary_movement = newTempSimulationMovement(current_movement.getParentValue(), current_movement.getId())
+    temporary_movement.edit(title=current_movement.getProperty('title'),
+                            description=current_movement.getProperty('description'),
+                            resource=current_movement.getProperty('resource'),
+                            reference=current_movement.getProperty('reference'),
+                            int_index=current_movement.getProperty('int_index'),
+                            base_application_list=current_movement.getProperty('base_application_list'),
+                            base_contribution_list=current_movement.getProperty('base_contribution_list'),
+                            start_date=highest_priced_dvd_movement.getStartDate(),
+                            stop_date=highest_priced_dvd_movement.getStopDate(),
+                            create_line=current_movement.getProperty('is_create_line'),
+                            trade_phase_list=current_movement.getTradePhaseList(),
+                            causality_list=[movement.getRelativeUrl() for movement in causality_value_list])
+    temporary_movement.setPrice(current_movement.getProperty('price'))
+    temporary_movement.setQuantity(highest_priced_dvd_movement.getPrice())
+    return temporary_movement
+''')
+    order = self.createOrder()
+    order.edit(specialise_value=self.trade_condition)
+    order.Order_applyTradeCondition(order.getSpecialiseValue())
+    order.newContent(portal_type='Trade Model Line',
+                     reference='3CD_AND_1HIGHEST_PRICED_DVD_15PERCENT_OFF',
+                     resource_value=self.service_discount,
+                     price=-0.15,
+                     quantity=None,
+                     efficiency=1,
+                     target_level=TARGET_LEVEL_DELIVERY,
+                     calculation_script_id='TradeModelLine_calculate3CD15PercentDiscountOf1HighestPricedDVD',
+                     create_line=True,
+                     trade_phase=None,
+                     base_application_value_list=[self.special_discount_3cd],
+                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
+
+    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.movie_dvd_1,
+                                    quantity=1,
+                                    price=3000)
+    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.movie_dvd_2,
+                                    quantity=1,
+                                    price=1000)
+    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_1,
+                                    quantity=1,
+                                    price=5000)
+    self.appendBaseContributionCategory(order_line_3, self.special_discount_3cd)
+    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
+                                    resource_value=self.music_album_2,
+                                    quantity=1,
+                                    price=3000)
+    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
+
+    self.stepTic()
+
+    # check the current amount
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12000)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 600)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'),
+                     12600)
+    # add one more cd, then total is 3. the special discount will be applied.
+    order_line_3.setQuantity(2)
+
+    self.stepTic()
+
+    # check again
+    self.assertEqual(self.getAmount(order, '3CD_AND_1HIGHEST_PRICED_DVD_15PERCENT_OFF'),
+                     -450)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 16550)
+    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 827.5)
+    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 17377.5)
+class TestComplexTradeModelLineUseCaseSale(TestComplexTradeModelLineUseCase):
+  order_portal_type = 'Sale Order'
+  order_line_portal_type = 'Sale Order Line'
+  trade_condition_portal_type = 'Sale Trade Condition'
+
+
+class TestComplexTradeModelLineUseCasePurchase(TestComplexTradeModelLineUseCase):
+  order_portal_type = 'Purchase Order'
+  order_line_portal_type = 'Purchase Order Line'
+  trade_condition_portal_type = 'Purchase Trade Condition'
+
+
+def test_suite():
+  suite = unittest.TestSuite()
+  suite.addTest(unittest.makeSuite(TestComplexTradeModelLineUseCaseSale))
+  suite.addTest(unittest.makeSuite(TestComplexTradeModelLineUseCasePurchase))
+  return suite
diff --git a/product/ERP5/tests/testTradeModelLine.py b/product/ERP5/tests/testTradeModelLine.py
index 2ad1922af1..20819604fa 100644
--- a/product/ERP5/tests/testTradeModelLine.py
+++ b/product/ERP5/tests/testTradeModelLine.py
@@ -32,7 +32,6 @@ import transaction
 
 from Products.ERP5.tests.testBPMCore import TestBPMMixin
 from Products.ERP5Type.tests.Sequence import SequenceList
-from Products.ERP5Type.tests.utils import createZODBPythonScript
 from DateTime import DateTime
 from Products.CMFCore.utils import getToolByName
 from Products.ERP5.PropertySheet.TradeModelLine import (TARGET_LEVEL_MOVEMENT,
@@ -2722,639 +2721,6 @@ class TestTradeModelLine(TestTradeModelLineMixin):
     self.assertEqual(508.51000000000005, getTotalAmount(amount_list))
 
 
-class TestComplexTradeModelLineUseCase(TestTradeModelLineMixin):
-  """This test provides several complex use cases which are seen in the normal
-  shop and make sure that trade model line is capable of real business scene.
-  """
-
-  def createOrder(self):
-    module = self.portal.getDefaultModule(portal_type=self.order_portal_type)
-    return module.newContent(portal_type=self.order_portal_type,
-        title=self.id())
-
-  def createTradeCondition(self):
-    module = self.portal.getDefaultModule(
-        portal_type=self.trade_condition_portal_type)
-    trade_condition = module.newContent(
-        portal_type=self.trade_condition_portal_type,
-        title=self.id())
-    return trade_condition
-
-  def getAmount(self, order, reference, return_object=False):
-    trade_condition = order.getSpecialiseValue()
-    for movement in trade_condition.getAggregatedAmountList(order):
-      if movement.getReference() == reference:
-        if return_object == True:
-          return movement
-        else:
-          return movement.getTotalPrice()
-
-  def appendBaseContributionCategory(self, document, new_category):
-    base_contribution_value_list = document.getBaseContributionValueList()
-    document.setBaseContributionValueList(
-      base_contribution_value_list+[new_category])
-
-  def beforeTearDown(self):
-    # abort any transaction
-    transaction.abort()
-    # put non finished activities into ignored state
-    activity_connection = self.portal.cmf_activity_sql_connection
-    for table in 'message', 'message_queue':
-      activity_connection.manage_test(
-          'delete from %s where processing_node=-2' % table)
-
-    def removeAll(*args):
-      for container in args:
-        container.manage_delObjects(ids=list(container.objectIds()))
-    removeAll(self.portal.sale_order_module,
-              self.portal.purchase_order_module,
-              self.portal.sale_trade_condition_module,
-              self.portal.purchase_trade_condition_module,
-              self.portal.person_module,
-              self.portal.organisation_module,
-              self.portal.service_module,
-              self.portal.product_module,
-              self.portal.currency_module,
-              self.portal.portal_categories.product_line,
-              self.portal.portal_categories.base_amount,
-              self.portal.portal_categories.trade_phase,
-              self.portal.portal_categories.use,
-              self.portal.portal_categories.quantity_unit,
-              )
-
-    self.stepTic()
-
-  def afterSetUp(self):
-    portal = self.portal
-
-    # inherited method
-    self.createCategories()
-
-    self.stepTic()
-
-    # add currency
-    jpy = portal.currency_module.newContent(title='Yen', reference='JPY', base_unit_quantity='1')
-
-    self.stepTic()
-
-    # add organisations
-    my_company = portal.organisation_module.newContent(title='My Company')
-    client_1 = portal.organisation_module.newContent(title='Client 1')
-
-    self.stepTic()
-
-    # add base amount subcategories
-    base_amount = portal.portal_categories.base_amount
-    self.total_price_of_ordered_items = base_amount.newContent(id='total_price_of_ordered_items')
-    self.discount_amount_of_non_vat_taxable = base_amount.newContent(id='discount_amount_of_non_vat_taxable')
-    self.discount_amount_of_vat_taxable = base_amount.newContent(id='discount_amount_of_vat_taxable')
-    self.vat_taxable = base_amount.newContent(id='vat_taxable')
-    self.total_price_without_vat = base_amount.newContent(id='total_price_without_vat')
-    self.total_price_of_vat_taxable = base_amount.newContent(id='total_price_of_vat_taxable')
-    self.discount_amount = base_amount.newContent(id='discount_amount')
-    self.vat_amount = base_amount.newContent(id='vat_amount')
-    self.total_price_with_vat = base_amount.newContent(id='total_price_with_vat')
-    self.poster_present_1dvd = base_amount.newContent(id='poster_present_1dvd')
-    self.poster_present_3cd = base_amount.newContent(id='poster_present_3cd')
-    self.special_discount_3cd = base_amount.newContent(id='special_discount_3cd')
-    # add product line subcategories
-    product_line = portal.portal_categories.product_line
-    audio = product_line.newContent(id='audio')
-    audio_cd = audio.newContent(id='cd')
-    video = product_line.newContent(id='video')
-    video_dvd = video.newContent(id='dvd')
-    other_product = product_line.newContent(id='other')
-    # add a quantity unit subcategory
-    self.unit = portal.portal_categories.quantity_unit.newContent(id='unit')
-
-    self.stepTic()
-
-    # create services
-    self.service_vat = portal.service_module.newContent(title='VAT')
-    self.service_discount = portal.service_module.newContent(title='VAT')
-
-    self.stepTic()
-
-    # create products
-    def addProductDocument(title, product_line_value):
-      return portal.product_module.newContent(
-        title=title,
-        product_line_value=product_line_value,
-        quantity_unit_value=self.unit,
-        base_contribution_value_list=[self.vat_taxable,
-                                      self.total_price_of_ordered_items])
-
-    self.music_album_1 = addProductDocument('Music Album 1', audio_cd)
-    self.movie_dvd_1 = addProductDocument('Movie DVD 1', video_dvd)
-    self.music_album_2 = addProductDocument('Movie Album 2', audio_cd)
-    self.candy = addProductDocument('Candy', other_product)
-    self.poster = addProductDocument('Poster', other_product)
-    self.music_album_3 = addProductDocument('Movie Album 3', audio_cd)
-    self.movie_dvd_2 = addProductDocument('Movie DVD 2', video_dvd)
-    self.music_album_4 = addProductDocument('Movie Album 4', audio_cd)
-
-    self.stepTic()
-
-    # create a trade condition and add several common trade model lines in it.
-    self.trade_condition = self.createTradeCondition()
-    self.trade_condition.edit(
-      source_section_value=my_company,
-      source_value=my_company,
-      source_decision_value=my_company,
-      destination_section_value=client_1,
-      destination_value=client_1,
-      destination_decision_value=client_1,
-      price_currency_value=jpy)
-    self.trade_condition.newContent(
-      portal_type='Trade Model Line',
-      title='Total Price Without VAT',
-      reference='TOTAL_PRICE_WITHOUT_VAT',
-      price=1,
-      quantity=None,
-      efficiency=1,
-      target_level=TARGET_LEVEL_DELIVERY,
-      create_line=True,
-      trade_phase=None,
-      base_application_value_list=[self.discount_amount_of_non_vat_taxable,
-                                   self.discount_amount_of_vat_taxable,
-                                   self.total_price_of_ordered_items],
-      base_contribution_value_list=[self.total_price_without_vat])
-    self.trade_condition.newContent(
-      portal_type='Trade Model Line',
-      title='Total Price Of VAT Taxable',
-      reference='TOTAL_PRICE_OF_VAT_TAXABLE',
-      price=1,
-      quantity=None,
-      efficiency=1,
-      target_level=TARGET_LEVEL_DELIVERY,
-      create_line=True,
-      trade_phase=None,
-      base_application_value_list=[self.discount_amount_of_vat_taxable,
-                                   self.vat_taxable],
-      base_contribution_value_list=[self.total_price_of_vat_taxable])
-    self.trade_condition.newContent(
-      portal_type='Trade Model Line',
-      title='Discount Amount',
-      reference='DISCOUNT_AMOUNT',
-      resource_value=self.service_discount,
-      price=1,
-      quantity=None,
-      efficiency=1,
-      target_level=TARGET_LEVEL_DELIVERY,
-      create_line=True,
-      trade_phase_value=portal.portal_categories.trade_phase.default.invoicing,
-      base_application_value_list=[self.discount_amount_of_vat_taxable,
-                                   self.discount_amount_of_non_vat_taxable],
-      base_contribution_value_list=[self.discount_amount])
-    self.trade_condition.newContent(
-      portal_type='Trade Model Line',
-      title='VAT Amount',
-      reference='VAT_AMOUNT',
-      resource_value=self.service_vat,
-      price=0.05,
-      quantity=None,
-      efficiency=1,
-      target_level=TARGET_LEVEL_DELIVERY,
-      create_line=True,
-      trade_phase_value=portal.portal_categories.trade_phase.default.invoicing,
-      base_application_value_list=[self.discount_amount_of_vat_taxable,
-                                   self.vat_taxable],
-      base_contribution_value_list=[self.vat_amount])
-    self.trade_condition.newContent(
-      portal_type='Trade Model Line',
-      title='Total Price With VAT',
-      reference='TOTAL_PRICE_WITH_VAT',
-      price=1,
-      quantity=None,
-      efficiency=1,
-      target_level=TARGET_LEVEL_DELIVERY,
-      create_line=True,
-      trade_phase=None,
-      base_application_value_list=[self.vat_amount,
-                                   self.total_price_without_vat],
-      base_contribution_value_list=[self.total_price_with_vat])
-
-    self.stepTic()
-
-  def test_usecase1(self):
-    """
-    Use case 1 : Buy 3 CDs or more, get 10% off them.
-
-    1 CD   5000 yen
-    1 CD   3000 yen
-    1 Candy 100 yen
-    1 CD   2400 yen
-    discount (5000+3000+2400) * 0.1 = 1040 yen
-    """
-    createZODBPythonScript(
-      self.portal.portal_skins.custom,
-      'TradeModelLine_calculate3CD10PercentDiscount',
-      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
-      """\
-total_quantity = sum([movement.getQuantity()
-                      for movement in aggregated_movement_list])
-if total_quantity >= 3:
-  return current_movement
-else:
-  return None
-""")
-    order = self.createOrder()
-    order.edit(specialise_value=self.trade_condition)
-    order.Order_applyTradeCondition(order.getSpecialiseValue())
-    order.newContent(portal_type='Trade Model Line',
-                     reference='3CD_AND_10PERCENT_DISCOUNT_OFF_THEM',
-                     resource_value=self.service_discount,
-                     price=-0.1,
-                     quantity=None,
-                     efficiency=1,
-                     target_level=TARGET_LEVEL_DELIVERY,
-                     calculation_script_id='TradeModelLine_calculate3CD10PercentDiscount',
-                     create_line=True,
-                     trade_phase=None,
-                     base_application_value_list=[self.special_discount_3cd],
-                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
-
-    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_1,
-                                    quantity=1,
-                                    price=5000)
-    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
-    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_2,
-                                    quantity=1,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_2, self.special_discount_3cd)
-    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.candy,
-                                    quantity=1,
-                                    price=100)
-
-    self.stepTic()
-
-    # check the current amount
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 8100)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 405)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 8505)
-    # add one more cd, then total is 3. the special discount will be applied.
-    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_3,
-                                    quantity=1,
-                                    price=2400)
-    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
-
-    self.stepTic()
-
-    # check again
-    self.assertEqual(self.getAmount(order, '3CD_AND_10PERCENT_DISCOUNT_OFF_THEM'),
-                     -1040)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 9460)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 473)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 9933)
-
-  def test_usecase2(self):
-    """
-    Use case 2 : Buy 3 CDs or more, get 500 yen off.
-
-    1 CD  5000 yen
-    1 CD  3000 yen
-    1 DVD 3000 yen
-    1 CD  2400 yen
-    discount 500 yen
-    """
-    createZODBPythonScript(
-      self.portal.portal_skins.custom,
-      'TradeModelLine_calculate3CD500YenDiscount',
-      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
-      """\
-total_quantity = sum([movement.getQuantity() for movement in aggregated_movement_list])
-if total_quantity >= 3:
-  current_movement.setQuantity(-500)
-  return current_movement
-else:
-  return None
-""")
-    order = self.createOrder()
-    order.edit(specialise_value=self.trade_condition)
-    order.Order_applyTradeCondition(order.getSpecialiseValue())
-    order.newContent(portal_type='Trade Model Line',
-                     reference='3CD_AND_500YEN_OFF',
-                     resource_value=self.service_discount,
-                     price=1,
-                     quantity=None,
-                     efficiency=1,
-                     target_level=TARGET_LEVEL_DELIVERY,
-                     calculation_script_id='TradeModelLine_calculate3CD500YenDiscount',
-                     create_line=True,
-                     trade_phase=None,
-                     base_application_value_list=[self.special_discount_3cd],
-                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
-
-    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_1,
-                                    quantity=1,
-                                    price=5000)
-    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
-    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_2,
-                                    quantity=1,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_2, self.special_discount_3cd)
-    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.movie_dvd_1,
-                                    quantity=1,
-                                    price=3000)
-
-    self.stepTic()
-
-    # check the current amount
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11000)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 550)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11550)
-    # add one more cd, then total is 3. the special discount will be applied.
-    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_3,
-                                    quantity=1,
-                                    price=2400)
-    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
-    # check again
-    self.assertEqual(self.getAmount(order, '3CD_AND_500YEN_OFF'), -500)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12900)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 645)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 13545)
-
-  def test_usecase3(self):
-    """
-    Use case 3 : Buy 3 CDs or more, get 10% off total.
-
-    1 CD  5000 yen
-    1 DVD 3000 yen
-    1 CD  3000 yen
-    1 CD  2400 yen
-    discount (5000+3000+3000+2400) * 0.1 = 1340 yen
-    """
-    createZODBPythonScript(
-      self.portal.portal_skins.custom,
-      'TradeModelLine_calculate3CD10PercentDiscountFromTotal',
-      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
-      '''\
-special_discount_3cd = context.portal_categories.base_amount.special_discount_3cd
-total_quantity = sum([movement.getQuantity() for movement in current_aggregated_amount_list
-                      if special_discount_3cd in movement.getBaseContributionValueList()])
-if total_quantity >= 3:
-  return current_movement
-else:
-  return None
-''')
-    order = self.createOrder()
-    order.edit(specialise_value=self.trade_condition)
-    order.Order_applyTradeCondition(order.getSpecialiseValue())
-    order.newContent(portal_type='Trade Model Line',
-                     reference='3CD_10PERCENT_OFF_FROM_TOTAL',
-                     resource_value=self.service_discount,
-                     price=-0.1,
-                     quantity=None,
-                     efficiency=1,
-                     target_level=TARGET_LEVEL_DELIVERY,
-                     calculation_script_id='TradeModelLine_calculate3CD10PercentDiscountFromTotal',
-                     create_line=True,
-                     trade_phase=None,
-                     base_application_value_list=[self.total_price_of_ordered_items],
-                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
-
-    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_1,
-                                    quantity=1,
-                                    price=5000)
-    self.appendBaseContributionCategory(order_line_1, self.special_discount_3cd)
-    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.movie_dvd_1,
-                                    quantity=1,
-                                    price=3000)
-    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_2,
-                                    quantity=1,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_3, self.special_discount_3cd)
-
-    self.stepTic()
-
-    # check the current amount
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11000)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 550)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11550)
-    # add one more cd, then total is 3. the special discount will be applied.
-    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_3,
-                                    quantity=1,
-                                    price=2400)
-    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
-    # check again
-    self.assertEqual(self.getAmount(order, '3CD_10PERCENT_OFF_FROM_TOTAL'),
-                     -1340)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12060)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 603)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 12663)
-
-  def test_usecase4(self):
-    """
-    Use case 4 : Buy 3 CDs or 1 DVD, get 1 poster free.
-
-    2 CD     6000 yen
-    1 DVD    3000 yen
-    1 Poster    0 yen
-    """
-    createZODBPythonScript(
-      self.portal.portal_skins.custom,
-      'TradeModelLine_calculate3CDOr1DVDForPoster',
-      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
-      '''\
-poster_present_3cd = context.portal_categories.base_amount.poster_present_3cd
-poster_present_1dvd = context.portal_categories.base_amount.poster_present_1dvd
-
-total_quantity_3cd = sum([movement.getQuantity() for movement in aggregated_movement_list
-                          if poster_present_3cd in movement.getBaseContributionValueList()])
-total_quantity_1dvd = sum([movement.getQuantity() for movement in aggregated_movement_list
-                           if poster_present_1dvd in movement.getBaseContributionValueList()])
-if (total_quantity_3cd >= 3 or total_quantity_1dvd >= 1):
-  current_movement.setQuantity(1)
-  return current_movement
-else:
-  return None
-''')
-    order = self.createOrder()
-    order.edit(specialise_value=self.trade_condition)
-    order.Order_applyTradeCondition(order.getSpecialiseValue())
-    order.newContent(portal_type='Trade Model Line',
-                     reference='3CD_OR_1DVD_GET_1_POSTER_FREE',
-                     resource_value=self.poster,
-                     price=0,
-                     quantity=None,
-                     efficiency=1,
-                     target_level=TARGET_LEVEL_DELIVERY,
-                     calculation_script_id='TradeModelLine_calculate3CDOr1DVDForPoster',
-                     create_line=True,
-                     trade_phase=None,
-                     base_application_value_list=[self.poster_present_1dvd,
-                                                  self.poster_present_3cd])
-
-    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_4,
-                                    quantity=2,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_1, self.poster_present_3cd)
-
-    self.stepTic()
-
-    # check the current amount
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 6000)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 300)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 6300)
-    self.assertEqual(self.getAmount(order, '3CD_OR_1DVD_GET_1_POSTER_FREE'),
-                     None)
-    # add 1 dvd, then 1 poster will be given.
-    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.movie_dvd_1,
-                                    quantity=1,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_2, self.poster_present_1dvd)
-
-    self.stepTic()
-    
-    # check again
-    one_free_poster_amount = self.getAmount(order,
-                                            '3CD_OR_1DVD_GET_1_POSTER_FREE',
-                                            return_object=True)
-    self.assertEqual(one_free_poster_amount.getTotalPrice(), 0)
-    self.assertEqual(one_free_poster_amount.getQuantity(), 1)
-    self.assertEqual(one_free_poster_amount.getPrice(), 0)
-    self.assertEqual(one_free_poster_amount.getResourceValue(), self.poster)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 9000)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 450)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 9450)
-
-    # even if we buy 3 CDs and 1 DVD, only one poster will be given.
-    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_3,
-                                    quantity=1,
-                                    price=2400)
-    self.appendBaseContributionCategory(order_line_3, self.poster_present_3cd)
-
-    self.stepTic()
-
-    # check again
-    one_free_poster_amount = self.getAmount(order,
-                                            '3CD_OR_1DVD_GET_1_POSTER_FREE',
-                                            return_object=True)
-    self.assertEqual(one_free_poster_amount.getTotalPrice(), 0)
-    self.assertEqual(one_free_poster_amount.getQuantity(), 1)
-    self.assertEqual(one_free_poster_amount.getPrice(), 0)
-    self.assertEqual(one_free_poster_amount.getResourceValue(), self.poster)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 11400)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 570)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 11970)
-
-  def test_usecase5(self):
-    """
-    Use case 5 : Buy 3 CDs or more, 1 highest priced DVD in ordered 15% off.
-
-    1 DVD    3000 yen
-    1 DVD    1000 yen
-    2 CD    10000 yen
-    1 CD     3000 yen
-    discount 3000 * 0.15 = 450 yen
-    """
-    createZODBPythonScript(
-      self.portal.portal_skins.custom,
-      'TradeModelLine_calculate3CD15PercentDiscountOf1HighestPricedDVD',
-      'current_aggregated_amount_list, current_movement, aggregated_movement_list',
-      '''\
-total_quantity = sum([movement.getQuantity() for movement in aggregated_movement_list])
-if total_quantity >= 3:
-  price_dvd_list = []
-  product_line_dvd = context.portal_categories.product_line.video.dvd
-  for movement in current_aggregated_amount_list:
-    resource = movement.getResourceValue()
-    if resource.getProductLineValue() == product_line_dvd:
-      price_dvd_list.append((movement.getPrice(), movement))
-  if price_dvd_list:
-    price_dvd_list.sort()
-    highest_priced_dvd_movement = price_dvd_list[-1][1]
-    total_price = highest_priced_dvd_movement.getTotalPrice()
-
-    from Products.ERP5Type.Document import newTempSimulationMovement
-    causality_value_list = list(aggregated_movement_list) + [highest_priced_dvd_movement]
-    temporary_movement = newTempSimulationMovement(current_movement.getParentValue(), current_movement.getId())
-    temporary_movement.edit(title=current_movement.getProperty('title'),
-                            description=current_movement.getProperty('description'),
-                            resource=current_movement.getProperty('resource'),
-                            reference=current_movement.getProperty('reference'),
-                            int_index=current_movement.getProperty('int_index'),
-                            base_application_list=current_movement.getProperty('base_application_list'),
-                            base_contribution_list=current_movement.getProperty('base_contribution_list'),
-                            start_date=highest_priced_dvd_movement.getStartDate(),
-                            stop_date=highest_priced_dvd_movement.getStopDate(),
-                            create_line=current_movement.getProperty('is_create_line'),
-                            trade_phase_list=current_movement.getTradePhaseList(),
-                            causality_list=[movement.getRelativeUrl() for movement in causality_value_list])
-    temporary_movement.setPrice(current_movement.getProperty('price'))
-    temporary_movement.setQuantity(highest_priced_dvd_movement.getPrice())
-    return temporary_movement
-''')
-    order = self.createOrder()
-    order.edit(specialise_value=self.trade_condition)
-    order.Order_applyTradeCondition(order.getSpecialiseValue())
-    order.newContent(portal_type='Trade Model Line',
-                     reference='3CD_AND_1HIGHEST_PRICED_DVD_15PERCENT_OFF',
-                     resource_value=self.service_discount,
-                     price=-0.15,
-                     quantity=None,
-                     efficiency=1,
-                     target_level=TARGET_LEVEL_DELIVERY,
-                     calculation_script_id='TradeModelLine_calculate3CD15PercentDiscountOf1HighestPricedDVD',
-                     create_line=True,
-                     trade_phase=None,
-                     base_application_value_list=[self.special_discount_3cd],
-                     base_contribution_value_list=[self.discount_amount_of_vat_taxable])
-
-    order_line_1 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.movie_dvd_1,
-                                    quantity=1,
-                                    price=3000)
-    order_line_2 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.movie_dvd_2,
-                                    quantity=1,
-                                    price=1000)
-    order_line_3 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_1,
-                                    quantity=1,
-                                    price=5000)
-    self.appendBaseContributionCategory(order_line_3, self.special_discount_3cd)
-    order_line_4 = order.newContent(portal_type=self.order_line_portal_type,
-                                    resource_value=self.music_album_2,
-                                    quantity=1,
-                                    price=3000)
-    self.appendBaseContributionCategory(order_line_4, self.special_discount_3cd)
-
-    self.stepTic()
-
-    # check the current amount
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 12000)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 600)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'),
-                     12600)
-    # add one more cd, then total is 3. the special discount will be applied.
-    order_line_3.setQuantity(2)
-
-    self.stepTic()
-
-    # check again
-    self.assertEqual(self.getAmount(order, '3CD_AND_1HIGHEST_PRICED_DVD_15PERCENT_OFF'),
-                     -450)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITHOUT_VAT'), 16550)
-    self.assertEqual(self.getAmount(order, 'VAT_AMOUNT'), 827.5)
-    self.assertEqual(self.getAmount(order, 'TOTAL_PRICE_WITH_VAT'), 17377.5)
-
-
 class TestTradeModelLineSale(TestTradeModelLine):
   invoice_portal_type = 'Sale Invoice Transaction'
   invoice_line_portal_type = 'Invoice Line'
@@ -3375,22 +2741,8 @@ class TestTradeModelLinePurchase(TestTradeModelLine):
   trade_condition_portal_type = 'Purchase Trade Condition'
 
 
-class TestComplexTradeModelLineUseCaseSale(TestComplexTradeModelLineUseCase):
-  order_portal_type = 'Sale Order'
-  order_line_portal_type = 'Sale Order Line'
-  trade_condition_portal_type = 'Sale Trade Condition'
-
-
-class TestComplexTradeModelLineUseCasePurchase(TestComplexTradeModelLineUseCase):
-  order_portal_type = 'Purchase Order'
-  order_line_portal_type = 'Purchase Order Line'
-  trade_condition_portal_type = 'Purchase Trade Condition'
-
-
 def test_suite():
   suite = unittest.TestSuite()
   suite.addTest(unittest.makeSuite(TestTradeModelLineSale))
   suite.addTest(unittest.makeSuite(TestTradeModelLinePurchase))
-  suite.addTest(unittest.makeSuite(TestComplexTradeModelLineUseCaseSale))
-  suite.addTest(unittest.makeSuite(TestComplexTradeModelLineUseCasePurchase))
   return suite
-- 
2.30.9