# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved. # Ćukasz Nowak <lukasz.nowak@ventis.com.pl> # # 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.ERP5TypeTestCase import ERP5TypeTestCase from DateTime import DateTime from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5.tests.testOrder import TestOrderMixin from Products.ERP5.tests.utils import newSimulationExpectedFailure class TestOrderBuilderMixin(TestOrderMixin): run_all_test = 1 order_builder_portal_type = 'Order Builder' order_module = 'purchase_order_module' order_portal_type = 'Purchase Order' order_line_portal_type = 'Purchase Order Line' order_cell_portal_type = 'Purchase Order Cell' packing_list_portal_type = 'Internal Packing List' packing_list_line_portal_type = 'Internal Packing List Line' packing_list_cell_portal_type = 'Internal Packing List Cell' # hardcoded values order_builder_hardcoded_time_diff = 10.0 # defaults decrease_quantity = 1.0 max_delay = 0.0 min_flow = 0.0 def stepSetMaxDelayOnResource(self, sequence=None, sequence_list=None, **kw): """ Sets max_delay on resource """ resource = sequence.get('resource') resource.edit( max_delay = self.max_delay, ) def stepSetMinFlowOnResource(self, sequence=None, sequence_list=None, **kw): """ Sets min_flow on resource """ resource = sequence.get('resource') resource.edit( min_flow = self.min_flow, ) def stepFillOrderBuilder(self, sequence=None, sequence_list=None, **kw): """ Fills Order Builder with proper quantites """ order_builder = sequence.get('order_builder') organisation = sequence.get('organisation') order_builder.edit( delivery_module = self.order_module, delivery_portal_type = self.order_portal_type, delivery_line_portal_type = self.order_line_portal_type, delivery_cell_portal_type = self.order_cell_portal_type, destination_value = organisation, resource_portal_type = self.resource_portal_type, ) order_builder.newContent( portal_type = 'Category Movement Group', collect_order_group='delivery', tested_property=['source', 'destination', 'source_section', 'destination_section'], int_index=1 ) order_builder.newContent( portal_type = 'Property Movement Group', collect_order_group='delivery', tested_property=['start_date', 'stop_date'], int_index=2 ) order_builder.newContent( portal_type = 'Category Movement Group', collect_order_group='line', tested_property=['resource'], int_index=1 ) order_builder.newContent( portal_type = 'Base Variant Movement Group', collect_order_group='line', int_index=2 ) order_builder.newContent( portal_type = 'Variant Movement Group', collect_order_group='cell', int_index=1 ) def stepCheckGeneratedDocumentListVariated(self, sequence=None, sequence_list=None, **kw): """ Checks documents generated by Order Builders with its properties for variated resource """ # XXX: Some values still hardcoded organisation = sequence.get('organisation') resource = sequence.get('resource') generated_document_list = sequence.get('generated_document_list') self.assertEquals( 1, # XXX len(generated_document_list) ) order = generated_document_list[0] self.assertEquals( order.getDestinationValue(), organisation ) self.assertEquals( order.getStartDate(), self.wanted_start_date ) self.assertEquals( order.getStopDate(), self.wanted_stop_date ) order_line_list = order.contentValues(filter={'portal_type':self.order_line_portal_type}) self.assertEquals( 1, # XXX len(order_line_list) ) order_line = order_line_list[0] # XXX: add support for more lines and cells too self.assertEquals( order_line.getResourceValue(), resource ) self.assertEquals( order_line.getTotalQuantity(), sum(self.wanted_quantity_matrix.itervalues()) ) order_cell_list = order_line.contentValues(filter={'portal_type':self.order_cell_portal_type}) self.assertEquals( len(order_cell_list), len(self.wanted_quantity_matrix.values()) ) for order_cell in order_cell_list: self.assertEquals( order_cell.getQuantity(), self.wanted_quantity_matrix[ order_cell.getProperty('membership_criterion_category') ] ) def stepCheckGeneratedDocumentList(self, sequence=None, sequence_list=None, **kw): """ Checks documents generated by Order Builders with its properties """ # XXX: Some values still hardcoded organisation = sequence.get('organisation') resource = sequence.get('resource') generated_document_list = sequence.get('generated_document_list') self.assertEquals( 1, # XXX len(generated_document_list) ) order = generated_document_list[0] self.assertEquals( order.getDestinationValue(), organisation ) self.assertEquals( order.getStartDate(), self.wanted_start_date ) self.assertEquals( order.getStopDate(), self.wanted_stop_date ) order_line_list = order.contentValues(filter={'portal_type':self.order_line_portal_type}) self.assertEquals( 1, # XXX len(order_line_list) ) order_line = order_line_list[0] # XXX: add support for more lines and cells too self.assertEquals( order_line.getResourceValue(), resource ) self.assertEquals( order_line.getTotalQuantity(), self.wanted_quantity ) def stepBuildOrderBuilder(self, sequence=None, sequence_list=None, **kw): """ Invokes build method for Order Builder """ order_builder = sequence.get('order_builder') generated_document_list = order_builder.build() sequence.edit(generated_document_list = generated_document_list) def stepCreateOrderBuilder(self, sequence=None, sequence_list=None, **kw): """ Creates empty Order Builder """ portal_orders = self.portal.portal_orders order_builder = portal_orders.newContent( portal_type = self.order_builder_portal_type ) sequence.edit( order_builder = order_builder ) def stepDecreaseOrganisationResourceQuantityVariated(self, sequence=None, sequence_list=None, **kw): """ Creates movement with variation from organisation to None. Using Internal Packing List, confirms it. Note: Maybe use InventoryAPITestCase::_makeMovement instead of IPL ? """ organisation = sequence.get('organisation') resource = sequence.get('resource') packing_list_module = self.portal.getDefaultModule( portal_type = self.packing_list_portal_type ) packing_list = packing_list_module.newContent( portal_type = self.packing_list_portal_type, source_value = organisation, start_date = self.datetime ) packing_list_line = packing_list.newContent( portal_type = self.packing_list_line_portal_type, resource_value = resource, quantity = self.decrease_quantity, ) packing_list_line.setVariationCategoryList( list(self.decrease_quantity_matrix.iterkeys()) ) transaction.commit() self.tic() base_id = 'movement' cell_key_list = list(packing_list_line.getCellKeyList(base_id=base_id)) cell_key_list.sort() for cell_key in cell_key_list: cell = packing_list_line.newCell(base_id=base_id, \ portal_type=self.packing_list_cell_portal_type, *cell_key) cell.edit(mapped_value_property_list=['price','quantity'], quantity=self.decrease_quantity_matrix[cell_key[0]], predicate_category_list=cell_key, variation_category_list=cell_key) packing_list.confirm() def stepDecreaseOrganisationResourceQuantity(self, sequence=None, sequence_list=None, **kw): """ Creates movement from organisation to None. Using Internal Packing List, confirms it. Note: Maybe use InventoryAPITestCase::_makeMovement instead of IPL ? """ organisation = sequence.get('organisation') resource = sequence.get('resource') packing_list_module = self.portal.getDefaultModule( portal_type = self.packing_list_portal_type ) packing_list = packing_list_module.newContent( portal_type = self.packing_list_portal_type, source_value = organisation, start_date = self.datetime ) packing_list.newContent( portal_type = self.packing_list_line_portal_type, resource_value = resource, quantity = self.decrease_quantity, ) packing_list.confirm() class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase): """ Test Order Builder functionality """ run_all_test = 1 common_sequence_string = '\ CreateOrganisation \ CreateNotVariatedResource \ SetMaxDelayOnResource \ SetMinFlowOnResource \ Tic \ DecreaseOrganisationResourceQuantity \ Tic \ CreateOrderBuilder \ FillOrderBuilder \ Tic \ BuildOrderBuilder \ Tic \ CheckGeneratedDocumentList \ ' def getTitle(self): return "Order Builder" @newSimulationExpectedFailure def test_01_simpleOrderBuilder(self, quiet=0, run=run_all_test): """ Test simple Order Builder """ if not run: return self.wanted_quantity = 1.0 self.wanted_start_date = DateTime( str(self.datetime.earliestTime() \ + self.order_builder_hardcoded_time_diff)) self.wanted_stop_date = self.wanted_start_date sequence_list = SequenceList() sequence_list.addSequenceString(self.common_sequence_string) sequence_list.play(self) @newSimulationExpectedFailure def test_01a_simpleOrderBuilderVariatedResource(self, quiet=0, run=run_all_test): """ Test simple Order Builder for Variated Resource """ if not run: return sequence_string = '\ CreateOrganisation \ CreateVariatedResource \ SetMaxDelayOnResource \ SetMinFlowOnResource \ Tic \ DecreaseOrganisationResourceQuantityVariated \ Tic \ CreateOrderBuilder \ FillOrderBuilder \ Tic \ BuildOrderBuilder \ Tic \ CheckGeneratedDocumentListVariated \ ' self.wanted_quantity = 1.0 self.wanted_start_date = DateTime( str(self.datetime.earliestTime() + \ self.order_builder_hardcoded_time_diff)) self.wanted_stop_date = self.wanted_start_date self.decrease_quantity_matrix = { 'size/Man' : 1.0, 'size/Woman' : 2.0, } self.wanted_quantity_matrix = self.decrease_quantity_matrix.copy() sequence_list = SequenceList() sequence_list.addSequenceString(sequence_string) sequence_list.play(self) @newSimulationExpectedFailure def test_02_maxDelayResourceOrderBuilder(self, quiet=0, run=run_all_test): """ Test max_delay impact on generated order start date """ if not run: return self.max_delay = 14.0 self.wanted_quantity = 1.0 self.wanted_start_date = DateTime( str(self.datetime.earliestTime() \ - self.max_delay \ + self.order_builder_hardcoded_time_diff)) self.wanted_stop_date = DateTime( str(self.datetime.earliestTime() \ + self.order_builder_hardcoded_time_diff)) sequence_list = SequenceList() sequence_list.addSequenceString(self.common_sequence_string) sequence_list.play(self) @newSimulationExpectedFailure def test_03_minFlowResourceOrderBuilder(self, quiet=0, run=run_all_test): """ Test min_flow impact on generated order line quantity """ if not run: return self.wanted_quantity = 1.0 self.wanted_start_date = DateTime( str(self.datetime.earliestTime() \ + self.order_builder_hardcoded_time_diff)) self.wanted_stop_date = self.wanted_start_date sequence_list = SequenceList() sequence_list.addSequenceString(self.common_sequence_string) # case when min_flow > decreased_quantity self.min_flow = 144.0 self.wanted_quantity = self.min_flow + self.decrease_quantity # why to order more than needed? # self.wanted_quantity = self.min_flow sequence_list.play(self) # case when min_flow < decreased_quantity self.min_flow = 15.0 self.decrease_quantity = 20.0 self.wanted_quantity = self.min_flow + self.decrease_quantity # why to order more than needed? # self.wanted_quantity = self.decreased_quantity sequence_list.play(self) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestOrderBuilder)) return suite