##############################################################################
#
# Copyright (c) 2004, 2005 Nexedi SARL and Contributors. All Rights Reserved.
#          Sebastien Robin <seb@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
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from DateTime import DateTime
from Products.ERP5Type.tests.Sequence import SequenceList
from erp5.component.test.testOrder import TestOrderMixin
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod

class TestInventoryModule(TestOrderMixin, ERP5TypeTestCase):
  """
    Test inventory module
  """
  run_all_test = 1
  inventory_portal_type = 'Inventory'
  inventory_line_portal_type = 'Inventory Line'
  inventory_cell_portal_type = 'Inventory Cell'
  item_portal_type = 'Apparel Bath'
  first_date_string = '2005/12/09' # First Inventory
  second_date_string = '2005/12/29' # Next Inventory
  view_stock_date = '2005/12/31' # The day where we are looking for stock
  size_list = ['Child/32','Child/34']

  def getTitle(self):
    return "Inventory Module"

  def getInventoryModule(self):
    return getattr(self.getPortal(), 'inventory_module',None)

  def deliverPackingList(self, packing_list):
    """step through all steps of packing list workflow."""
    packing_list.confirm()
    packing_list.setReady()
    packing_list.start()
    packing_list.stop()
    packing_list.deliver()
    self.assertEqual(packing_list.getSimulationState(), 'delivered')

  def stepCreateInitialMovements(self, sequence=None, **kw):
    """Create movements before this inventory.
    """
    pplm = self.getPortal().purchase_packing_list_module
    splm = self.getPortal().sale_packing_list_module
    iplm = self.getPortal().internal_packing_list_module

    # we create content :
    #   1 purchase packing list
    #   1 sale packing list
    #   1 internal packing list
    for month in range(1, 11):
      ppl = pplm.newContent(
                      portal_type='Purchase Packing List',
                      specialise=self.business_process,
                      source_value = sequence.get('organisation2'),
                      destination_value = sequence.get('organisation1'),
                      start_date=DateTime(2005, month, 1),
                    )
      ppl.newContent( portal_type='Purchase Packing List Line',
                      resource_value=sequence.get('resource'),
                      quantity=month*10) # dummy quantity, it will be
                                         # replaced by inventory
      self.deliverPackingList(ppl)

      spl = splm.newContent(
                      portal_type='Sale Packing List',
                      specialise=self.business_process,
                      source_value = sequence.get('organisation1'),
                      destination_value = sequence.get('organisation2'),
                      start_date=DateTime(2005, month, 1),
                    )
      spl.newContent( portal_type='Sale Packing List Line',
                      resource_value=sequence.get('resource'),
                      quantity=month*10)
      self.deliverPackingList(spl)

      ipl = iplm.newContent(
                      portal_type='Internal Packing List',
                      specialise=self.business_process,
                      source_value = sequence.get('organisation1'),
                      destination_value = sequence.get('organisation1'),
                      start_date=DateTime(2005, month, 1),
                    )
      ipl.newContent( portal_type='Internal Packing List Line',
                      resource_value=sequence.get('resource'),
                      quantity=month*10)
      self.deliverPackingList(ipl)

  def createInventory(self, start_date=None,
                                       sequence=None,**kw):
    """
    We will put default values for an inventory
    """
    organisation =  sequence.get('organisation1')
    inventory = self.getInventoryModule().newContent()
    inventory.edit(start_date=start_date,
                   destination_value=organisation)
    inventory.deliver()
    inventory_list = sequence.get('inventory_list',[])
    inventory_list.append(inventory)
    sequence.edit(inventory_list=inventory_list)
    return inventory

  @UnrestrictedMethod
  def createNotVariatedInventoryLine(self, quantity=None,
                                       sequence=None,**kw):
    """
    We will put default values for an inventory
    """
    inventory = sequence.get('inventory_list')[-1]
    resource = sequence.get('resource_list')[-1]
    inventory_line = inventory.newContent(
           portal_type=self.inventory_line_portal_type)
    inventory_line.edit(inventory=quantity,
                        resource_value = resource)
    return inventory

  def stepCreateFirstNotVariatedInventory(self, sequence=None,
                                          sequence_list=None, **kw):
    """
    We will put default values for an inventory
    """
    date = DateTime(self.first_date_string)
    quantity=self.default_quantity
    self.createInventory(start_date=date,sequence=sequence)
    self.createNotVariatedInventoryLine(sequence=sequence,
                                    quantity=quantity)

  def stepCreateSecondNotVariatedInventory(self, sequence=None,
                                           sequence_list=None, **kw):
    """
    We will put default values for an inventory
    """
    date = DateTime(self.second_date_string)
    quantity=self.default_quantity - 2
    self.createInventory(start_date=date,sequence=sequence)
    self.second_inventory = self.createNotVariatedInventoryLine(sequence=sequence,
                                    quantity=quantity)


  @UnrestrictedMethod
  def stepModifySecondNotVariatedInventory(self, sequence=None,
                                           sequence_list=None, **kw):
    """
    Modify the quantity to have a tmp line with null quantity
    """
    quantity=self.default_quantity
    inventory_line = self.second_inventory.objectValues()[0]
    inventory_line.edit(inventory=quantity)


  def stepCheckFirstNotVariatedInventory(self, start_date=None,quantity=None,
                                             sequence=None,**kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(self.default_quantity,quantity)

  def stepCheckSecondNotVariatedInventory(self, start_date=None,quantity=None,
                                             sequence=None, **kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(self.default_quantity-2,quantity)

  def stepCheckSecondNotVariatedInventoryModified(self, start_date=None,quantity=None,
                                             sequence=None,**kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(self.default_quantity,quantity)


  def test_01_NotVariatedInventory(self, quiet=0, run=run_all_test):
    """
    We will create an inventory with the default quantity for
    a particular resource. Then we will check if the is correct.
    Then we create another inventory and see if we have the new
    stock value
    """
    if not run: return
    self.logMessage('Test Not Variated Inventory')

    sequence_list = SequenceList()

    # Test with a simple inventory without cell
    sequence_string = 'stepCreateNotVariatedResource \
                       stepCreateOrganisation1 \
                       stepCreateInitialMovements \
                       stepTic \
                       stepCreateFirstNotVariatedInventory \
                       stepTic \
                       stepCheckFirstNotVariatedInventory \
                       stepCreateSecondNotVariatedInventory \
                       stepTic \
                       stepCheckSecondNotVariatedInventory \
                       stepModifySecondNotVariatedInventory \
                       stepTic \
                       stepCheckSecondNotVariatedInventoryModified'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  @UnrestrictedMethod
  def createVariatedInventoryLine(self, sequence=None, sequence_list=None,
                                 start_date=None, quantity=None, item_list=None,
                                 **kw):
    """
    We will put default values for an inventory
    """
    inventory = sequence.get('inventory_list')[-1]
    resource = sequence.get('resource_list')[-1]
    inventory_line = inventory.newContent(
           portal_type=self.inventory_line_portal_type)
    inventory_line.edit(resource_value = resource)
    resource_vcl = list(resource.getVariationCategoryList(
        omit_individual_variation=1, omit_optional_variation=1))
    resource_vcl.sort()
    self.assertEqual(len(resource_vcl),2)
    inventory_line.setVariationCategoryList(resource_vcl)
    base_id = 'movement'
    cell_key_list = list(inventory_line.getCellKeyList(base_id=base_id))
    cell_key_list.sort()
    price = 100
    for cell_key in cell_key_list:
      cell = inventory_line.newCell(base_id=base_id,
                                portal_type=self.inventory_cell_portal_type,
                                *cell_key)
      cell.edit(mapped_value_property_list=['price','inventory'],
                price=price, inventory=quantity,
                predicate_category_list=cell_key,
                variation_category_list=cell_key,)
      if item_list is not None:
        cell.setAggregateValueList(item_list)
      price += 1
      quantity += 1

  def stepCreateFirstVariatedInventory(self, sequence=None, sequence_list=None, \
                                 **kw):
    """
    We will put default values for an inventory
    """
    date = DateTime(self.first_date_string)
    self.createInventory(start_date=date,sequence=sequence)
    quantity = self.default_quantity
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)

  def stepCreateSecondVariatedInventory(self, sequence=None, sequence_list=None, \
                                 **kw):
    """
    We will put default values for an inventory
    """
    date = DateTime(self.second_date_string)
    self.createInventory(start_date=date,sequence=sequence)
    quantity = self.default_quantity - 10
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)

  @UnrestrictedMethod
  def createVariatedInventory(self, start_date=None,quantity=None,
                                       sequence=None,**kw):
    """
    We will put default values for an inventory
    """
    inventory = self.createNotVariatedInventory(sequence=sequence,
                                                start_date=start_date)
    resource = sequence.get('resource_list')[0]
    organisation =  sequence.get('organisation1')
    inventory = self.getInventoryModule().newContent()
    inventory.edit(start_date=start_date,
                   destination_value=organisation)
    inventory_line = inventory.newContent(
           portal_type=self.inventory_line_portal_type)
    inventory_line.edit(inventory=quantity,
                        resource_value = resource,
                        destination_value=organisation)

  def stepCheckFirstVariatedInventory(self, start_date=None,quantity=None,
                                             sequence=None,**kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    total_quantity = 99 + 100
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date)
    self.assertEqual(total_quantity,quantity)
    variation_text = 'size/Child/32'
    total_quantity = 99
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        variation_text=variation_text,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(total_quantity,quantity)

  def stepCheckSecondVariatedInventory(self, start_date=None,quantity=None,
                                             sequence=None,**kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    total_quantity = 89 + 90
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date)
    self.assertEqual(total_quantity,quantity)
    variation_text = 'size/Child/32'
    total_quantity = 89
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        variation_text=variation_text,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(total_quantity,quantity)

  def test_02_VariatedInventory(self, run=run_all_test):
    """
    Same thing as test_01 with variation
    """
    if not run: return
    self.logMessage('Test Variated Inventory')

    sequence_list = SequenceList()

    # Test with a variated inventory
    sequence_string = 'stepCreateVariatedResource \
                       stepCreateOrganisation1 \
                       stepCreateInitialMovements \
                       stepTic \
                       stepCreateFirstVariatedInventory \
                       stepTic \
                       stepCheckFirstVariatedInventory \
                       stepCreateSecondVariatedInventory \
                       stepTic \
                       stepCheckSecondVariatedInventory'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  def stepCreateItem(self, start_date=None,quantity=None,
                                             sequence=None,**kw):
    """
    Create an Apparel Bath
    """
    portal = self.getPortal()
    item_list = sequence.get('item_list',[])
    item_module = portal.getDefaultModule(self.item_portal_type)
    item = item_module.newContent(portal_type=self.item_portal_type)
    item_list.append(item)
    sequence.edit(item_list=item_list)

  def stepCreateFirstVariatedAggregatedInventory(self, sequence=None, sequence_list=None, \
                                 **kw):
    """
    We will put default values for an inventory
    - size/Child/32 99
    - size/Child/34 100
    - size/Child/32 99    item1,item2
    - size/Child/34 100   item1,item2
    """
    date = DateTime(self.first_date_string)
    self.createInventory(start_date=date,sequence=sequence)
    quantity = self.default_quantity
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)
    item_list = sequence.get('item_list')
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity,
                  item_list=item_list)

  def getAggregateRelativeUrlText(self,item_list):
    relative_url_list = ['aggregate/%s' % x.getRelativeUrl() for x in item_list]
    relative_url_list.sort()
    relative_url_text = '\n'.join(relative_url_list)
    return relative_url_text

  def stepCheckFirstVariatedAggregatedInventory(self, start_date=None,
                                quantity=None, sequence=None, **kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    total_quantity = (99 + 100) * 2
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date)
    self.assertEqual(total_quantity,quantity)
    variation_text = 'size/Child/32'
    total_quantity = (99) * 2
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        variation_text=variation_text,
                        to_date=date)
    self.assertEqual(total_quantity,quantity)
    # Also check when we look stock for a particular aggregate
    sub_variation_text = self.getAggregateRelativeUrlText(
                                            sequence.get('item_list'))
    total_quantity = 99
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        variation_text=variation_text,
                        to_date=date,
                        sub_variation_text=sub_variation_text)
    self.assertEqual(total_quantity,quantity)

  def stepCheckExplanationTextInInventoryList(self, start_date=None,
                                quantity=None, sequence=None, **kw):
    """Tests getExplanationText from InventoryBrain
    """
    # this is rather a test for InventoryBrain
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    for inventory_brain in self.getSimulationTool().getInventoryList(
                        node_uid=node_uid,
                        resource=resource_url,
                        to_date=date):
      self.assertNotEquals(inventory_brain.getExplanationText(),
                           'Unknown')
      self.assertNotEquals(inventory_brain.getListItemUrl(
                                'getExplanationText',
                                0,
                                'dummy_selection_name'), '')

  def stepCreateSecondVariatedAggregatedInventory(self, sequence=None,
                                      sequence_list=None, **kw):
    """
    We will put default values for an inventory
    - size/Child/32 89    item1,item2
    - size/Child/34 90    item1,item2
    - size/Child/32 89    item1
    - size/Child/34 90    item1
    """
    date = DateTime(self.second_date_string)
    self.createInventory(start_date=date,sequence=sequence)
    quantity = self.default_quantity - 10
    item_list = sequence.get('item_list')
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)
    item_list = sequence.get('item_list')[:1]
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity,
                  item_list=item_list)

  def stepCheckSecondVariatedAggregatedInventory(self, start_date=None,
                                quantity=None, sequence=None, **kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    total_quantity = (89 + 90) * 2
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date)
    self.assertEqual(total_quantity,quantity)
    variation_text = 'size/Child/32'
    total_quantity = (89) * 2
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        variation_text=variation_text,
                        to_date=date,simulation_state='delivered')
    self.assertEqual(total_quantity,quantity)
    # Also check when we look stock for a particular aggregate
    sub_variation_text = self.getAggregateRelativeUrlText(
                                                sequence.get('item_list'))
    total_quantity = 0
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                        resource=resource_url,
                        to_date=date,
                        sub_variation_text=sub_variation_text,
                        simulation_state='delivered')
    self.assertEqual(total_quantity,quantity)
    sub_variation_text = self.getAggregateRelativeUrlText(
                                    sequence.get('item_list')[:1])

  def test_03_VariatedAggregatedInventory(self, run=run_all_test):
    """
    Same thing as test_01 with variation and aggregate
    """
    if not run: return
    self.logMessage('Test Variated Aggregated Inventory')

    sequence_list = SequenceList()

    # Test with a variated inventory with some aggregate
    sequence_string = 'stepCreateVariatedResource \
                       stepCreateOrganisation1 \
                       stepCreateInitialMovements \
                       stepTic \
                       stepCreateItem \
                       stepCreateItem \
                       stepCreateFirstVariatedAggregatedInventory \
                       stepTic \
                       stepCheckFirstVariatedAggregatedInventory \
                       stepCreateSecondVariatedAggregatedInventory \
                       stepTic \
                       stepCheckSecondVariatedAggregatedInventory'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  def test_04_VariatedAggregatedInventoryGetInventoryList(self, run=run_all_test):
    """
    Same thing as test_03 with testing getInventoryList columns
    """
    if not run: return
    self.logMessage('Test getInventoryList and Variated Aggregated Inventory')

    sequence_list = SequenceList()

    # Test with a variated inventory with some aggregate
    sequence_string = 'stepCreateVariatedResource \
                       stepCreateOrganisation1 \
                       stepCreateInitialMovements \
                       stepTic \
                       stepCreateItem \
                       stepCreateItem \
                       stepCreateFirstVariatedAggregatedInventory \
                       stepTic \
                       stepCheckFirstVariatedAggregatedInventory \
                       stepCheckExplanationTextInInventoryList \
                       stepCreateSecondVariatedAggregatedInventory \
                       stepTic \
                       stepCheckSecondVariatedAggregatedInventory \
                       stepCheckExplanationTextInInventoryList'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  def stepCreateFirstVariatedMultipleQuantityUnitResourceInventory(self, sequence=None, sequence_list=None, \
                                 **kw):
    """
    We will put default values for an inventory
    - size/Child/32 99 drum
    - size/Child/34 100 drum
    - size/Child/32 99 kilogram
    - size/Child/34 100 kiligram
    """
    date = DateTime(self.first_date_string)
    inventory = self.createInventory(start_date=date,sequence=sequence)
    quantity = self.default_quantity
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)
    inventory_line = inventory.objectValues(portal_type='Inventory Line')[0]
    # Set non-default quantity unit to make sure that conversion correctly
    # works and converted value is applied to stock.
    inventory_line.setQuantityUnitValue(self.portal.portal_categories.quantity_unit.unit.drum)
    self.createVariatedInventoryLine(start_date=date,
                  sequence=sequence, quantity=quantity)

  def stepCheckFirstVariatedMultipleQuantityUnitResourceInventory(self, sequence=None, sequence_list=None, \
                                 **kw):
    node_uid = sequence.get('organisation1').getUid()
    resource_url = sequence.get('resource').getRelativeUrl()
    date = DateTime(self.view_stock_date)
    inventory = sequence.get('inventory_list')[-1]
    total_quantity = sum([inventory_movement.getInventoriatedQuantity() for inventory_movement in inventory.getMovementList()])
    self.assertEqual(total_quantity, (99*100 + 100*100 + 99 + 100))
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                                                     resource=resource_url,
                                                     to_date=date)
    self.assertEqual(total_quantity, quantity)
    variation_text = 'size/Child/32'
    total_quantity = (99*100 + 99)
    quantity = self.getSimulationTool().getInventory(node_uid=node_uid,
                                                     resource=resource_url,
                                                     variation_text=variation_text,
                                                     to_date=date)
    self.assertEqual(total_quantity,quantity)

  def test_05_VariatedMultipleQuantityUnitResourceInventory(self, run=run_all_test):
    """
    Input inventory for resource which has variation and multiple quantity units
    and make sure that inventory stores correct data.
    """
    if not run: return
    self.logMessage('Test inventory with variated multiple quantity units resource')

    sequence_list = SequenceList()

    sequence_string = 'stepCreateVariatedMultipleQuantityUnitResource \
                       stepCreateOrganisation1 \
                       stepTic \
                       stepCreateFirstVariatedMultipleQuantityUnitResourceInventory \
                       stepTic \
                       stepCheckFirstVariatedMultipleQuantityUnitResourceInventory'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  def createInitialDeliveryForCheckingUselessCorrection(self, sequence=None):
    organisation =  sequence.get('organisation1')
    from_organisation = sequence.get('organsation2')
    delivery = self.getPortal().internal_packing_list_module.newContent(
                    portal_type='Internal Packing List',
                    specialise=self.business_process,
                    source_value = from_organisation,
                    destination_value = organisation,
                    start_date=DateTime(2019, 02, 20),
                  )
    resource_value = sequence.get('resource')
    delivery.newContent( portal_type='Internal Packing List Line',
                    resource_value=resource_value,
                    quantity=2)
    self.deliverPackingList(delivery)
    self.tic()
    return delivery

  def stepCheckInventoryDoesNotKeepUselessCorrectionAtInventoryLevel(self, sequence=None):
    organisation =  sequence.get('organisation1')
    resource_value = sequence.get('resource')
    delivery = self.createInitialDeliveryForCheckingUselessCorrection(sequence=sequence)

    def getInventoryQuantity():
      return self.getSimulationTool().getCurrentInventory(node_uid=organisation.getUid(),
                                                  resource=resource_value.getRelativeUrl())

    self.assertEqual(2, getInventoryQuantity())

    inventory = self.getInventoryModule().newContent()
    inventory.edit(start_date=DateTime(2019, 02, 21),
                   destination_value=organisation,
                   full_inventory=True)
    inventory.deliver()
    self.tic()

    self.assertEqual(0, getInventoryQuantity())

    delattr(delivery, 'workflow_history')
    self.assertEqual('draft', delivery.getSimulationState())
    delivery.reindexObject()
    self.tic()
    inventory.reindexObject()
    self.tic()
    self.assertEqual(0, getInventoryQuantity())

  def test_06_InventoryDoesNotKeepUselessCorrectionAtInventoryLevel(self):
    """
    We will create a movement, then a full inventory setting all stock to 0.
    This will insert a correction line in stock table with uid of inventory.
    But then, if initial movement is cancelled, a reindex of inventory must remove the correction
    """
    sequence_list = SequenceList()

    # Test with a simple inventory without cell
    sequence_string = 'stepCreateNotVariatedResource \
                       stepCreateOrganisation1 \
                       stepTic \
                       stepCheckInventoryDoesNotKeepUselessCorrectionAtInventoryLevel'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

  def stepCheckInventoryDoesNotKeepUselessCorrectionAtLineLevel(self, sequence=None):
    organisation =  sequence.get('organisation1')
    resource_value = sequence.get('resource')
    delivery = self.createInitialDeliveryForCheckingUselessCorrection(sequence=sequence)

    def getInventoryQuantity():
      return self.getSimulationTool().getCurrentInventory(node_uid=organisation.getUid(),
                                                  resource=resource_value.getRelativeUrl())

    self.assertEqual(2, getInventoryQuantity())

    inventory = self.getInventoryModule().newContent()
    inventory.edit(start_date=DateTime(2019, 02, 21),
                   destination_value=organisation,
                   full_inventory=True)
    inventory_line = inventory.newContent(portal_type='Inventory Line',
                    resource_value=resource_value,
                    quantity=3)
    inventory.deliver()
    self.tic()

    self.assertEqual(3, getInventoryQuantity())

    delattr(delivery, 'workflow_history')
    self.assertEqual('draft', delivery.getSimulationState())
    delivery.reindexObject()
    self.tic()
    inventory.reindexObject()
    self.tic()
    self.assertEqual(3, getInventoryQuantity())
    # Even though this scenario might not really, happen, make sure the code does not
    # keep a correction line for a resource which is not set any more
    inventory_line.setResourceValue(None)
    inventory.reindexObject()
    self.tic()
    self.assertEqual(0, getInventoryQuantity())
    inventory_line.setResourceValue(resource_value)
    inventory.reindexObject()
    self.tic()
    self.assertEqual(3, getInventoryQuantity())
    # last safety check, make sure deletion of line of inventory has really an impact
    inventory.manage_delObjects(ids=[inventory_line.getId()])
    inventory.reindexObject()
    self.tic()
    self.assertEqual(0, getInventoryQuantity())

  def test_07_InventoryDoesNotKeepUselessCorrectionAtLineLevel(self):
    """
    We will create a movement, then a full inventory changing stock value.
    This will insert a correction line in stock table with uid of inventory line.
    But then, if initial movement is cancelled, a reindex of inventory must remove the correction
    """
    sequence_list = SequenceList()

    # Test with a simple inventory without cell
    sequence_string = 'stepCreateNotVariatedResource \
                       stepCreateOrganisation1 \
                       stepTic \
                       stepCheckInventoryDoesNotKeepUselessCorrectionAtLineLevel'
    sequence_list.addSequenceString(sequence_string)

    sequence_list.play(self)

def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestInventoryModule))
  return suite