############################################################################## # # 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 responsability of assessing all potential # consequences resulting from its eventual inadequacies and bugs # End users who are looking for a ready-to-use solution with commercial # garantees and support are strongly adviced to contract a Free Software # Service Company # # This program is Free Software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## import unittest from DateTime import DateTime from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.utils import reindex from AccessControl.SecurityManagement import newSecurityManager from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5.tests.testInvoice import TestSaleInvoiceMixin from Products.ERP5.tests.utils import newSimulationExpectedFailure from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod class TestItemMixin(TestSaleInvoiceMixin): item_portal_type = 'Item' def getBusinessTemplateList(self): """ custom list of business templates for testItem erp5_trade_proxy_field_legacy is added only for a temporary period until wrongly proxyfied business template (erp5_item here) stops using obsolete field libraries. erp5_trade_proxy_field_legacy must be removed as soon as possible. """ return TestSaleInvoiceMixin.getBusinessTemplateList(self) + \ ('erp5_item',) + ('erp5_trade_proxy_field_legacy',) def createOrganisation(self, title=None): organisation_portal_type = 'Organisation' organisation_module = self.portal.getDefaultModule( portal_type=organisation_portal_type) organisation = organisation_module.newContent( portal_type=organisation_portal_type) if title is None: organisation.edit(title='organisation%s' % organisation.getId()) else: organisation.edit(title=title) return organisation def createNotVariatedResource(self,title=None): """ Create a resource with no variation """ resource_portal_type = 'Product' resource_module = self.portal.getDefaultModule(resource_portal_type) resource = resource_module.newContent(portal_type=resource_portal_type) resource.edit( title = "NotVariatedResource%s" % resource.getId(), quantity_unit='unit/piece', aggregated_portal_type_list=['Item'], required_aggregated_portal_type_list=['Item'] ) return resource def createVariatedResource(self,title=None): resource_portal_type = 'Product' resource_module = self.portal.getDefaultModule(resource_portal_type) resource = resource_module.newContent(portal_type=resource_portal_type) resource.edit( title = "VariatedResource%s" % resource.getId(), ) resource.setIndividualVariationBaseCategoryList(('size',)) resource.setQuantityUnit('unit/piece') resource.setAggregatedPortalTypeList('Item') resource.setRequiredAggregatedPortalTypeList('Item') # Add size variation size_variation_count = 3 for i in range(size_variation_count): variation_portal_type = 'Product Individual Variation' variation = resource.newContent(portal_type = variation_portal_type) variation.edit( title = 'SizeVariation%s' % str(i) ) return resource def createPackingList(self, resource=None, organisation=None, portal_type='Purchase Packing List'): portal = self.portal packing_list_module = portal.getDefaultModule(portal_type=portal_type) pac_list = packing_list_module.newContent(portal_type=portal_type) pac_list.edit( title = "PPL%s" % pac_list.getId(), start_date = self.datetime + 20, stop_date = self.datetime + 10, specialise_value = portal.business_process_module.erp5_default_business_process, ) if organisation is not None: pac_list.edit(source_value=organisation, source_section_value=organisation, destination_value=organisation, destination_section_value=organisation, source_decision_value=organisation, destination_decision_value=organisation, source_administration_value=organisation, destination_administration_value=organisation, ) return pac_list def createPackingListLine(self, packing_list=None, resource=None, portal_type='Purchase Packing List Line'): packing_list_line = packing_list.newContent(portal_type=portal_type) packing_list_line.edit( title = "Packing List Line" ) packing_list_line.setResourceValue(resource) return packing_list_line def stepCreateItemList(self, sequence=None, sequence_list=None, **kw): """ Create some items """ item_module = self.getPortal().item_module resource = sequence.get('resource') item = item_module.newContent(portal_type=self.item_portal_type) sequence.edit(item_list=[item]) def stepOrderLineSetAggregationList(self, sequence=None, sequence_list=None, **kw): """ Aggregate Items """ order_line = sequence.get('order_line') item_list = sequence.get('item_list') order_line.setAggregateValueList(item_list) def stepOrderSetAggregationList(self, sequence=None, sequence_list=None, **kw): """ Aggregate Items """ order = sequence.get('order') item_module = self.getPortal().item_module item_list = item_module.contentValues() # this step expect that number of order lines # and number of item list is same. order_line_list = order.contentValues(portal_type=self.order_line_portal_type) self.assertEqual(len(order_line_list), len(item_list)) for order_line, item in zip(order_line_list, item_list): order_line.setAggregateValueList([item]) def stepCheckOrderLineAggregate(self, sequence=None, sequence_list=None, **kw): """ Check items """ order_line = sequence.get('order_line') self.checkAggregate(line=order_line, sequence=sequence) def stepCheckSimulationAggregate(self, sequence=None, sequence_list=None, **kw): """ Check items """ order_line = sequence.get('order_line') simulation_movement = order_line.getDeliveryRelatedValue() self.assertFalse(simulation_movement is None) self.checkAggregate(line=simulation_movement, sequence=sequence) def stepCheckPackingListLineAggregate(self, sequence=None, sequence_list=None, **kw): """ Check items """ packing_list_line = sequence.get('packing_list_line') self.checkAggregate(line=packing_list_line, sequence=sequence) def stepCheckPackingListLineAggregateList(self, sequence=None, sequence_list=None, **kw): """ Check items """ packing_list_line = sequence.get('packing_list_line') self.checkAggregateList(line=packing_list_line, sequence=sequence) def stepCheckInvoiceLineAggregate(self, sequence=None, sequence_list=None, **kw): """ Check items """ invoice = sequence.get('invoice') invoice_line_list = invoice.contentValues( portal_type=self.invoice_line_portal_type) self.checkAggregate(line=invoice_line_list[0], sequence=sequence) def stepCheckToRender_Delivery_viewAggregatedItemList(self, sequence=None, sequence_list=None, **kw): """Check to render the view""" packing_list = sequence.get('packing_list') packing_list.Delivery_viewAggregatedItemList() def stepCheckPackingListStartDateAfterStartDateAdopt(self,sequence=None, sequence_list=None, **kw): """ Check that start date is adopted. """ packing_list = sequence.get('packing_list') self.assertEqual(packing_list.getStartDate(),self.datetime+15) @UnrestrictedMethod def stepModifyOrderLinesQuantity(self,sequence=None, sequence_list=None, **kw): """ modify order line quantities """ order = sequence.get('order') order_line_list = order.contentValues(portal_type=self.order_line_portal_type) for order_line in order_line_list: order_line.edit(quantity=self.default_quantity-1) @UnrestrictedMethod def stepModifyOneOrderLineStartDate(self,sequence=None, sequence_list=None, **kw): """ modify order line start date """ order = sequence.get('order') resource_list = sequence.get('resource_list') order_line_list = order.contentValues(portal_type=self.order_line_portal_type) self.assertEqual(len(order_line_list),len(resource_list)) order_line_list[-1].edit(start_date=self.datetime+15) @UnrestrictedMethod def stepModifyOrderLinesDate(self,sequence=None, sequence_list=None, **kw): """ modify order line date """ order = sequence.get('order') for order_line in order.contentValues(portal_type=self.order_line_portal_type): order_line.edit(start_date=self.datetime+15) def checkAggregate(self, line=None, sequence=None): """ Check items """ item_list = sequence.get('item_list') self.assertEqual(len(line.getAggregateList()),1) self.assertTrue(item_list[0] in line.getAggregateValueList()) def checkAggregateList(self, line=None, sequence=None): """ Check items """ item_list = self.portal.item_module.contentValues(portal_type='Item') self.assertTrue(line.getAggregateValueList()[0] in item_list) DEFAULT_ITEM_WITH_ORDER_SEQUENCE = \ 'stepCreateEntities \ stepCreateCurrency \ stepCreateItemList \ stepCreateOrder \ stepSetOrderProfile \ stepSetOrderPriceCurrency \ stepCreateNotVariatedResource \ stepTic \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepOrderLineSetAggregationList \ ' DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE = DEFAULT_ITEM_WITH_ORDER_SEQUENCE + '\ stepOrderOrder \ stepTic \ stepConfirmOrder \ stepTic \ stepPackingListBuilderAlarm \ stepTic \ stepCheckOrderRule \ stepCheckOrderLineAggregate \ stepCheckOrderSimulation \ stepCheckSimulationAggregate \ stepCheckDeliveryBuilding \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListLineAggregate \ stepCheckToRender_Delivery_viewAggregatedItemList \ ' DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE_AND_SAME_RESOURCE_LINES = DEFAULT_ITEM_WITH_ORDER_SEQUENCE + '\ stepCreateItemList \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepOrderSetAggregationList \ stepOrderOrder \ stepTic \ stepConfirmOrder \ stepTic \ stepPackingListBuilderAlarm \ stepTic \ stepCheckOrderSimulation \ stepCheckDeliveryBuilding \ stepCheckPackingListIsNotDivergent \ stepCheckOrderPackingList \ stepCheckPackingListLineAggregateList \ ' class TestItem(TestItemMixin, ERP5TypeTestCase): quiet = 0 run_all_test= 1 def getTitle(self): return "Item" def beforeTearDown(self): self.abort() for module in (self.portal.organisation_module, self.portal.item_module, self.portal.sale_packing_list_module, self.portal.purchase_packing_list_module, self.portal.product_module, self.portal.portal_simulation,): module.manage_delObjects(list(module.objectIds())) self.tic() def test_01_ItemSimpleTest(self, quiet=quiet): sequence_list = SequenceList() # Test with a simply order without cell sequence_string = 'stepCreateOrganisation1 \ stepCreateOrganisation2 \ stepCreateOrganisation3 \ stepCreateItemList \ stepCreateOrder \ stepSetOrderProfile \ stepCreateNotVariatedResource \ stepTic \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepOrderLineSetAggregationList \ stepConfirmOrder \ stepTic \ stepPackingListBuilderAlarm \ stepTic \ stepCheckOrderLineAggregate \ stepCheckOrderSimulation \ stepCheckSimulationAggregate \ stepCheckDeliveryBuilding \ stepCheckPackingListLineAggregate \ stepCheckPackingListIsNotDivergent ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_02_ItemWithInvoice(self, quiet=quiet): sequence_list = SequenceList() sequence_string = 'stepCreateEntities \ stepCreateCurrency \ stepCreateItemList \ stepCreateSaleInvoiceTransactionRule \ stepCreateOrder \ stepSetOrderProfile \ stepSetOrderPriceCurrency \ stepCreateNotVariatedResource \ stepTic \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepOrderLineSetAggregationList \ stepConfirmOrder \ stepTic \ stepPackingListBuilderAlarm \ stepTic \ stepCheckOrderRule \ stepCheckOrderLineAggregate \ stepCheckOrderSimulation \ stepCheckSimulationAggregate \ stepCheckDeliveryBuilding \ stepCheckPackingListLineAggregate \ stepAddPackingListContainer \ stepAddPackingListContainerLine \ stepSetContainerLineFullQuantity \ stepTic \ stepCheckPackingListIsPacked \ stepSetReadyPackingList \ stepTic \ stepStartPackingList \ stepCheckInvoicingRule \ stepTic \ stepInvoiceBuilderAlarm \ stepTic \ stepCheckInvoiceBuilding \ stepRebuildAndCheckNothingIsCreated \ stepCheckInvoicesConsistency \ stepCheckInvoiceLineAggregate \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_03_CreateItemsFromPackingListLine(self): organisation = self.createOrganisation(title='Organisation I') self.tic() resource = self.createVariatedResource() # XXX this tests depends on the relative url of the resource self.assertEqual('product_module/1', resource.getRelativeUrl()) self.tic() packing_list = self.createPackingList(resource=resource,organisation=organisation) packing_list_line= self.createPackingListLine(packing_list=packing_list, resource=resource) self.tic() # make sure we can render the dialog packing_list_line.DeliveryLine_viewItemCreationDialog() # create a listbox listbox = ({ 'listbox_key': '000', 'title': 'Lot A', 'reference': '20_05_09_LA', 'quantity': 20.0, 'line_variation_category_list': 'size/product_module/1/3', }, { 'listbox_key': '001', 'title': 'Lot B', 'reference': '20_05_09_LB', 'quantity': 10.0, 'line_variation_category_list': 'size/product_module/1/2', }, { 'listbox_key': '002', 'title': 'Lot C', 'reference': '20_05_09_LC', 'quantity': 15.0, 'line_variation_category_list': 'size/product_module/1/1', }, ) packing_list_line.DeliveryLine_createItemList(type='Item', listbox=listbox) self.tic() self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot A')]) ,1) self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot B')]), 1) self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot C')]), 1) self.assertEqual(packing_list_line.getTotalQuantity(), 45.0) self.assertEqual(sorted(packing_list_line.getVariationCategoryList()), sorted(['size/product_module/1/3', 'size/product_module/1/2', 'size/product_module/1/1'])) self.assertEqual(packing_list_line.getAggregateTitleList(), []) movement_cell_list = packing_list_line.contentValues( portal_type='Purchase Packing List Cell') self.assertEqual(3, len(movement_cell_list)) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/1/3', )) self.assertEqual(cell.getQuantity(), 20) self.assertEqual(['Lot A'], cell.getAggregateTitleList()) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/1/2', )) self.assertEqual(cell.getQuantity(), 10) self.assertEqual(['Lot B'], cell.getAggregateTitleList()) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/1/1', )) self.assertEqual(cell.getQuantity(), 15) self.assertEqual(['Lot C'], cell.getAggregateTitleList()) def test_04_CreateItemsFromPackingListLineWithVariationDefined(self): organisation = self.createOrganisation(title='Organisation II') self.tic() resource = self.createVariatedResource() # XXX this tests depends on the relative url of the resource self.assertEqual('product_module/2', resource.getRelativeUrl()) self.tic() packing_list = self.createPackingList(resource=resource,organisation=organisation) packing_list_line= self.createPackingListLine(packing_list=packing_list, resource=resource) self.tic() # create a listbox listbox = ({ 'listbox_key': '000', 'title': 'Lot A2', 'reference': '25_05_09_LA2', 'quantity': 20.0, 'line_variation_category_list': 'size/product_module/2/3', }, ) packing_list_line.DeliveryLine_createItemList(type='Item', listbox=listbox) self.assertEqual(packing_list_line.getVariationCategoryList(), ['size/product_module/2/3']) self.assertEqual(packing_list_line.getTotalQuantity(), 20) # create listbox a second time listbox = ({ 'listbox_key': '000', 'title': 'Lot B2', 'reference': '25_05_09_LB2', 'quantity': 20.0, 'line_variation_category_list': 'size/product_module/2/1', }, { 'listbox_key': '001', 'title': 'Lot C2', 'reference': '25_05_09_LC2', 'quantity': 15.0, 'line_variation_category_list': 'size/product_module/2/2', }, ) packing_list_line.DeliveryLine_createItemList(type='Item', listbox=listbox) self.tic() self.assertEqual(packing_list_line.getTotalQuantity(), 55.0) self.assertEqual(sorted(packing_list_line.getVariationCategoryList()), sorted(['size/product_module/2/1', 'size/product_module/2/2', 'size/product_module/2/3'])) movement_cell_list = packing_list_line.contentValues( portal_type='Purchase Packing List Cell') self.assertEqual(3, len(movement_cell_list)) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/2/3', )) self.assertEqual(cell.getQuantity(), 20) self.assertEqual(['Lot A2'], cell.getAggregateTitleList()) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/2/1', )) self.assertEqual(cell.getQuantity(), 20) self.assertEqual(['Lot B2'], cell.getAggregateTitleList()) cell = packing_list_line.getCell(base_id='movement', *('size/product_module/2/2', )) self.assertEqual(cell.getQuantity(), 15) self.assertEqual(['Lot C2'], cell.getAggregateTitleList()) def test_05_CreateItemsFromPackingListLineWithNotVariatedResource(self): organisation = self.createOrganisation(title='Organisation III') self.tic() resource = self.createNotVariatedResource() self.tic() packing_list = self.createPackingList(resource=resource, organisation=organisation) packing_list_line= self.createPackingListLine(packing_list=packing_list, resource=resource) packing_list_line.setQuantity(32) self.tic() # create a listbox listbox = ({ 'listbox_key': '000', 'title': 'Lot A3', 'reference': '25_05_09_LA3', 'quantity': 10.0, }, { 'listbox_key': '001', 'title': 'Lot B3', 'reference': '25_05_09_LB3', 'quantity': 5.0, }, { 'listbox_key': '002', 'title': 'Lot C3', 'reference': '25_05_09_LC3', 'quantity': 15.0, }, ) packing_list_line.DeliveryLine_createItemList(type='Item', listbox=listbox) self.tic() self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot A3')]), 1) self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot B3')]), 1) self.assertEqual( len([x.getObject() for x in self.portal.portal_catalog( portal_type='Item', title='Lot C3')]), 1) self.assertEqual(packing_list_line.getQuantity(),30.0) self.assertEqual(packing_list_line.getVariationCategoryList(), []) self.assertEqual(packing_list_line.getAggregateTitleList(), ['Lot A3', 'Lot B3', 'Lot C3']) movement_cell_list = packing_list_line.contentValues( portal_type='Purchase Packing List Cell') self.assertEqual(movement_cell_list,[]) @newSimulationExpectedFailure def test_06_VerifyHavingSameItemTwiceOnMovementCausesNoBug(self): """ """ organisation = self.createOrganisation(title='Organisation VI') self.tic() resource = self.createVariatedResource() # XXX this tests depends on the relative url of the resource self.assertEqual('product_module/4', resource.getRelativeUrl()) self.tic() packing_list = self.createPackingList(resource=resource,organisation=organisation) packing_list_line= self.createPackingListLine(packing_list=packing_list, resource=resource) self.tic() packing_list_line.DeliveryLine_viewItemCreationDialog() # create a listbox listbox = ({ 'listbox_key': '000', 'title': 'Lot A10', 'reference': '1070110000015', 'quantity': 20.0, 'line_variation_category_list': 'size/product_module/4/3' }, ) packing_list_line.DeliveryLine_createItemList(type='Item', listbox=listbox) self.tic() item = [x.getObject() for x in self.portal.portal_catalog( portal_type='Item', reference = '1070110000015' )][0] packing_list_cell_list = packing_list_line.contentValues(portal_type='Purchase Packing List Cell') for packing_list_cell in packing_list_cell_list: packing_list_cell.setAggregateValueList(packing_list_cell.getAggregateValueList()+[item]) self.portal.portal_workflow.doActionFor(packing_list, 'confirm_action') self.assertEqual(packing_list.getSimulationState(), 'confirmed') self.tic() self.assertEqual(packing_list.getCausalityState(),'solved') def test_07_WithPackingListChangePackingListQuantityAndAccept(self, quiet=quiet, run=run_all_test): """ Create order and add items, then Change the quantity on an delivery line, after that see if the packing list is divergent and then split and defer the packing list """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepDecreasePackingListLineQuantity \ stepCheckPackingListIsCalculating \ stepTic \ stepCheckPackingListIsDiverged \ stepSplitAndDeferPackingList \ stepTic \ stepCheckPackingListIsSolved \ stepCheckPackingListSplitted \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_08_ChangePackingListDateAndAccept(self, quiet=quiet, run=run_all_test): """ Create order and add items, then Change the date on an delivery line, after that see if the packing list is divergent and then accept decision on the packing list """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepChangePackingListStartDate \ stepCheckPackingListIsCalculating \ stepTic \ stepCheckPackingListIsDiverged \ stepUnifyStartDateWithDecision \ stepTic \ stepCheckPackingListIsSolved \ stepCheckPackingListIsNotDivergent \ stepCheckSimulationStartDateUpdated \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) @newSimulationExpectedFailure def test_09_ChangeOrderDateAndAcceptOnPackingList(self, quiet=quiet, run=run_all_test): """ Create order and add items, then Change the order date on an order line, after that see if the packing list is divergent and then adopt prevision on the packing list """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepModifyOneOrderLineStartDate \ stepTic \ stepCheckPackingListIsDiverged \ stepCheckPackingListIsDivergent \ stepUnifyStartDateWithPrevision \ stepTic \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListIsSolved \ stepCheckNewPackingListAfterStartDateAdopt \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_10_ChangeOrderQuantityAndAdoptOnPackingList(self, quiet=quiet, run=run_all_test): """ Create order and add items, then Change the quantity on an order line, after that see if the packing list is divergent and then adopt prevision on the packing list """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepModifyOrderLinesQuantity \ stepTic \ stepCheckPackingListIsDiverged \ stepAdoptPrevisionQuantity \ stepTic \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListIsSolved \ stepCheckPackingListLineWithNewQuantityPrevision \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_11_ChangeOrderQuantityAndAcceptOnPackingList(self, quiet=quiet, run=run_all_test): """ Create order and add items, then Change the quantity on an order line, after that see if the packing list is divergent and then accept decision on the packing list """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepModifyOrderLinesQuantity \ stepTic \ stepCheckPackingListIsDiverged \ stepAcceptDecisionQuantity \ stepTic \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListIsSolved \ stepCheckSimulationQuantityUpdated \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) @newSimulationExpectedFailure def test_12_CreteSameResourceDifferentItemOrderLines(self, quiet=quiet, run=run_all_test): """ Create order lines with same resouces and add items into them, then Change the quantity on the order lines, after that see if the packing list is divergent and then adopt prevision on the packing list """ sequence_list = SequenceList() sequence_string = '' sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE_AND_SAME_RESOURCE_LINES + '\ stepModifyOrderLinesQuantity \ stepTic \ stepCheckPackingListIsDiverged \ stepAdoptPrevisionQuantity \ stepTic \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListIsSolved \ stepCheckPackingListLineWithNewQuantityPrevision \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) @newSimulationExpectedFailure def test_13_CreateSameResourceDiffrentItemOrderLinesThenChangeTheOrderLinesDate( self, quiet=quiet, run=run_all_test): sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE_AND_SAME_RESOURCE_LINES + '\ stepModifyOrderLinesDate \ stepTic \ stepCheckPackingListIsDiverged \ stepUnifyStartDateWithPrevision \ stepTic \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListIsSolved \ stepCheckPackingListStartDateAfterStartDateAdopt \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_14_ManuallyAddPackingListWithItem(self, quiet=quiet, run=run_all_test): """ Checks that adding invoice lines and accounting lines to one invoice generates correct simulation """ if not quiet: self.logMessage('Invoice with Manually Added Movements') sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_PACKING_LIST_SEQUENCE + '\ stepSetReadyPackingList \ stepTic \ stepStartPackingList \ stepCheckInvoicingRule \ stepTic \ stepInvoiceBuilderAlarm \ stepTic \ stepCheckInvoiceBuilding \ stepRebuildAndCheckNothingIsCreated \ stepCheckInvoicesConsistency \ stepAddInvoiceLines \ stepTic \ stepStartInvoice \ stepTic \ stepCheckSimulationTrees \ ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_15_ThreeOrderLines(self, quiet=quiet, run=run_all_test): """ Check that item with three order lines. """ sequence_list = SequenceList() sequence_string = self.DEFAULT_ITEM_WITH_ORDER_SEQUENCE + '\ stepCreateItemList \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepCreateItemList \ stepCreateOrderLine \ stepSetOrderLineResource \ stepSetOrderLineDefaultValues \ stepOrderSetAggregationList \ stepTic \ stepOrderOrder \ stepTic \ stepConfirmOrder \ stepTic \ stepPackingListBuilderAlarm \ stepTic \ stepCheckOrderSimulation \ stepCheckDeliveryBuilding \ stepCheckPackingListIsNotDivergent \ stepCheckPackingListLineAggregateList \ stepCheckOrderPackingList ' sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) # Note that: Item with Inventory API tests exsist in # testInventoryModule(tested getInventory) and testInventoryAPI(tested getTrackingList). # # def test_WithInventoryAPI(self): # pass def test_select_item_dialog_no_variation(self): organisation = self.createOrganisation(title='Organisation III') resource = self.createNotVariatedResource() # create one item that is in organisation packing_list = self.createPackingList(resource=resource, organisation=organisation) packing_list.edit(source_section=None, source=None) packing_list_line = self.createPackingListLine(packing_list=packing_list, resource=resource) item = self.portal.item_module.newContent( portal_type='Item', title='Test Item', reference='TI', quantity=12) packing_list_line.setAggregateValue(item) packing_list.confirm() packing_list.stop() self.assertEqual('stopped', packing_list.getSimulationState()) self.tic() packing_list = self.createPackingList(resource=resource, organisation=organisation, portal_type='Internal Packing List') packing_list_line = self.createPackingListLine( packing_list=packing_list, resource=resource, portal_type='Internal Packing List Line') packing_list_line.setQuantity(32) # we can view the dialog packing_list_line.DeliveryLine_viewSelectItemListDialog() # the listbox contains the items physically in the source of the packing # list self.assertEqual([item], packing_list_line.DeliveryLine_getSelectableItemList()) packing_list_line.DeliveryLine_selectItemList( list_selection_name='select_item_fast_input_selection', listbox_uid=(item.getUid(),), uids=(item.getUid(),)) self.assertEqual([item], packing_list_line.getAggregateValueList()) self.assertEqual(12, packing_list_line.getQuantity()) def test_select_item_dialog_variation(self): organisation = self.createOrganisation(title='Organisation IV') resource = self.createVariatedResource() variation_category_list = [ 'size/%s' % variation.getRelativeUrl() for variation in resource.contentValues() ] # create one item that is in organisation packing_list = self.createPackingList(resource=resource, organisation=organisation) packing_list.edit(source_section=None, source=None) packing_list_line = self.createPackingListLine(packing_list=packing_list, resource=resource) packing_list_line.setVariationCategoryList(variation_category_list) variation = variation_category_list[0] cell = packing_list_line.newCell(base_id='movement', *(variation,)) cell.edit(mapped_value_property_list=('quantity,'), quantity=1, variation_category_list=[variation]) item = self.portal.item_module.newContent( portal_type='Item', title='Test Item %s' % variation, reference='TI%s' % variation, quantity=12) cell.setAggregateValue(item) packing_list.confirm() packing_list.stop() self.assertEqual('stopped', packing_list.getSimulationState()) self.tic() packing_list = self.createPackingList(resource=resource, organisation=organisation, portal_type='Internal Packing List') packing_list_line = self.createPackingListLine( packing_list=packing_list, resource=resource, portal_type='Internal Packing List Line') packing_list_line.setQuantity(32) # we can view the dialog packing_list_line.DeliveryLine_viewSelectItemListDialog() # the listbox contains the items physically in the source of the packing # list, and have matching variations self.assertEqual([item], packing_list_line.DeliveryLine_getSelectableItemList()) packing_list_line.DeliveryLine_selectItemList( list_selection_name='select_item_fast_input_selection', listbox_uid=(item.getUid(),), uids=(item.getUid(),)) self.assertEqual([variation], packing_list_line.getVariationCategoryList()) self.assertEqual(12, packing_list_line.getTotalQuantity()) self.assertEqual([], packing_list_line.getAggregateValueList()) self.assertEqual(1, len(packing_list_line.getCellValueList(base_id='movement'))) cell = packing_list_line.getCell(base_id='movement', *(variation, )) self.assertEqual(12, cell.getQuantity()) self.assertEqual([item], cell.getAggregateValueList()) class TestItemScripts(ERP5TypeTestCase): """Test scripts from erp5_item. """ def getBusinessTemplateList(self): return ('erp5_base', 'erp5_pdm', 'erp5_simulation', 'erp5_trade', 'erp5_item', 'erp5_configurator_standard_solver', 'erp5_configurator_standard_trade_template', 'erp5_simulation_test') def afterSetUp(self): self.validateRules() size_category = self.portal.portal_categories.size if 'big' not in size_category.objectIds(): size_category.newContent(portal_type='Category', id='big', title='Big') if 'small' not in size_category.objectIds(): size_category.newContent(portal_type='Category', id='small', title='Small') self.node = self.portal.organisation_module.newContent( portal_type='Organisation', title='Node') self.section = self.portal.organisation_module.newContent( portal_type='Organisation', title='Section') self.mirror_node = self.portal.organisation_module.newContent( portal_type='Organisation', title='Mirror Node') self.mirror_section = self.portal.organisation_module.newContent( portal_type='Organisation', title='Mirror Section') self.product = self.portal.product_module.newContent( portal_type='Product', title='Product') self.variated_product = self.portal.product_module.newContent( portal_type='Product', title='Variated Product', variation_base_category_list=('size',), variation_category_list=('size/big', 'size/small')) self.item = self.portal.item_module.newContent( portal_type='Item', title='Item') self.tic() def beforeTearDown(self): self.abort() for module in (self.portal.organisation_module, self.portal.item_module, self.portal.sale_packing_list_module, self.portal.purchase_packing_list_module, self.portal.product_module, self.portal.portal_simulation,): module.manage_delObjects(list(module.objectIds())) self.tic() @reindex def _makeSalePackingListLine(self, start_date=None): if start_date is None: start_date = DateTime() - 1 packing_list = self.portal.sale_packing_list_module.newContent( portal_type='Sale Packing List', source_value=self.mirror_node, source_section_value=self.mirror_section, destination_value=self.node, destination_section_value=self.section, specialise_value=self.portal.business_process_module.erp5_default_business_process, start_date=start_date,) line = packing_list.newContent( portal_type='Sale Packing List Line', quantity=1, resource_value=self.product, aggregate_value=self.item,) packing_list.confirm() packing_list.start() packing_list.deliver() return line # with line def test_Item_getResourceValue(self): self.assertEqual(None, self.item.Item_getResourceValue()) line = self._makeSalePackingListLine() self.assertEqual(self.product, self.item.Item_getResourceValue()) self.assertEqual(None, self.item.Item_getResourceValue( at_date=DateTime() - 2)) def test_Item_getResourceTitle(self): self.assertEqual(None, self.item.Item_getResourceTitle()) line = self._makeSalePackingListLine() self.assertEqual('Product', self.item.Item_getResourceTitle()) self.assertEqual(None, self.item.Item_getResourceTitle( at_date=DateTime() - 2)) def test_Item_getCurrentOwnerValue(self): self.assertEqual(None, self.item.Item_getCurrentOwnerValue()) line = self._makeSalePackingListLine() self.assertEqual(self.section, self.item.Item_getCurrentOwnerValue()) self.assertEqual(None, self.item.Item_getCurrentOwnerValue(at_date=DateTime() - 2)) def test_Item_getCurrentOwnerTitle(self): self.assertEqual(None, self.item.Item_getCurrentOwnerTitle()) line = self._makeSalePackingListLine() self.assertEqual('Section', self.item.Item_getCurrentOwnerTitle()) self.assertEqual(None, self.item.Item_getCurrentOwnerTitle(at_date=DateTime() - 2)) def test_Item_getCurrentSiteValue(self): self.assertEqual(None, self.item.Item_getCurrentSiteValue()) line = self._makeSalePackingListLine() self.assertEqual(self.node, self.item.Item_getCurrentSiteValue()) self.assertEqual(None, self.item.Item_getCurrentSiteValue( at_date=DateTime() - 2)) def test_Item_getCurrentSiteTitle(self): self.assertEqual(None, self.item.Item_getCurrentSiteTitle()) line = self._makeSalePackingListLine() self.assertEqual('Node', self.item.Item_getCurrentSiteTitle()) self.assertEqual(None, self.item.Item_getCurrentSiteTitle(at_date=DateTime() - 2)) def test_Item_getTrackingList_empty(self): self.assertEqual([], self.item.Item_getTrackingList()) def test_Item_getTrackingList_explanation_brain_attribute(self): line = self._makeSalePackingListLine(start_date=DateTime(2001, 2, 3)) line.setTitle('explanation title') self.tic() history_item, = self.item.Item_getTrackingList() self.assertEqual(DateTime(2001, 2, 3), history_item.date) self.assertEqual('Node', history_item.node_title) self.assertEqual('Mirror Node', history_item.source_title) self.assertEqual('Section', history_item.section_title) self.assertEqual('Product', history_item.resource_title) self.assertEqual('explanation title', history_item.explanation) self.assertEqual('Sale Packing List Line', history_item.translated_portal_type) self.assertEqual(1, history_item.quantity) self.assertEqual(line.absolute_url(), history_item.url) self.assertEqual((), history_item.variation_category_item_list) self.assertEqual('Delivered', history_item.simulation_state) def test_Item_getTrackingList_default_sort(self): # Item_getTrackingList returns lines sorted in chronological order implicit_movement = self.portal.implicit_item_movement_module.newContent( portal_type='Implicit Item Movement', destination_value=self.mirror_node, destination_section_value=self.mirror_section, stop_date=DateTime(2016, 1, 1), aggregate_value=self.item, ) implicit_movement.deliver() self._makeSalePackingListLine(start_date=DateTime(2017, 1, 1)) self.assertEqual( [DateTime(2016, 1, 1), DateTime(2017, 1, 1)], [brain.date for brain in self.item.Item_getTrackingList()]) self.assertEqual( ['Mirror Node', 'Node'], [brain.node_title for brain in self.item.Item_getTrackingList()]) def test_item_current_location_and_transit_movement(self): # a started packing list is still in transit, so we do not know its # current location until it is delivered. # https://lab.nexedi.com/nexedi/erp5/merge_requests/70 implicit_movement = self.portal.implicit_item_movement_module.newContent( portal_type='Implicit Item Movement', destination_value=self.mirror_node, destination_section_value=self.mirror_section, stop_date=DateTime() - 2, aggregate_value=self.item, ) implicit_movement.deliver() packing_list = self.portal.sale_packing_list_module.newContent( portal_type='Sale Packing List', source_value=self.mirror_node, source_section_value=self.mirror_section, destination_value=self.node, destination_section_value=self.section, specialise_value=self.portal.business_process_module.erp5_default_business_process, start_date=DateTime() - 1,) line = packing_list.newContent( portal_type='Sale Packing List Line', quantity=1, resource_value=self.product, aggregate_value=self.item,) packing_list.confirm() self.tic() self.assertEqual(self.mirror_node, self.item.Item_getCurrentSiteValue()) self.assertEqual('Mirror Node', self.item.Item_getCurrentSiteTitle()) self.assertEqual(self.mirror_section, self.item.Item_getCurrentOwnerValue()) self.assertEqual('Mirror Section', self.item.Item_getCurrentOwnerTitle()) packing_list.start() self.tic() # When movement is started, the item is still moving so we do not know it's location / ownership. # In this case we just return None. self.assertEqual(None, self.item.Item_getCurrentSiteValue()) self.assertEqual(None, self.item.Item_getCurrentSiteTitle()) self.assertEqual(None, self.item.Item_getCurrentOwnerValue()) self.assertEqual(None, self.item.Item_getCurrentOwnerTitle()) packing_list.stop() self.tic() self.assertEqual(self.node, self.item.Item_getCurrentSiteValue()) self.assertEqual('Node', self.item.Item_getCurrentSiteTitle()) self.assertEqual(self.section, self.item.Item_getCurrentOwnerValue()) self.assertEqual('Section', self.item.Item_getCurrentOwnerTitle()) # with cells @reindex def _makeSalePackingListCellWithVariation(self): packing_list = self.portal.sale_packing_list_module.newContent( portal_type='Sale Packing List', source_value=self.mirror_node, source_section_value=self.mirror_section, destination_value=self.node, destination_section_value=self.section, specialise_value=self.portal.business_process_module.erp5_default_business_process, start_date=DateTime() - 1,) line = packing_list.newContent( portal_type='Sale Packing List Line', resource_value=self.variated_product,) line.setVariationCategoryList(['size/small']) cell = line.newCell(portal_type='Sale Packing List Cell', base_id='movement', *('size/small',)) cell.edit(mapped_value_property_list=['price','quantity'], quantity=1, variation_category_list=['size/small'], aggregate_value=self.item) packing_list.confirm() packing_list.start() packing_list.deliver() return cell def test_Item_getVariationCategoryList(self): self.assertEqual([], self.item.Item_getVariationCategoryList()) self._makeSalePackingListCellWithVariation() self.assertEqual(['size/small'], self.item.Item_getVariationCategoryList()) self.assertEqual([], self.item.Item_getVariationCategoryList(at_date=DateTime() - 2)) def test_Item_getVariationRangeCategoryItemList(self): self.assertEqual([], self.item.Item_getVariationRangeCategoryItemList()) self._makeSalePackingListCellWithVariation() self.assertEqual([['Big', 'size/big'], ['Small', 'size/small']], self.item.Item_getVariationRangeCategoryItemList()) self.assertEqual([], self.item.Item_getVariationRangeCategoryItemList( at_date=DateTime() - 2)) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestItem)) suite.addTest(unittest.makeSuite(TestItemScripts)) return suite