############################################################################## # # Copyright (c) 2004-2008 Nexedi SA 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. # ############################################################################## from collections import deque import unittest from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod from Products.ERP5.Document.BusinessTemplate import getChainByType from zLOG import LOG from Products.ERP5Type.tests.Sequence import SequenceList from Products.ERP5.tests.testOrder import TestOrderMixin from DateTime import DateTime def getTree(self): tree = [] object_list = deque((self,)) while object_list: self = object_list.popleft() tree.append(self) object_list += self.objectValues() return tree class TestPackingListMixin(TestOrderMixin): """ Test business template erp5_trade """ container_portal_type = 'Container' container_line_portal_type = 'Container Line' container_cell_portal_type = 'Container Cell' default_order_sequence = """ CreateOrganisation1 CreateOrganisation2 CreateOrganisation3 CreateProject1 CreateProject2 CreateOrder CreateCurrency SetOrderPriceCurrency SetOrderProfile """ # Simple order without cell default_sequence = default_order_sequence + """ CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsNotDivergent CheckOrderPackingList """ confirmed_order_without_packing_list = default_order_sequence + """ CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic """ default_sequence_with_duplicated_lines = default_order_sequence + """ CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsNotDivergent CheckOrderPackingList """ default_sequence_with_two_lines = default_order_sequence + """ CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsNotDivergent CheckOrderPackingList """ variated_default_sequence = default_order_sequence + """ CreateVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues SetOrderLineFullVCL CompleteOrderLineMatrix OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsNotDivergent CheckOrderPackingList """ def getTitle(self): return "Packing List" def enableLightInstall(self): """ You can override this. Return if we should do a light install (1) or not (0) """ return 1 def enableActivityTool(self): """ You can override this. Return if we should create (1) or not (0) an activity tool. """ return 1 def stepCheckOrderPackingList(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is matching order """ packing_list = sequence.get('packing_list') order = sequence.get('order') self.assertEqual(packing_list.getCausalityValue(), order) self.assertEqual(packing_list.getSource(), order.getSource()) self.assertEqual(packing_list.getDestination(), order.getDestination()) self.assertEqual(packing_list.getDestinationSection(), order.getDestinationSection()) self.assertEqual(packing_list.getSourceSection(), order.getSourceSection()) self.assertEqual(packing_list.getSourceDecision(), order.getSourceDecision()) self.assertEqual(packing_list.getDestinationAdministration(), order.getDestinationAdministration()) self.assertEqual(packing_list.getSourceAdministration(), order.getSourceAdministration()) self.assertEqual(packing_list.getPriceCurrency(), order.getPriceCurrency()) self.assertEqual(packing_list.getDestinationProject(), order.getDestinationProject()) self.assertEqual(packing_list.getSourceProject(), order.getSourceProject()) def stepCheckPackingListIsDivergent(self, sequence=None, sequence_list=None, packing_list=None,**kw): """ Test if packing list is divergent """ if packing_list is None: packing_list = sequence.get('packing_list') self.assertFalse('Site Error' in packing_list.view()) self.assertTrue(packing_list.isDivergent()) def stepCheckNewPackingListIsDivergent(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is divergent """ packing_list = sequence.get('new_packing_list') self.stepCheckPackingListIsDivergent(packing_list=packing_list,sequence=sequence) def stepCheckPackingListIsCalculating(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is calculating """ packing_list = sequence.get('packing_list') self.assertEqual('calculating',packing_list.getCausalityState()) def stepCheckPackingListIsSolved(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is solved """ packing_list = sequence.get('packing_list') self.assertEqual('solved',packing_list.getCausalityState()) def stepCheckNewPackingListIsSolved(self, sequence=None, sequence_list=None, **kw): packing_list = sequence.get('new_packing_list') self.assertEqual('solved', packing_list.getCausalityState()) def stepCheckPackingListIsDiverged(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is divergent """ packing_list = sequence.get('packing_list') self.assertEqual('diverged', packing_list.getCausalityState()) def stepCheckPackingListIsNotDivergent(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is not divergent """ packing_list = sequence.get('packing_list') self.assertFalse(packing_list.isDivergent()) @UnrestrictedMethod def stepChangeOrderLineResource(self, sequence=None, sequence_list=None, **kw): """ Change the resource of the order. """ order = sequence.get('order') resource = sequence.get('resource') for order_line in order.objectValues( portal_type=self.order_line_portal_type): order_line.edit(resource_value=resource) def stepChangePackingListLineResource(self, sequence=None, sequence_list=None, **kw): """ Change the resource of the packing list. """ packing_list = sequence.get('packing_list') resource = sequence.get('resource') for packing_list_line in packing_list.objectValues( portal_type=self.packing_list_line_portal_type): packing_list_line.edit(resource_value=resource) @UnrestrictedMethod def stepDecreaseOrderLineQuantity(self, sequence=None, sequence_list=None, **kw): """ Set a decreased quantity on order lines """ order = sequence.get('order') quantity = sequence.get('line_quantity', default=self.default_quantity - 1) sequence.edit(line_quantity=quantity) for order_line in order.objectValues( portal_type=self.order_line_portal_type): order_line.edit(quantity=quantity) def stepDecreasePackingListLineQuantity(self, sequence=None, sequence_list=None, **kw): """ Set a decreased quantity on packing list lines """ packing_list = sequence.get('packing_list') quantity = sequence.get('line_quantity',default=self.default_quantity) quantity = quantity - 1 sequence.edit(line_quantity=quantity) for packing_list_line in packing_list.objectValues( portal_type=self.packing_list_line_portal_type): packing_list_line.edit(quantity=quantity) sequence.edit(last_delta = sequence.get('last_delta', 0.0) - 1.0) def stepIncreasePackingListLineQuantity(self, sequence=None, sequence_list=None, **kw): """ Set a increased quantity on packing list lines """ packing_list = sequence.get('packing_list') quantity = sequence.get('line_quantity',default=self.default_quantity) quantity = quantity + 1 sequence.edit(line_quantity=quantity) for packing_list_line in packing_list.objectValues( portal_type=self.packing_list_line_portal_type): packing_list_line.edit(quantity=quantity) sequence.edit(last_delta = sequence.get('last_delta', 0.0) + 1.0) def stepSplitAndDeferPackingList(self, sequence=None, sequence_list=None, **kw): """ Do the split and defer action """ packing_list = sequence.get('packing_list') solver_process_tool = self.portal.portal_solver_processes solver_process = solver_process_tool.newSolverProcess(packing_list) quantity_solver_decision, = [x for x in solver_process.contentValues() if x.getCausalityValue().getTestedProperty() == 'quantity'] # use Quantity Split Solver. quantity_solver_decision.setSolverValue(self.portal.portal_solvers['Quantity Split Solver']) # configure for Quantity Split Solver. kw = {'delivery_solver':'FIFO Delivery Solver', 'start_date':self.datetime + 15, 'stop_date':self.datetime + 25} quantity_solver_decision.updateConfiguration(**kw) solver_process.buildTargetSolverList() solver_process.solve() self.callPackingListBuilderList(packing_list) def stepSplitAndDeferDoNothingPackingList(self, sequence=None, sequence_list=None, **kw): """ Do the solve divrgence action, but choose "do nothing" for divergences """ packing_list = sequence.get('packing_list') solver_process = self.portal.portal_solver_processes.newSolverProcess(packing_list) quantity_solver_decision, = [x for x in solver_process.contentValues() if x.getCausalityValue().getTestedProperty() == 'quantity'] # use no solver quantity_solver_decision.setSolverValue(None) # and no configure quantity_solver_decision.updateConfiguration() solver_process.buildTargetSolverList() solver_process.solve() def stepCheckPackingListSplitted(self, sequence=None, sequence_list=None, **kw): """ Test if packing list was splitted """ packing_list1, packing_list2 = self.getTwoRelatedPackingList(sequence) packing_list1_line, = packing_list1.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(self.default_quantity-1,packing_list1_line.getQuantity()) packing_list2_line, = packing_list2.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(1,packing_list2_line.getQuantity()) def stepCheckPackingListSplittedTwoTimes(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is divergent """ packing_list1, packing_list2 = self.getTwoRelatedPackingList(sequence) packing_list1_line, = packing_list1.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(self.default_quantity-2,packing_list1_line.getQuantity()) packing_list2_line, = packing_list2.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(2,packing_list2_line.getQuantity()) def stepCheckPackingListNotSplitted(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is divergent """ order = sequence.get('order') packing_list_list = order.getCausalityRelatedValueList( portal_type=self.packing_list_portal_type) self.assertEqual(1,len(packing_list_list)) packing_list1 = sequence.get('packing_list') last_delta = sequence.get('last_delta', 0.0) for line in packing_list1.objectValues( portal_type= self.packing_list_line_portal_type): self.assertEqual(self.default_quantity + last_delta, line.getQuantity()) simulation_list = line.getDeliveryRelatedValueList( portal_type='Simulation Movement') self.assertEqual(len(simulation_list),1) simulation_movement = simulation_list[0] self.assertEqual(self.default_quantity + last_delta, simulation_movement.getCorrectedQuantity()) def stepCheckPackingListNotSolved(self, sequence=None, sequence_list=None, **kw): """ This step is specific to test_10 : the incorrectly used solver didn't solve anything. """ order = sequence.get('order') packing_list_list = order.getCausalityRelatedValueList( portal_type=self.packing_list_portal_type) self.assertEqual(1,len(packing_list_list)) packing_list1 = sequence.get('packing_list') last_delta = sequence.get('last_delta', 0.0) for line in packing_list1.objectValues( portal_type= self.packing_list_line_portal_type): self.assertEqual(self.default_quantity + last_delta, line.getQuantity()) simulation_list = line.getDeliveryRelatedValueList( portal_type='Simulation Movement') self.assertEqual(len(simulation_list),1) simulation_movement = simulation_list[0] # Here we don't add last_delta, as the solver didn't do its work. self.assertEqual(self.default_quantity, simulation_movement.getCorrectedQuantity()) def stepChangePackingListDestination(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is divergent """ organisation3 = sequence.get('organisation3') packing_list = sequence.get('packing_list') packing_list.edit(destination_value=organisation3) def stepCreateOrganisation3(self,sequence=None, sequence_list=None, **kw): """ Create a empty organisation """ self.stepCreateOrganisation(sequence=sequence, sequence_list=sequence_list, **kw) organisation = sequence.get('organisation') sequence.edit(organisation3=organisation) def stepCheckSimulationDestinationUpdated(self,sequence=None, sequence_list=None, **kw): """ Test if the destination of the simulation movement was changed """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) org3 = sequence.get('organisation3') for simulation_movement in simulation_movement_list: simulation_movement = simulation_movement.objectValues()[0].objectValues()[0] self.assertEqual(simulation_movement.getDestinationValue(),org3) def stepChangePackingListStartDate(self, sequence=None, sequence_list=None, **kw): """ Change the start_date of the packing_list. """ packing_list = sequence.get('packing_list') packing_list.edit(start_date=self.datetime + 15) def stepCheckSimulationStartDateUpdated(self,sequence=None, sequence_list=None, **kw): """ Test if the start_date of the simulation movement was changed """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) delivery_applied_rule = simulation_movement_list[0].objectValues()[0] simulation_movement_list = delivery_applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) for simulation_movement in simulation_movement_list: self.assertEqual(simulation_movement.getStartDate(),self.datetime + 15) def stepCheckSimulationQuantityUpdated(self,sequence=None, sequence_list=None, **kw): """ Test if the quantity of the simulation movement was changed """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) for simulation_movement in simulation_movement_list: simulation_movement = simulation_movement.objectValues()[0].objectValues()[0] self.assertEqual(simulation_movement.getQuantity() + simulation_movement.getDeliveryError(), self.default_quantity) def stepCheckSimulationQuantityUpdatedForMergedLine(self,sequence=None, sequence_list=None, **kw): """ Test if the quantity of the simulation movement was changed """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),2) for simulation_movement in simulation_movement_list: simulation_movement = simulation_movement.objectValues()[0].objectValues()[0] self.assertEqual(simulation_movement.getQuantity() + simulation_movement.getDeliveryError(), self.default_quantity) def stepEditPackingListLine(self,sequence=None, sequence_list=None, **kw): """ Edits a Packing List Line """ packing_list_line = sequence.get('packing_list_line') packing_list_line.edit(description='This line was edited!') def stepDeletePackingListLine(self,sequence=None, sequence_list=None, **kw): """ Deletes a Packing List Line """ packing_list = sequence.get('packing_list') packing_list_line_id = sequence.get('packing_list_line').getId() packing_list.manage_delObjects([packing_list_line_id]) def stepAddPackingListLine(self,sequence=None, sequence_list=None, **kw): """ Adds a Packing List Line """ packing_list = sequence.get('packing_list') packing_list_line = packing_list.newContent( portal_type=self.packing_list_line_portal_type) self.stepCreateNotVariatedResource(sequence=sequence, sequence_list=sequence_list, **kw) resource = sequence.get('resource') packing_list_line.setResourceValue(resource) packing_list_line.edit(price=100, quantity=200) def stepCheckSimulationConnected(self,sequence=None, sequence_list=None, **kw): """ Check if simulation movement are connected """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) order_line = sequence.get('order_line') packing_list = sequence.get('packing_list') packing_list_line = sequence.get('packing_list_line') for simulation_movement in simulation_movement_list: self.assertEqual(simulation_movement.getDeliveryValue(), order_line) self.assertEqual(packing_list_line.getCausalityValue(), order_line) rule_list = simulation_movement.objectValues() self.assertTrue(len(rule_list), 1) delivering_rule = rule_list[0] self.assertTrue(delivering_rule.getSpecialiseValue().getPortalType(), 'Delivering Rule') child_simulation_movement_list = delivering_rule.objectValues() self.assertTrue(len(child_simulation_movement_list), 1) child_simulation_movement = child_simulation_movement_list[0] self.assertEqual(child_simulation_movement.getDeliveryValue(), packing_list_line) def stepCheckSimulationDisconnected(self,sequence=None, sequence_list=None, **kw): """ Check if simulation movement are disconnected """ applied_rule = sequence.get('applied_rule') simulation_movement_list = applied_rule.objectValues() self.assertEqual(len(simulation_movement_list),1) for simulation_movement in simulation_movement_list: child_simulation_movement = simulation_movement.objectValues()[0].objectValues()[0] self.assertEqual(child_simulation_movement.getDeliveryValue(),None) def stepCheckTwoSimulationLines(self, sequence): """ Check there are exactly two simulation lines related to the packing list line(s) """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) self.assertEqual(len(simulation_movement_list),2) def _getSPLSimulationMovementList(self, sequence): """ Get the simulation movement lines from sales packing list movements """ packing_list = sequence['packing_list'] movement_list = packing_list.getMovementList() simulation_movement_list = [] for movement in movement_list: simulation_movement_list.extend( movement.getDeliveryRelatedValueList() ) return simulation_movement_list def stepModifySimulationLineQuantity(self,sequence=None, sequence_list=None, **kw): """ Modify quantity on simulation lines related to SPL lines """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) for simulation_movement in simulation_movement_list: # we record the property so it doesn't get changed by expand with # the value from a higher simulation level simulation_movement.recordProperty('quantity') simulation_movement.edit(quantity=self.default_quantity-1) #simulation_movement.getDeliveryValue().edit(quantity=self.default_quantity-1) simulation_movement.expand() def stepModifySimulationLineStartDate(self,sequence=None, sequence_list=None, **kw): """ Modify start_date on simulation lines related to SPL lines """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) for simulation_movement in simulation_movement_list: # we record the property so it doesn't get changed by expand with # the value from a higher simulation level simulation_movement.recordProperty('start_date') simulation_movement.edit(start_date=self.datetime+15) simulation_movement.expand() def stepModifyOneSimulationLineStartDate(self,sequence=None, sequence_list=None, **kw): """ Modify start_date on only one simulation line related to SPL lines """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) self.assertEqual(len(simulation_movement_list), len(sequence['resource_list'])) simulation_movement_list[-1].recordProperty('start_date') simulation_movement_list[-1].edit(start_date=self.datetime+15) simulation_movement_list[-1].expand() def stepModifySimulationLineResource(self,sequence=None, sequence_list=None, **kw): """ Modify the resource on simulation lines related to SPL lines """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) resource_list = sequence.get('resource_list') for simulation_movement in simulation_movement_list: simulation_movement.recordProperty('resource') simulation_movement.edit(resource_value=resource_list[-1]) simulation_movement.expand() def stepModifyOneSimulationLineResource(self,sequence=None, sequence_list=None, **kw): """ Modify the resource on only one simulation line related to SPL lines """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) resource_list = sequence.get('resource_list') simulation_movement_list[-1].recordProperty('resource') simulation_movement_list[-1].edit(resource_value=resource_list[-1]) simulation_movement_list[-1].expand() def stepNewPackingListAdoptPrevisionQuantity(self,sequence=None, sequence_list=None, **kw): """ Solve quantity divergence on new_packing_list with 'Adopt Solver' """ packing_list = sequence.get('new_packing_list') self._solveDivergence(packing_list, 'quantity', 'Adopt Solver') def stepAcceptDecisionDestination(self,sequence=None, sequence_list=None, **kw): """ Solve destination divergence on packing_list with 'Adopt Solver' """ packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'destination', 'Accept Solver') def stepUnifyStartDateWithDecision(self,sequence=None, sequence_list=None, **kw): """ Solve start_date divergence on packing_list with the 'Unify Solver', using the start_date of the packing_list. """ packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'start_date', 'Unify Solver', value=packing_list.getStartDate()) def stepUnifyStartDateWithPrevision(self,sequence=None, sequence_list=None, **kw): """ Solve start_date divergence on packing_list with the 'Unify Solver', using the start_date of one of the simulation movements. """ packing_list = sequence.get('packing_list') simulation_movement_list = self._getSPLSimulationMovementList(sequence) self._solveDivergence(packing_list, 'start_date', 'Unify Solver', value=simulation_movement_list[-1].getStartDate()) def stepAcceptDecisionResource(self,sequence=None, sequence_list=None, **kw): packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'resource', 'Accept Solver') def stepAcceptDecisionQuantity(self,sequence=None, sequence_list=None, **kw): packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'quantity', 'Accept Solver') def stepAdoptPrevisionResource(self,sequence=None, sequence_list=None, **kw): packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'resource', 'Adopt Solver') def stepAdoptPrevisionQuantity(self,sequence=None, sequence_list=None, **kw): packing_list = sequence.get('packing_list') self._solveDivergence(packing_list, 'quantity', 'Adopt Solver') def _solveDivergence(self, document, property, solver, **kw): """Solve divergence by using solver tool""" solver_process_tool = self.portal.portal_solver_processes solver_process = solver_process_tool.newSolverProcess(document) solver_decision, = [x for x in solver_process.contentValues() if x.getCausalityValue().getTestedProperty() == property] # use Quantity Accept Solver. solver_decision.setSolverValue(self.portal.portal_solvers[solver]) # configure for Accept Solver. solver_decision.updateConfiguration(tested_property_list=[property], **kw) solver_process.buildTargetSolverList() solver_process.solve() def stepCheckPackingListLineWithNewQuantityPrevision(self,sequence=None, sequence_list=None, **kw): """ Look if the packing list has new previsions """ packing_list_line = sequence.get('packing_list_line') self.assertEqual(packing_list_line.getQuantity(),self.default_quantity-1) def stepCheckPackingListLineWithNewQuantityPrevisionForMergedLine(self,sequence=None, sequence_list=None, **kw): """ Look if the packing list has new previsions """ packing_list_line = sequence.get('packing_list_line') self.assertEqual(packing_list_line.getQuantity(),(self.default_quantity-1)*2) def stepCheckPackingListLineWithNewResource(self,sequence=None, sequence_list=None, **kw): """ Look if the packing list has new resource """ packing_list_line = sequence.get('packing_list_line') new_resource = sequence.get('resource') self.assertEqual(packing_list_line.getQuantity(), self.default_quantity*2) self.assertEqual(packing_list_line.getResourceValue(), new_resource) simulation_line_list = packing_list_line.getDeliveryRelatedValueList() order_line_list = sum([x.getParentValue().getParentValue().getDeliveryList() for x in simulation_line_list], []) self.assertEqual(sorted(packing_list_line.getCausalityList()), sorted(order_line_list)) def stepCheckPackingListLineWithPreviousResource(self, sequence=None): packing_list_line = sequence.get('packing_list_line') old_resource = sequence['resource_list'][-2] self.assertEqual(packing_list_line.getResourceValue(), old_resource) def stepCheckPackingListLineWithSameResource(self,sequence=None, sequence_list=None, **kw): """ Look if the packing list has new previsions """ old_packing_list_line = sequence.get('packing_list_line') packing_list_line = old_packing_list_line.aq_parent[str(int(old_packing_list_line.getId())-1)] resource = sequence.get('resource') for line in sequence.get('packing_list').getMovementList(): self.assertEqual(line.getResourceValue(), resource) self.assertEqual(line.getQuantity(), self.default_quantity) self.assertEqual(line.getCausalityList(), [x.getParentValue().getParentValue().getDelivery() for x in line.getDeliveryRelatedValueList()]) def stepCheckNewPackingListAfterStartDateAdopt(self,sequence=None, sequence_list=None, **kw): """ Check if simulation movement are disconnected """ applied_rule = sequence.get('applied_rule') packing_list_line = sequence.get('packing_list_line') packing_list = sequence.get('packing_list') LOG('CheckNewPackingList, self.datetime+15',0,self.datetime+15) LOG('CheckNewPackingList, packing_list.getStartDate',0,packing_list.getStartDate()) self.assertEqual(packing_list_line.getQuantity(),self.default_quantity) self.assertEqual(packing_list.getStartDate(),self.datetime+15) simulation_movement_list = applied_rule.objectValues() resource_list = sequence.get('resource_list') self.assertEqual(len(simulation_movement_list),len(resource_list)) delivery_value_list = [] for simulation_movement in simulation_movement_list: # self.assertNotEquals(simulation_movement.getDeliveryValue(),None) delivery_value = simulation_movement.getDeliveryValue() if delivery_value not in delivery_value_list: delivery_value_list.append(delivery_value_list) # new_packing_list = delivery_value.getParent() # self.assertNotEquals(new_packing_list.getUid(),packing_list.getUid()) self.assertEqual(len(delivery_value_list),len(resource_list)) def stepCheckNewSplitPackingListAfterStartDateAdopt(self,sequence=None, sequence_list=None, **kw): """ Check if simulation movement are disconnected """ applied_rule = sequence.get('applied_rule') packing_list = sequence.get('packing_list') packing_list_line = [x for x in packing_list.getMovementList() if x.getQuantity()][0] new_packing_list = self.portal.sale_packing_list_module[str(int(packing_list.getId())-1)] new_packing_list_line = [x for x in new_packing_list.getMovementList() if x.getQuantity()][0] self.assertEqual(packing_list_line.getQuantity(),self.default_quantity) self.assertEqual(packing_list.getStartDate(),self.datetime+10) self.assertEqual(new_packing_list_line.getQuantity(),self.default_quantity) self.assertEqual(new_packing_list.getStartDate(),self.datetime+15) simulation_movement_list = applied_rule.objectValues() resource_list = sequence.get('resource_list') self.assertEqual(len(simulation_movement_list),len(resource_list)) delivery_value_list = [] for simulation_movement in simulation_movement_list: # self.assertNotEquals(simulation_movement.getDeliveryValue(),None) delivery_value = simulation_movement.getDeliveryValue() if delivery_value not in delivery_value_list: delivery_value_list.append(delivery_value_list) # new_packing_list = delivery_value.getParent() # self.assertNotEquals(new_packing_list.getUid(),packing_list.getUid()) self.assertEqual(len(delivery_value_list),len(resource_list)) def stepAddPackingListContainer(self,sequence=None, packing_list=None,sequence_list=None, **kw): """ Check if simulation movement are disconnected """ if packing_list is None: packing_list = sequence.get('packing_list') container = packing_list.newContent(portal_type=self.container_portal_type) sequence.edit(container=container) def stepDefineNewPackingListContainer(self,sequence=None, sequence_list=None, **kw): """ Check if simulation movement are disconnected """ packing_list = sequence.get('new_packing_list') self.stepAddPackingListContainer(sequence=sequence,packing_list=packing_list) self.stepAddPackingListContainerLine(sequence=sequence) self.stepSetContainerLineFullQuantity(quantity=1,sequence=sequence) def stepAddPackingListContainerLine(self,sequence=None, sequence_list=None, **kw): """ Add a container line in the packing list """ container = sequence.get('container') container_line = container.newContent(portal_type=self.container_line_portal_type) sequence.edit(container_line=container_line) resource = sequence.get('resource') container_line.edit(resource_value=resource) def stepSetContainerLineSmallQuantity(self,sequence=None, sequence_list=None, **kw): """ Set a small quantity on the container line, it should not be enough for the packing list to be packed. """ container_line = sequence.get('container_line') container_line.edit(quantity=self.default_quantity-1) def stepCheckContainerLineSmallQuantity(self, sequence=None, sequence_list=None, **kw): """ Checks that quantity is set correctly on the container_line. """ container_line = sequence.get('container_line') self.assertEqual(self.default_quantity - 1, container_line.getQuantity()) self.assertEqual(self.default_quantity - 1, container_line.getTotalQuantity()) def stepSetContainerLineFullQuantity(self,sequence=None, sequence_list=None, quantity=None,**kw): """ Set the full quantity """ container_line = sequence.get('container_line') if quantity is None: quantity = sequence.get('line_quantity',self.default_quantity) container_line.edit(quantity=quantity) def stepSetContainerFullQuantity(self,sequence=None, sequence_list=None, quantity=None,**kw): """ Really fills the container """ packing_list = sequence.get('packing_list') container = sequence.get('container') #empty container container.deleteContent(container.contentIds()) for line in packing_list.objectValues( portal_type=self.packing_list_line_portal_type): resource = line.getResourceValue() container_line = \ container.newContent(portal_type=self.container_line_portal_type) container_line.setResourceValue(resource) # without variation if not line.hasCellContent(): quantity = line.getQuantity() container_line.edit(quantity=quantity) self.assertEqual(quantity, container_line.getQuantity()) self.assertEqual(quantity, container_line.getTotalQuantity()) # with variation elif line.hasCellContent(): vcl = line.getVariationCategoryList() vcl.sort() base_id = 'movement' container_line.setVariationCategoryList(vcl) cell_key_list = list(line.getCellKeyList(base_id=base_id)) cell_key_list.sort() for cell_key in cell_key_list: if line.hasCell(base_id=base_id, *cell_key): old_cell = line.getCell(base_id=base_id, *cell_key) cell = container_line.newCell(base_id=base_id, portal_type=self.container_cell_portal_type, *cell_key) cell.edit(mapped_value_property_list=['price', 'quantity'], price=old_cell.getPrice(), quantity=old_cell.getQuantity(), predicate_category_list=cell_key, variation_category_list=cell_key) self.assertEqual(old_cell.getQuantity(), cell.getQuantity()) self.assertEqual(old_cell.getTotalQuantity(), cell.getTotalQuantity()) self.assertEqual(line.getQuantity(), container_line.getQuantity()) self.assertEqual(line.getTotalQuantity(), container_line.getTotalQuantity()) # quantity is 1 on the container itself self.assertEqual(1, container.getQuantity()) self.assertEqual(1, container.getTotalQuantity()) def stepCheckPackingListIsNotPacked(self,sequence=None, sequence_list=None, **kw): """ Check that the number of objects in containers are not equals to the quantity of the packing list """ packing_list = sequence.get('packing_list') self.assertFalse(packing_list.isPacked()) self.assertEqual('missing', packing_list.getContainerState()) def stepCheckPackingListIsPacked(self,sequence=None, sequence_list=None, packing_list=None,**kw): """ Check that the number of objects in containers are equals to the quantity of the packing list """ if packing_list is None: packing_list = sequence.get('packing_list') self.commit() self.assertTrue(packing_list.isPacked()) self.assertEqual('packed', packing_list.getContainerState()) def stepCheckNewPackingListIsPacked(self,sequence=None, sequence_list=None, **kw): """ Check that the number of objects in containers are equals to the quantity of the packing list """ packing_list = sequence.get('new_packing_list') self.stepCheckPackingListIsPacked(sequence=sequence, packing_list=packing_list) def stepCreateCurrency(self, sequence, **kw) : """Create a default currency. """ currency_module = self.getCurrencyModule() if currency_module._getOb('EUR', None) is None: currency = self.getCurrencyModule().newContent( portal_type='Currency', id="EUR", base_unit_quantity=0.01, ) else: currency = currency_module._getOb('EUR') sequence.edit(currency=currency) def stepSetOrderPriceCurrency(self, sequence, **kw) : """Set the price currency of the order. This step is not necessary. TODO : - include a test without this step. - include a test with this step late. """ currency = sequence.get('currency') order = sequence.get('order') order.setPriceCurrency(currency.getRelativeUrl()) def _checkRecordedProperty(self, movement_list, property_id, assertion): for movement in movement_list: for simulation_movement in movement.getDeliveryRelatedValueList(): if assertion: self.assertTrue(simulation_movement.isPropertyRecorded(property_id)) else: self.assertFalse(simulation_movement.isPropertyRecorded(property_id)) def stepCheckSimulationMovementHasRecordedQuantity(self, sequence=None, sequence_list=None): movement_list = sequence.get('packing_list').objectValues( portal_type=self.packing_list_line_portal_type) self._checkRecordedProperty(movement_list, 'quantity', True) def stepCheckSimulationMovementHasNoRecordedQuantity(self, sequence=None, sequence_list=None): movement_list = sequence.get('packing_list').objectValues( portal_type=self.packing_list_line_portal_type) self._checkRecordedProperty(movement_list, 'quantity', False) def stepCheckSimulationMovementHasRecordedResource(self, sequence=None, sequence_list=None): movement_list = sequence.get('packing_list').objectValues( portal_type=self.packing_list_line_portal_type) self._checkRecordedProperty(movement_list, 'resource', True) def stepCheckSimulationMovementHasNoRecordedResource(self, sequence=None, sequence_list=None): movement_list = sequence.get('packing_list').objectValues( portal_type=self.packing_list_line_portal_type) self._checkRecordedProperty(movement_list, 'resource', False) def callPackingListBuilderList(self, packing_list): # build split deliveries manually. XXX ad-hoc previous_tag = None for delivery_builder in packing_list.getBuilderList(): after_tag = [] if previous_tag: after_tag.append(previous_tag) delivery_builder.activate( after_method_id=('solve', 'immediateReindexObject'), # XXX too brutal. after_tag=after_tag, ).build(explanation_uid=packing_list.getCausalityValue().getUid()) def stepMergeSplittedPackingList(self, sequence=None): """ Invoke the merge of the two sales packing list and check the merged packing list Then also try to create a packing list not coming from order, and then tro to merge it with the merged packing list """ # Merge the two existing packing list packing_list1 = sequence.get('packing_list') packing_list2 = sequence.get('new_packing_list') self.portal.portal_simulation.mergeDeliveryList([packing_list1, packing_list2]) self.tic() self.assertEqual('confirmed', packing_list1.getSimulationState()) self.assertEqual('cancelled', packing_list2.getSimulationState()) line, = packing_list1.objectValues( portal_type= self.packing_list_line_portal_type) self.assertEqual(self.default_quantity,line.getQuantity()) self.assertTrue(packing_list1.getStartDate() is not None) self.assertTrue(packing_list1.getStopDate() is not None) # Now clone the merged packing list, so that we will have : # - one packing list coming from order (merged_packing_list) # - one not coming from order (the cloned one) cloned_packing_list = packing_list1.Base_createCloneDocument(batch_mode=True) cloned_packing_list.setStartDate(cloned_packing_list.getStartDate() + 1) cloned_packing_list.setStopDate(cloned_packing_list.getStopDate() + 1) cloned_line, = cloned_packing_list.objectValues() cloned_line.setQuantity(self.default_quantity+1) self.portal.portal_workflow.doActionFor(cloned_packing_list, "confirm_action") self.tic() self.portal.portal_simulation.mergeDeliveryList([packing_list1, cloned_packing_list]) self.tic() self.assertEqual('confirmed', packing_list1.getSimulationState()) self.assertEqual('cancelled', cloned_packing_list.getSimulationState()) resource = sequence.get('resource').getRelativeUrl() def checkLineSet(delivery, expected_set): line_list = delivery.getMovementList() self.assertEqual(len(line_list), len(expected_set)) found_set = set([(x.getResource(), x.getQuantity(), x.getPrice()) for x in line_list]) expected_set = set([(resource, self.default_quantity, 555), (resource, self.default_quantity+1, 555)]) checkLineSet(packing_list1, expected_set) class TestPackingList(TestPackingListMixin, ERP5TypeTestCase) : run_all_test = 1 quiet = 0 def test_01_PackingListDecreaseQuantity(self, quiet=quiet, run=run_all_test): """ Change the quantity on an delivery line, then see if the packing list is divergent and then split and defer the packing list Finally, check we can merge if needed """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsSolved CheckPackingListSplitted MergeSplittedPackingList """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_02_PackingListChangeDestination(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ ChangePackingListDestination CheckPackingListIsCalculating Tic CheckPackingListIsDiverged AcceptDecisionDestination Tic CheckPackingListIsSolved CheckPackingListIsNotDivergent CheckSimulationDestinationUpdated """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_03_PackingListChangeStartDate(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ ChangePackingListStartDate CheckPackingListIsCalculating Tic CheckPackingListIsDiverged UnifyStartDateWithDecision Tic CheckPackingListIsSolved CheckPackingListIsNotDivergent CheckSimulationStartDateUpdated """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_04_PackingListDeleteLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ CheckSimulationConnected DeletePackingListLine CheckPackingListIsNotDivergent Tic CheckSimulationDisconnected """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05_SimulationChangeQuantity(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ ModifySimulationLineQuantity Tic CheckPackingListIsDiverged AdoptPrevisionQuantity Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckPackingListLineWithNewQuantityPrevision """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05a_SimulationChangeQuantityAndAcceptDecision(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ ModifySimulationLineQuantity Tic CheckPackingListIsDiverged AcceptDecisionQuantity Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckSimulationQuantityUpdated """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05b_SimulationChangeQuantityForMergedLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_duplicated_lines + """ CheckTwoSimulationLines ModifySimulationLineQuantity Tic CheckPackingListIsDiverged AdoptPrevisionQuantity Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckPackingListLineWithNewQuantityPrevisionForMergedLine """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05c_SimulationChangeQuantityAndAcceptDecisionForMergedLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_duplicated_lines + """ CheckTwoSimulationLines ModifySimulationLineQuantity Tic CheckPackingListIsDiverged AcceptDecisionQuantity Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckSimulationQuantityUpdatedForMergedLine """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05d_SimulationChangeResourceOnOneSimulationMovementForMergedLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_duplicated_lines + """ CreateNotVariatedResource ModifyOneSimulationLineResource Tic CheckPackingListIsDiverged AdoptPrevisionResource Tic # Trying to Solve the divergence above with one simulation # movement changes the resource CheckPackingListLineWithNewResource # but doesn't solve the divergence as it is now divergent with the # other simulation movement CheckPackingListIsDiverged # solving again reverts the value. AdoptPrevisionResource Tic CheckPackingListLineWithPreviousResource # but now the packing list is divergent with the previous # simulation movement CheckPackingListIsDiverged # We have to chose one of them and accept the decision AcceptDecisionResource Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05e_SimulationUnifyResourceOnSimulationMovementsForNonMergedLines(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_two_lines + """ ModifySimulationLineResource Tic CheckPackingListIsDiverged AdoptPrevisionResource Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckPackingListLineWithSameResource """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05f_SimulationChangeAndPartialAcceptDecision(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_duplicated_lines + """ CreateNotVariatedResource CheckTwoSimulationLines ModifySimulationLineQuantity ModifyOneSimulationLineResource ModifySimulationLineStartDate Tic CheckPackingListIsDiverged AcceptDecisionQuantity Tic CheckPackingListIsDiverged AcceptDecisionResource Tic CheckPackingListIsDiverged UnifyStartDateWithDecision Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckSimulationQuantityUpdatedForMergedLine """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_05g_SimulationAfterCloningLine(self): sequence_list = SequenceList() sequence_string = self.default_sequence sequence_list.addSequenceString(sequence_string) sequence_list.play(self) sequence = sequence_list.getSequenceList()[0] packing_list = sequence.get('packing_list') self.assertEqual(None, packing_list.getCausalityRelatedValue( portal_type="Applied Rule")) line, = packing_list.getMovementList() line.Base_createCloneDocument(batch_mode=True) self.assertEqual('calculating', packing_list.getCausalityState()) self.tic() self.assertEqual('solved', packing_list.getCausalityState()) applied_rule = packing_list.getCausalityRelatedValue( portal_type="Applied Rule") self.assertNotEqual(None, applied_rule) self.assertEqual(1, len(applied_rule.objectValues())) # create new line and check simulation has it line.Base_createCloneDocument(batch_mode=True) self.assertEqual('calculating', packing_list.getCausalityState()) self.tic() self.assertEqual('solved', packing_list.getCausalityState()) self.assertEqual(2, len(applied_rule.objectValues())) def stepModifySimulationMovementWithOppositeQuantities(self,sequence=None, sequence_list=None, **kw): """ Make simulation movement having opposite quantities """ simulation_movement_list = self._getSPLSimulationMovementList(sequence) new_quantity_list = [self.default_quantity, -self.default_quantity] for index, simulation_movement in enumerate(simulation_movement_list): # we record the property so it doesn't get changed by expand with # the value from a higher simulation level simulation_movement.recordProperty('quantity') simulation_movement.edit(quantity=new_quantity_list[index]) simulation_movement.expand() def stepCheckPackingListLineHavingQuantityZero(self,sequence=None, sequence_list=None, **kw): """ Look if the packing list has new previsions """ packing_list_line = sequence.get('packing_list_line') self.assertEqual(packing_list_line.getQuantity(), 0) def test_05h_SimulationAdoptPrevisionOnAMergeLineHavingQuantityZero(self): """ In some cases, we might have several simulation movements that makes a total quantity of zero. Make sure Adopt Solver works fine in such case """ sequence_list = SequenceList() sequence_string = self.default_sequence_with_duplicated_lines + """ CheckTwoSimulationLines ModifySimulationMovementWithOppositeQuantities Tic CheckPackingListIsDiverged AdoptPrevisionQuantity Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckPackingListLineHavingQuantityZero """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self) def test_06_SimulationChangeStartDate(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ ModifySimulationLineStartDate Tic CheckPackingListIsDiverged UnifyStartDateWithPrevision Tic CheckPackingListIsSolved CheckNewPackingListAfterStartDateAdopt """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_07_SimulationChangeStartDateWithTwoOrderLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_two_lines + """ ModifySimulationLineStartDate Tic CheckPackingListIsDiverged CheckPackingListIsDivergent UnifyStartDateWithPrevision Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckNewPackingListAfterStartDateAdopt """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_07a_SimulationChangeStartDateWithTwoOrderLine(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence_with_two_lines + """ ModifyOneSimulationLineStartDate Tic CheckPackingListIsDiverged CheckPackingListIsDivergent UnifyStartDateWithPrevision Tic CheckPackingListIsNotDivergent CheckPackingListIsSolved CheckNewPackingListAfterStartDateAdopt """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_08_AddContainers(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ AddPackingListContainer AddPackingListContainerLine SetContainerLineSmallQuantity CheckContainerLineSmallQuantity CheckPackingListIsNotPacked SetContainerFullQuantity Tic CheckPackingListIsPacked """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_09_AddContainersWithVariatedResources(self, quiet=quiet, run=run_all_test): if not run: return sequence_list = SequenceList() # Test with a order with cells sequence_string = self.variated_default_sequence + """ AddPackingListContainer AddPackingListContainerLine SetContainerLineSmallQuantity CheckContainerLineSmallQuantity CheckPackingListIsNotPacked SetContainerFullQuantity Tic CheckPackingListIsPacked ModifySimulationLineStartDate Tic CheckPackingListIsDiverged CheckPackingListIsDivergent UnifyStartDateWithPrevision Tic """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_10_PackingListIncreaseQuantity(self, quiet=quiet, run=run_all_test): """ - Increase the quantity on an delivery line - check if the packing list is divergent - Apply the "split and defer" solver to the packing list - check that nothing was splitted and the packing list is still divergent (reset the delta before, as we don't expect a modification) Basically, when we apply "split and defer" to a packing list, we don't want it to modify lines which have been increased. """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ IncreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsDiverged CheckPackingListIsDivergent CheckPackingListNotSolved """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_11_PackingListDecreaseTwoTimesQuantityAndUpdateDelivery(self, quiet=quiet, run=run_all_test): """ Change the quantity on an delivery line, then see if the packing list is divergent and then split and defer the packing list """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsSolved CheckPackingListSplitted DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckNewPackingListIsDivergent NewPackingListAdoptPrevisionQuantity Tic CheckPackingListIsSolved CheckNewPackingListIsSolved CheckPackingListSplittedTwoTimes """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def stepDeliverPackingList(self, sequence=None, sequence_list=None, **kw): """ Deliver Packing List """ packing_list = sequence.get('packing_list') packing_list.stop() packing_list.deliver() def stepDeliverNewPackingList(self, sequence=None, sequence_list=None, **kw): """ Deliver New Packing List """ packing_list = sequence.get('new_packing_list') packing_list.stop() packing_list.deliver() def stepCheckExpandOrderRootAppliedRuleIsStable(self, sequence=None, sequence_list=None, **kw): """ Check Order Applied Rule can be expanded without error """ order = sequence.get('order') related_applied_rule_list = order.getCausalityRelatedValueList( \ portal_type=self.applied_rule_portal_type) applied_rule = related_applied_rule_list[0].getObject() before = set(getTree(applied_rule)) applied_rule.expand("immediate") after = getTree(applied_rule) self.assertTrue(before.issubset(after)) for element in after: if element in before: if (element.getPortalType() == 'Simulation Movement' and element.getDelivery() and element.getParentValue().getSpecialiseValue().getPortalType() != 'Order Root Simulation Rule'): self.assertFalse(element.getDivergenceList()) else: if element.getPortalType() == 'Simulation Movement': element = element.getParentValue() self.assertNotIn(element, before) def test_11_02_PackingListDecreaseTwoTimesQuantityAndUpdateDeliveryAndDeliver(self, quiet=quiet, run=run_all_test): """ Change the quantity on an delivery line, then see if the packing list is divergent and then split and defer the packing list. Deliver Packing Lists and make sure the root can be expanded """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsSolved CheckPackingListSplitted DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckNewPackingListIsDivergent NewPackingListAdoptPrevisionQuantity Tic CheckPackingListIsSolved CheckNewPackingListIsSolved CheckPackingListSplittedTwoTimes DeliverPackingList DeliverNewPackingList Tic CheckExpandOrderRootAppliedRuleIsStable """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def stepSplitAndMovePackingList(self, sequence=None, sequence_list=None, **kw): """ Do the split and move to another delivery action """ packing_list = sequence.get('packing_list') new_packing_list = sequence.get('new_packing_list') solver_process_tool = self.portal.portal_solver_processes solver_process = solver_process_tool.newSolverProcess(packing_list) quantity_solver_decision, = [x for x in solver_process.contentValues() if 'quantity' in x.getCausalityValue().getTestedPropertyList()] # use Quantity Split Solver. quantity_solver_decision.setSolverValue(self.portal.portal_solvers['Quantity Split Move Solver']) # configure for Quantity Split Solver. kw = {'delivery_solver':'FIFO Delivery Solver', 'delivery_url': new_packing_list.getRelativeUrl()} quantity_solver_decision.updateConfiguration(**kw) solver_process.buildTargetSolverList() solver_process.solve() def stepCheckSeveralDivergenceAction(self, sequence=None, sequence_list=None, **kw): """ Do the split and move to another delivery action """ packing_list1 = sequence.get('packing_list') line1, = packing_list1.objectValues(portal_type=self.packing_list_line_portal_type) packing_list2 = sequence.get('new_packing_list') # Make sure we can split and defer the new packing list, this would make # use of FIFO delivery solver in the case we have several lines line2, = packing_list2.objectValues(portal_type=self.packing_list_line_portal_type) line2.setQuantity(1.5) self.tic() self.assertEqual('diverged', packing_list2.getCausalityState()) solver_process, = [x for x in packing_list2.getSolverValueList() if \ x.getValidationState() == "draft"] quantity_solver_decision, = [x for x in solver_process.contentValues() if 'quantity' in x.getCausalityValue().getTestedPropertyList()] # use Quantity Split Solver. quantity_solver_decision.setSolverValue(self.portal.portal_solvers['Quantity Split Solver']) # configure for Quantity Split Solver. kw = {'delivery_solver':'FIFO Delivery Solver', 'start_date':self.datetime + 35, 'stop_date':self.datetime + 45} quantity_solver_decision.updateConfiguration(**kw) solver_process.buildTargetSolverList() solver_process.solve() self.callPackingListBuilderList(packing_list2) self.tic() packing_list1, packing_list2, packing_list3 = self.getCreatedTypeList( self.packing_list_portal_type) line3, = packing_list3.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(0.5, line3.getQuantity()) self.assertEqual('solved', packing_list1.getCausalityState()) self.assertEqual('solved', packing_list2.getCausalityState()) self.assertEqual('solved', packing_list3.getCausalityState()) # And now make sure we could accept a new quantity in case we have several # simulation movements line2.setQuantity(1.2) self.tic() self.assertEqual('diverged', packing_list2.getCausalityState()) solver_process, = [x for x in packing_list2.getSolverValueList() if \ x.getValidationState() == "draft"] quantity_solver_decision, = [x for x in solver_process.contentValues() if 'quantity' in x.getCausalityValue().getTestedPropertyList()] # use Quantity Split Solver. quantity_solver_decision.setSolverValue(self.portal.portal_solvers['Accept Solver']) kw = {'tested_property_list':['quantity']} quantity_solver_decision.updateConfiguration(**kw) solver_process.buildTargetSolverList() solver_process.solve() self.callPackingListBuilderList(packing_list2) self.tic() packing_list1, packing_list2, packing_list3 = self.getCreatedTypeList( self.packing_list_portal_type) self.assertEqual('solved', packing_list1.getCausalityState()) self.assertEqual('solved', packing_list2.getCausalityState()) self.assertEqual('solved', packing_list3.getCausalityState()) self.assertEqual(self.default_quantity-2, line1.getQuantity()) self.assertEqual(1.2, line2.getQuantity()) self.assertEqual(0.5, line3.getQuantity()) def test_11b_PackingListDecreaseTwoTimesQuantityAndMoveToDelivery(self, quiet=quiet, run=run_all_test): """ Change the quantity on an delivery line, then split and defer the packing list. Then decrease again the quantity, and use solver "split and move" to move the quantity to the second packing list. The second packing list would be solved by the "split and move" solver """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsSolved CheckPackingListSplitted DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndMovePackingList Tic CheckNewPackingListIsSolved CheckPackingListSplittedTwoTimes CheckSeveralDivergenceAction """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_SplitAndDeferDoNothing(self, quiet=quiet, run=run_all_test): """ Use split & defer to solve a divergence, but choose do nothing for all lines. """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ IncreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferDoNothingPackingList Tic CheckPackingListIsDiverged CheckPackingListIsDivergent CheckPackingListNotSolved """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_12_PackingListLineChangeResource(self, quiet=quiet, run=run_all_test): """ Test if delivery diverged when we change the resource. """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ CreateNotVariatedResource ChangePackingListLineResource CheckPackingListIsCalculating Tic CheckPackingListIsDivergent """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_14_PackingListHavePriceCurrencyCategory(self, quiet=quiet, run=run_all_test): """Deliveries must have a price currency category. #252 """ if not run: return pl = self.getPortal().getDefaultModule(self.packing_list_portal_type ).newContent(portal_type=self.packing_list_portal_type) self.assertTrue(hasattr(pl, 'getPriceCurrency')) def test_PackingList_viewAsODT(self): # tests packing list printout resource = self.portal.getDefaultModule( self.resource_portal_type).newContent( portal_type=self.resource_portal_type, title='Resource',) client = self.portal.organisation_module.newContent( portal_type='Organisation', title='Client') vendor = self.portal.organisation_module.newContent( portal_type='Organisation', title='Vendor') packing_list = self.portal.getDefaultModule(self.packing_list_portal_type).newContent( portal_type=self.packing_list_portal_type, title='Packing List', specialise=self.business_process, source_value=vendor, source_section_value=vendor, destination_value=client, destination_section_value=client) line = packing_list.newContent( portal_type=self.packing_list_line_portal_type, resource_value=resource, quantity=10, price=3) packing_list.confirm() self.tic() odt = packing_list.PackingList_viewAsODT() from Products.ERP5OOo.tests.utils import Validator odf_validator = Validator() err_list = odf_validator.validate(odt) if err_list: self.fail(''.join(err_list)) def test_15_CheckBuilderCanBeCalledTwiceSafely(self): """ Builder design should allows to call the build method as many times as we want. Make sure that we will not have duplicated packing list if build is called several times. """ delivery_builder = getattr(self.getPortalObject().portal_deliveries, self.delivery_builder_id) def doNothing(self, *args, **kw): pass original_delivery_builder_build = delivery_builder.__class__.build try: # We patch the delivery builder to make sure that it will not be # called by activities delivery_builder.__class__.build = doNothing sequence_list = SequenceList() sequence_string = self.confirmed_order_without_packing_list sequence_list.addSequenceString(sequence_string) sequence_list.play(self) # Now restore the build method and make sure first call returns document delivery_builder.__class__.build = original_delivery_builder_build self.assertTrue(len(delivery_builder.build()) > 0) # The second call should returns empty result even if tic not called self.assertTrue(len(delivery_builder.build()) == 0) finally: delivery_builder.build = original_delivery_builder_build def test_16_simulation_reindexation_on_cancel(self): self.organisation_portal_type = 'Organisation' self.resource_portal_type = 'Product' packing_list_module = self.portal.getDefaultModule( portal_type=self.packing_list_portal_type) organisation_module = self.portal.getDefaultModule( portal_type=self.organisation_portal_type) resource_module = self.portal.getDefaultModule( portal_type=self.resource_portal_type) source = organisation_module.newContent( portal_type=self.organisation_portal_type) destination = organisation_module.newContent( portal_type=self.organisation_portal_type) resource = resource_module.newContent( portal_type=self.resource_portal_type) packing_list = packing_list_module.newContent( portal_type=self.packing_list_portal_type, source_value=source, destination_value=destination, specialise=self.business_process, start_date=DateTime()) packing_list_line = packing_list.newContent( portal_type=self.packing_list_line_portal_type, resource_value=resource, quantity=1) packing_list.confirm() self.tic() self.assertEqual('confirmed', packing_list.getSimulationState()) simulation_movement = packing_list_line.getDeliveryRelatedValue( portal_type='Simulation Movement') self.assertEqual('confirmed', simulation_movement.getSimulationState()) packing_list.cancel() self.tic() self.assertEqual('cancelled', packing_list.getSimulationState()) self.assertEqual('cancelled', simulation_movement.getSimulationState()) def stepCreateSourceAccount(self, sequence=None, **kw): organisation = self.stepCreateOrganisation(sequence, None, 'dummy_source') sequence.edit(source_account = sequence.get('dummy_source')['bank']) def stepCreateDestinationAccount(self, sequence=None, **kw): organisation = self.stepCreateOrganisation(sequence, None, 'dummy_destination') sequence.edit(destination_account = sequence.get('dummy_destination') ['bank']) def stepSetOrderLineSourceAccount(self, sequence=None, **kw): order_line = sequence.get('order_line') account = sequence.get('source_account') self.assertNotEqual(None, account) order_line.setSourceAccountValue(account) def stepSetOrderLineDestinationAccount(self, sequence=None, **kw): order_line = sequence.get('order_line') account = sequence.get('destination_account') self.assertNotEqual(None, account) order_line.setDestinationAccountValue(account) def stepCheckPackingListLineSourceAccount(self, sequence=None, **kw): packing_list = sequence.get('packing_list') account = sequence.get('source_account') for line in packing_list.getMovementList(): self.assertEqual(line.getSourceAccountValue(), account) def stepCheckPackingListLineDestinationAccount(self, sequence=None, **kw): packing_list = sequence.get('packing_list') account = sequence.get('destination_account') for line in packing_list.getMovementList(): self.assertEqual(line.getDestinationAccountValue(), account) def test_17_PackingListOrderLineWithAccount(self, quiet=quiet): """ Check how packing list behaves if comes from order line which has source/destination account set. """ sequence_list = SequenceList() sequence_string = self.default_order_sequence + """ CreateNotVariatedResource CreateSourceAccount CreateDestinationAccount Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues SetOrderLineSourceAccount SetOrderLineDestinationAccount OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsSolved CheckOrderPackingList CheckPackingListLineSourceAccount CheckPackingListLineDestinationAccount """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_18_ChangeQuantityOnPackingListAndOrder(self, quiet=quiet): """ Change the quantity on a packing list line, and accept the divergence, then change the quantity on an order line to the same value and check if it does not cause divergence on a packing list line and recorded properties are reset after re-expand. """ sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity Tic CheckPackingListIsDiverged AcceptDecisionQuantity Tic CheckPackingListIsSolved CheckSimulationMovementHasRecordedQuantity DecreaseOrderLineQuantity Tic CheckPackingListIsSolved CheckSimulationMovementHasNoRecordedQuantity """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_19_ChangeResourceOnPackingListAndOrder(self, quiet=quiet): """ Change the resource on a packing list line, and accept the divergence, then change the resource on an order line to the same value and check if it does not cause divergence on a packing list line and recorded properties are reset after re-expand. """ sequence_list = SequenceList() sequence_string = self.default_sequence + """ CreateNotVariatedResource ChangePackingListLineResource Tic CheckPackingListIsDiverged AcceptDecisionResource Tic CheckPackingListIsSolved CheckSimulationMovementHasRecordedResource ChangeOrderLineResource Tic CheckPackingListIsSolved CheckSimulationMovementHasNoRecordedResource """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_subcontent_reindexing_packing_list_line_cell(self): """Tests, that indexation of Packing List are propagated to subobjects during reindxation""" packing_list = self.portal.getDefaultModule( self.packing_list_portal_type).newContent( portal_type=self.packing_list_portal_type) packing_list_line = packing_list.newContent( portal_type=self.packing_list_line_portal_type) packing_list_cell = packing_list_line.newContent( portal_type=self.packing_list_cell_portal_type) self._testSubContentReindexing(packing_list, [packing_list_line, packing_list_cell]) def test_subcontent_reindexing_packing_list_container_line_cell(self): """Tests, that indexation of Packing List are propagated to subobjects during reindxation, for Container, Container Line and Container Cell""" packing_list = self.portal.getDefaultModule( self.packing_list_portal_type).newContent( portal_type=self.packing_list_portal_type) container = packing_list.newContent( portal_type=self.container_portal_type) container_line = container.newContent( portal_type=self.container_line_portal_type) container_cell = container_line.newContent( portal_type=self.container_cell_portal_type) self._testSubContentReindexing(packing_list, [container, container_line, container_cell]) def test_PackingList_getMovementListSorting(self): '''Test that is possible to sort getMovementList result passing it sort_on parameter ''' packing_list = self.portal.getDefaultModule(self.packing_list_portal_type).newContent( portal_type=self.packing_list_portal_type, title='Packing List') # create some packing list lines line_bbb = packing_list.newContent( portal_type=self.packing_list_line_portal_type, reference='bbb', int_index=1) line_bbb_cell_bbb = line_bbb.newContent( portal_type=self.packing_list_cell_portal_type, reference='bbb', int_index=2) line_bbb_cell_aaa = line_bbb.newContent( portal_type=self.packing_list_cell_portal_type, reference='aaa', int_index=1) line_aaa = packing_list.newContent( portal_type=self.packing_list_line_portal_type, reference='aaa', int_index=2) line_ccc = packing_list.newContent( portal_type=self.packing_list_line_portal_type, reference='ccc', int_index=4) line_ddd = packing_list.newContent( portal_type=self.packing_list_line_portal_type, reference='ddd', int_index=3) self.tic() # check it's possible to sort by reference reference_result = packing_list.getMovementList(sort_on= [('reference', 'descending')]) self.assertEqual(reference_result, [line_ddd, line_ccc, line_bbb_cell_bbb, line_bbb_cell_aaa, line_aaa]) # check it's possible to sort by int_index int_index_result = packing_list.getMovementList(sort_on= [('int_index', 'ascending')]) self.assertEqual(int_index_result, [line_bbb_cell_aaa, line_bbb_cell_bbb, line_aaa, line_ddd, line_ccc]) def test_subcontent_reindexing_container_line_cell(self): """Tests, that indexation of Packing List are propagated to subobjects during reindxation, for Container, Container Line and Container Cell""" packing_list = self.portal.getDefaultModule( self.packing_list_portal_type).newContent( portal_type=self.packing_list_portal_type) container = packing_list.newContent( portal_type=self.container_portal_type) container_line = container.newContent( portal_type=self.container_line_portal_type) container_cell = container_line.newContent( portal_type=self.container_cell_portal_type) self._testSubContentReindexing(container, [container_line, container_cell]) def stepSetAssignmentOrderProfile(self,sequence=None, sequence_list=None, **kw): """ Configure an Assingnment Order. This order represents that it transfers an ownership to somebody. In this case, source and destination are not moving. """ organisation1 = sequence.get('organisation1') organisation2 = sequence.get('organisation2') project1 = sequence.get('project1') project2 = sequence.get('project2') order = sequence.get('order') order.edit(source_value = organisation1, source_section_value = organisation1, source_payment_value = organisation1['bank'], destination_value = organisation1, # set same organisation destination_section_value = organisation2, destination_payment_value = organisation2['bank'], source_project_value = project1, destination_project_value = project2 ) order.setPaymentConditionEfficiency(1.0) self.assertTrue('Site Error' not in order.view()) def testTransferOfOwnership(self, quiet=quiet): """ Test that Packing List has a capability to represent transfer of an ownership(rights). """ sequence_list = SequenceList() assignment_order_sequence = """ CreateOrganisation1 CreateOrganisation2 CreateOrganisation3 CreateProject1 CreateProject2 CreateOrder CreateCurrency SetOrderPriceCurrency SetAssignmentOrderProfile """ sequence_string = assignment_order_sequence + """ CreateNotVariatedResource Tic CreateOrderLine SetOrderLineResource SetOrderLineDefaultValues OrderOrder Tic ConfirmOrder Tic PackingListBuilderAlarm Tic CheckOrderSimulation CheckDeliveryBuilding CheckPackingListIsNotDivergent CheckOrderPackingList """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def stepAssertCausalityStateIsNotSolvedInConsistencyMessage(self, sequence=None, sequence_list=None, **kw): """ Test that Causality State not solved appears in check consistency """ packing_list = sequence.get('packing_list') self.assertEqual( ['Causality State is not "Solved". Please wait or take action' + ' for causality state to reach "Solved".'], [str(message.message) for message in packing_list.checkConsistency()]) def test_20_PackingListCausalityStateConstraint(self, quiet=quiet, run=run_all_test): """ Check that consistency takes into account the Causality State """ if not run: return sequence_list = SequenceList() sequence_string = self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating AssertCausalityStateIsNotSolvedInConsistencyMessage Tic CheckPackingListIsDiverged AssertCausalityStateIsNotSolvedInConsistencyMessage """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def stepIncreasePackingListLineNegativeQuantity(self, sequence=None, sequence_list=None, **kw): """ Set a decreased quantity on packing list lines """ packing_list = sequence.get('packing_list') quantity = sequence.get('line_quantity',default=self.default_quantity) quantity = quantity + 1 sequence.edit(line_quantity=quantity) packing_list_line, = packing_list.getMovementList(portal_type=self.packing_list_line_portal_type) packing_list_line.edit(quantity=quantity) for packing_list_line in packing_list.objectValues( portal_type=self.packing_list_line_portal_type): packing_list_line.edit(quantity=quantity) def stepCheckPackingListSplittedWithNegativeQuantity(self, sequence=None, sequence_list=None, **kw): """ Test if packing list was splitted """ packing_list1, packing_list2 = self.getTwoRelatedPackingList(sequence) packing_list1_line, = packing_list1.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(self.default_quantity+1,packing_list1_line.getQuantity()) packing_list2_line, = packing_list2.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(-1,packing_list2_line.getQuantity()) def stepCheckPackingListSplittedTwoTimesWithNegativeQuantity(self, sequence=None, sequence_list=None, **kw): """ Test if packing list is splitted two times """ packing_list1, packing_list2 = self.getTwoRelatedPackingList(sequence) packing_list1_line, = packing_list1.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(self.default_quantity+2,packing_list1_line.getQuantity()) packing_list2_line, = packing_list2.objectValues(portal_type=self.packing_list_line_portal_type) self.assertEqual(-2,packing_list2_line.getQuantity()) def test_21_PackingListQuantitySplitNegativeQuantity(self): """ Make sur quantity split solver works fine in the case we have negative quantities. Probably rarely useful in the case of sale packing list, but could be useful in other kinds of delivery (like in MRP). """ try: self.default_quantity = -99 sequence_list = SequenceList() sequence_string = self.default_sequence + """ IncreasePackingListLineNegativeQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndDeferPackingList Tic CheckPackingListIsSolved CheckPackingListSplittedWithNegativeQuantity IncreasePackingListLineNegativeQuantity CheckPackingListIsCalculating Tic CheckPackingListIsDiverged SplitAndMovePackingList Tic CheckNewPackingListIsSolved stepCheckPackingListSplittedTwoTimesWithNegativeQuantity """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self) finally: delattr(self, "default_quantity") class TestSolvingPackingList(TestPackingListMixin, ERP5TypeTestCase): quiet = 0 def afterSetUp(self, quiet=1, run=1): TestPackingListMixin.afterSetUp(self) solver_process_type_info = self.portal.portal_types['Solver Process'] self.original_allowed_content_types = \ solver_process_type_info.getTypeAllowedContentTypeList() self.added_target_solver_list = [] @UnrestrictedMethod def beforeTearDown(self, quiet=1, run=1): super(TestSolvingPackingList, self).beforeTearDown() self.portal.portal_rules.new_delivery_simulation_rule.quantity_tester.edit( solver=()) self.portal.portal_types['Solver Process'].setTypeAllowedContentTypeList( self.original_allowed_content_types) self.portal.portal_solvers.manage_delObjects(self.added_target_solver_list) self.tic() @UnrestrictedMethod def _setUpTargetSolver(self, solver_id, solver_class, tested_property_list): solver_tool = self.portal.portal_solvers solver = solver_tool.newContent( portal_type='Solver Type', id=solver_id, tested_property_list=tested_property_list, automatic_solver=1, type_class=solver_class, type_group_list=('target_solver',), ) solver.setCriterion(property='portal_type', identity=['Simulation Movement',]) solver.setCriterionProperty('portal_type') solver_process_type_info = self.portal.portal_types['Solver Process'] solver_process_type_info.setTypeAllowedContentTypeList( solver_process_type_info.getTypeAllowedContentTypeList() + [solver_id] ) (default_chain, chain_dict) = getChainByType(self.portal) chain_dict['chain_%s' % solver_id] = 'solver_workflow' self.portal.portal_workflow.manage_changeWorkflows(default_chain, props=chain_dict) self.portal.portal_caches.clearAllCache() self.added_target_solver_list.append(solver_id) @UnrestrictedMethod def stepSetUpAutomaticQuantityAcceptSolver(self, sequence=None, sequence_list=None): self._setUpTargetSolver('Automatic Quantity Accept Solver', 'AcceptSolver', ('quantity',)) self.portal.portal_rules.new_delivery_simulation_rule.quantity_tester.edit( solver=('portal_solvers/Automatic Quantity Accept Solver',)) @UnrestrictedMethod def stepSetUpAutomaticQuantityAdoptSolver(self, sequence=None, sequence_list=None): self._setUpTargetSolver('Automatic Quantity Adopt Solver', 'AdoptSolver', ('quantity',)) self.portal.portal_rules.new_delivery_simulation_rule.quantity_tester.edit( solver=('portal_solvers/Automatic Quantity Adopt Solver',)) @UnrestrictedMethod def stepSetUpMovementSplitSolver(self, sequence=None, sequence_list=None): self._setUpTargetSolver('Movement Split Solver', 'MovementSplitSolver', ()) def stepSplitMovementWithVariatedResources(self, sequence=None, sequence_list=None): packing_list = sequence.get('packing_list') simulation_movement_list = sum( [x.getDeliveryRelatedValueList() for x in packing_list.getMovementList()[:10]], []) solver_process = self.portal.portal_solver_processes.newContent( portal_type='Solver Process') target_solver = solver_process.newContent( portal_type='Movement Split Solver', delivery_value_list=simulation_movement_list) target_solver.solve() def stepCheckSplitMovementWithVariatedResources(self, sequence=None, sequence_list=None): packing_list = sequence.get('packing_list') order = packing_list.getCausalityValue() new_packing_list = filter(lambda x:x != packing_list, order.getCausalityRelatedValueList( portal_type=packing_list.getPortalType()))[0] self.assertEqual(len(packing_list.getMovementList()), len(order.getMovementList()) - 10) self.assertEqual(len(new_packing_list.getMovementList()), 10) def test_01_PackingListDecreaseQuantity(self, quiet=quiet): """ Change the quantity on an delivery line, then see if the packing list is solved automatically with accept solver. """ sequence_list = SequenceList() sequence_string = """ SetUpAutomaticQuantityAcceptSolver """ + self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsSolved """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_02_PackingListDecreaseQuantity(self, quiet=quiet): """ Change the quantity on an delivery line, then see if the packing list is solved automatically with adopt solver. """ sequence_list = SequenceList() sequence_string = """ SetUpAutomaticQuantityAdoptSolver """ + self.default_sequence + """ DecreasePackingListLineQuantity CheckPackingListIsCalculating Tic CheckPackingListIsSolved """ sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) def test_09_AddContainersWithVariatedResources(self, quiet=quiet): sequence_list = SequenceList() # Test with a order with cells sequence_string = """ SetUpMovementSplitSolver """ + self.variated_default_sequence + """ AddPackingListContainer AddPackingListContainerLine SetContainerLineSmallQuantity CheckContainerLineSmallQuantity CheckPackingListIsNotPacked SetContainerFullQuantity Tic CheckPackingListIsPacked SplitMovementWithVariatedResources Tic CheckSplitMovementWithVariatedResources """ # XXX Check if there is a new packing list created sequence_list.addSequenceString(sequence_string) sequence_list.play(self, quiet=quiet) class TestPurchasePackingListMixin(TestPackingListMixin): """Mixing class with steps to test purchase packing lists. """ order_portal_type = 'Purchase Order' order_line_portal_type = 'Purchase Order Line' order_cell_portal_type = 'Purchase Order Cell' packing_list_portal_type = 'Purchase Packing List' packing_list_line_portal_type = 'Purchase Packing List Line' packing_list_cell_portal_type = 'Purchase Packing List Cell' delivery_builder_id = 'purchase_packing_list_builder' container_portal_type = None container_line_portal_type = None container_cell_portal_type = None # all steps related to packing and container does not apply on purchase def ignored_step(self, **kw): return stepAddPackingListContainer = ignored_step stepDefineNewPackingListContainer = ignored_step stepAddPackingListContainerLine = ignored_step stepSetContainerLineSmallQuantity = ignored_step stepCheckContainerLineSmallQuantity = ignored_step stepSetContainerLineFullQuantity = ignored_step stepSetContainerFullQuantity = ignored_step stepCheckPackingListIsNotPacked = ignored_step stepCheckPackingListIsPacked = ignored_step stepCheckNewPackingListIsPacked = ignored_step def test_subcontent_reindexing_packing_list_container_line_cell(self): """No need to check Containers in Purchase Packing List""" def test_subcontent_reindexing_container_line_cell(self): """No need to check Containers in Purchase Packing List""" class TestPurchasePackingList(TestPurchasePackingListMixin, TestPackingList): """Tests for purchase packing list. """ def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestPackingList)) suite.addTest(unittest.makeSuite(TestSolvingPackingList)) suite.addTest(unittest.makeSuite(TestPurchasePackingList)) return suite