diff --git a/product/ERP5/Tool/SimulationTool.py b/product/ERP5/Tool/SimulationTool.py index 1181dfdfcf99bdc29f128739cc2ac0a979fb4aac..9ca8025a375caa0f547f3a3a76b6dbef99221e71 100755 --- a/product/ERP5/Tool/SimulationTool.py +++ b/product/ERP5/Tool/SimulationTool.py @@ -739,7 +739,6 @@ class SimulationTool (BaseTool): return None - ####################################################### # Traceability management security.declareProtected(Permissions.AccessContentsInformation, 'getTrackingList') @@ -800,33 +799,6 @@ class SimulationTool (BaseTool): ####################################################### # Movement Group Collection / Delivery Creation - def collectMovement(self, movement_list,class_list=None,**kw): - """ - group movements in the way we want. Thanks to this method, we are able to retrieve - movement classed by order, resource, criterion,.... - - movement_list : the list of movement wich we want to group - - check_list : the list of classes used to group movements. The order - of the list is important and determines by what we will - group movement first - Typically, check_list is : - [DateMovementGroup,PathMovementGroup,...] - """ - s_tool = self.portal_simulation - from Products.ERP5.MovementGroup import OrderMovementGroup, PathMovementGroup - from Products.ERP5.MovementGroup import DateMovementGroup, ResourceMovementGroup - from Products.ERP5.MovementGroup import VariantMovementGroup, RootMovementGroup - if class_list is None: - # For compatibility reasons, by default we keep the previous order - class_list = [OrderMovementGroup,PathMovementGroup,DateMovementGroup, - ResourceMovementGroup,VariantMovementGroup] - my_root_group = RootMovementGroup(class_list=class_list) - for movement in movement_list: - if not movement in my_root_group.movement_list : - my_root_group.append(movement,class_list=class_list) - - return my_root_group def buildOrderList(self, movement_group): # Build orders from a list of movements (attached to orders) @@ -955,380 +927,6 @@ class SimulationTool (BaseTool): return order_list - - - - - def buildDeliveryList(self, movement_group): - # Build deliveries from a list of movements - LOG('buildDeliveryList root_group',0,movement_group) - LOG('buildDeliveryList root_group.__dict__',0,movement_group.__dict__) - for group in movement_group.group_list: - LOG('buildDeliveryList group.__dict__',0,group.__dict__) - LOG('buildDeliveryList nested_class.__dict__',0,movement_group.nested_class.__dict__) - - - def orderGroupProcessing(order_group, delivery_list, reindexable_movement_list, **kw): - - # Order should never be None - LOG("buildDeliveryList", 0, str(order_group.__dict__)) - if order_group.order is not None: - order = self.portal_categories.resolveCategory(order_group.order) - if order is not None: - # define some variables - LOG("order", 0, str(order.__dict__)) - if order.getPortalType() == 'Purchase Order' : - delivery_module = order.getPortalObject().livraison_achat - delivery_type = 'Purchase Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - elif order.getPortalType() == 'Sale Order' : - delivery_module = order.getPortalObject().sale_packing_list - delivery_type = 'Sale Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - else : - delivery_module = order.getPortalObject().livraison_vente - delivery_type = 'Sales Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - else : # should never be none - LOG("order is None", 0, str(order.__dict__)) - return -1 - else: # order is None - order = None - # possible when we build deliveries for tranfer of property - delivery_module = self.getPortalObject().livraison_vente - delivery_type = 'Sales Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - - for path_group in order_group.group_list: - pathGroupProcessing(path_group=path_group, - delivery_module=delivery_module, - delivery_type=delivery_type, - delivery_line_type=delivery_line_type, - delivery_cell_type=delivery_cell_type, - order=order, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list, **kw) - - return 0 - - - def pathGroupProcessing(path_group, delivery_module, delivery_type, delivery_line_type, delivery_cell_type, order, delivery_list, reindexable_movement_list, default_rule_id=None, **kw): - # we create a new delivery for each DateGroup - - - if default_rule_id is 'default_amortisation_rule': - pass - else: - # if path is internal ??? - # JPS NEW - if path_group.source is None or path_group.destination is None: - # Production Path - LOG("Builder",0, "Strange Path %s " % path_group.source) - LOG("Builder",0, "Strange Path %s " % path_group.destination) - LOG("Builder path_group in pathGroupProcessing",0, path_group.__dict__) - - - if path_group.source is None or path_group.destination is None: - pass - #delivery_module = self.rapport_fabrication - #delivery_type = 'Production Report' - #delivery_line_type = 'Production Report Line' - #delivery_cell_type = 'Production Report Cell' - elif path_group.destination.find('site/Stock_PF') >= 0 and \ - path_group.source.find('site/Piquage') >= 0: - delivery_module = self.livraison_fabrication - delivery_type = 'Production Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - elif path_group.source.find('site/Stock_MP') >= 0 and \ - path_group.destination.find('site/Piquage') >= 0: - delivery_module = self.livraison_fabrication - delivery_type = 'Production Packing List' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = 'Delivery Cell' - - for date_group in path_group.group_list : - dateGroupProcessing(date_group=date_group, - path_group=path_group, - delivery_module=delivery_module, - delivery_type=delivery_type, - delivery_line_type=delivery_line_type, - delivery_cell_type=delivery_cell_type, - order=order, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list, - default_rule_id=default_rule_id, **kw) - - - def dateGroupProcessing(date_group, path_group, delivery_module, delivery_type, delivery_line_type, delivery_cell_type, order, delivery_list, reindexable_movement_list, default_rule_id=None, resource=None, **kw): - - if default_rule_id == 'default_amortisation_rule': - accounting_transaction_data_list = {} - - for path_group in date_group.group_list: - source_section = path_group.source_section - destination_section = path_group.destination_section - source = path_group.source - destination = path_group.destination - - accounting_transaction_data = accounting_transaction_data_list.get( (source_section, destination_section), None) - if accounting_transaction_data is None: - accounting_transaction_data_list[ (source_section, destination_section) ] = {} - accounting_transaction_data = accounting_transaction_data_list.get( (source_section, destination_section), None) - quantity = 0 - source_movement_list = [] - - for movement in path_group.movement_list: - if movement.getDeliveryValue() is None: - quantity += movement.getQuantity() - source_movement_list.append(movement) - accounting_transaction_data[ (source, destination) ] = (quantity, source_movement_list) - if len(source_movement_list) == 0: - del accounting_transaction_data[ (source, destination) ] - - for (source_section, destination_section), accounting_transaction_data in accounting_transaction_data_list.items(): - if len(accounting_transaction_data.items()) > 0: - new_delivery_id = str(delivery_module.generateNewId()) - accounting_transaction = delivery_module.newContent(portal_type = delivery_type, - id = new_delivery_id, - start_date = date_group.start_date, - stop_date = date_group.stop_date, - source_section = source_section, - destination_section = destination_section - ) - accounting_transaction.setResource(resource) - for (source, destination), (quantity, source_movement_list) in accounting_transaction_data.items(): - new_transaction_line_id = str(accounting_transaction.generateNewId()) - accounting_transaction_line = accounting_transaction.newContent(type_name = delivery_line_type, - id = new_transaction_line_id, - source = source, - destination = destination) - accounting_transaction_line = accounting_transaction[new_transaction_line_id] - accounting_transaction_line.setQuantity(quantity) - accounting_transaction_line.setResource(resource) - for movement in source_movement_list: - movement.setDeliveryValue(accounting_transaction_line) - movement.recursiveImmediateReindexObject() - - else: - # Create a new packing list - new_delivery_id = str(delivery_module.generateNewId()) - delivery = delivery_module.newContent(type_name = delivery_type, - id = new_delivery_id, - start_date = date_group.start_date, - stop_date = date_group.stop_date, - source = path_group.source, - destination = path_group.destination, - source_section = path_group.source_section, - destination_section = path_group.destination_section, - ) - if order is not None : - delivery.edit(title = order.getTitle(), - causality_value = order, - incoterm = order.getIncoterm(), - delivery_mode = order.getDeliveryMode() - ) - # the new delivery is added to the delivery_list - delivery_list.append(delivery) - # LOG('Livraison créée',0,str(delivery.getId())) - - # Create each delivery_line in the new delivery - - for resource_group in date_group.group_list : - resourceGroupProcessing(resource_group=resource_group, - delivery=delivery, - delivery_type=delivery_type, - delivery_line_type=delivery_line_type, - delivery_cell_type=delivery_cell_type, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list, **kw) - - - def resourceGroupProcessing(resource_group, delivery, delivery_type, delivery_line_type, delivery_cell_type, delivery_list, reindexable_movement_list, delivery_module=None, default_rule_id=None, **kw): - - if default_rule_id == 'default_amortisation_rule': - resource = resource_group.resource - for date_group in resource_group.group_list: - dateGroupProcessing(date_group=date_group, - path_group=None, - delivery_module=delivery_module, - delivery_type=delivery_type, - delivery_line_type=delivery_line_type, - delivery_cell_type=delivery_cell_type, - order=None, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list, - default_rule_id=default_rule_id, - resource=resource) - else: - - if delivery_type == 'Production Report': - if resource_group.resource.find('operation') == 0: - delivery_line_type = 'Production Report Operation' - else: - delivery_line_type = 'Production Report Component' - - #new_delivery_line_id = str(delivery.generateNewId()) - delivery_line = delivery.newContent(type_name = delivery_line_type, - resource = resource_group.resource, - ) - - line_variation_category_list = [] - line_variation_base_category_dict = {} - - # compute line_variation_base_category_list and - # line_variation_category_list for new delivery_line - for variant_group in resource_group.group_list : - for variation_item in variant_group.category_list : - if not variation_item in line_variation_category_list : - line_variation_category_list.append(variation_item) - variation_base_category_items = variation_item.split('/') - if len(variation_base_category_items) > 0 : - line_variation_base_category_dict[variation_base_category_items[0]] = 1 - - # update variation_base_category_list and line_variation_category_list for delivery_line - line_variation_base_category_list = line_variation_base_category_dict.keys() - delivery_line._setVariationBaseCategoryList(line_variation_base_category_list) - delivery_line.setVariationCategoryList(line_variation_category_list) - - # IMPORTANT : delivery cells are automatically created during setVariationCategoryList - - # update quantity for each delivery_cell - for variant_group in resource_group.group_list: - #LOG('Variant_group examin?,0,str(variant_group.category_list)) - object_to_update = None - # if there is no variation of the resource, update delivery_line with quantities and price - if len(variant_group.category_list) == 0 : - object_to_update = delivery_line - # else find which delivery_cell is represented by variant_group - else : - categories_identity = 0 - #LOG('Before Check cell',0,str(delivery_cell_type)) - #LOG('Before Check cell',0,str(delivery_line.contentValues())) - for delivery_cell in delivery_line.contentValues( - filter={'portal_type':delivery_cell_type}) : - #LOG('Check cell',0,str(delivery_cell)) - if len(variant_group.category_list) == len(delivery_cell.getVariationCategoryList()) : - #LOG('Parse category',0,str(delivery_cell.getVariationCategoryList())) - for category in delivery_cell.getVariationCategoryList() : - if not category in variant_group.category_list : - #LOG('Not found category',0,str(category)) - break - else : - categories_identity = 1 - - if categories_identity : - object_to_update = delivery_cell - break - - # compute quantity, quantity and price for delivery_cell or delivery_line and - # build relation between simulation_movement and delivery_cell or delivery_line - if object_to_update is not None : - cell_quantity = 0 - cell_total_price = 0 - for movement in variant_group.movement_list : - LOG('SimulationTool, movement.getPhysicalPath',0,movement.getPhysicalPath()) - LOG('SimulationTool, movement.showDict',0,movement.showDict()) - cell_quantity += movement.getNetConvertedQuantity() - try: - cell_total_price += movement.getNetConvertedQuantity()*movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY - except: - cell_total_price = None - - if movement.getPortalType() == 'Simulation Movement' : - # update every simulation_movement - # we set delivery_value and target dates and quantity - movement._setDeliveryValue(object_to_update) - movement._setQuantity(movement.getQuantity()) - movement._setEfficiency(movement.getEfficiency()) - movement._setStartDate(movement.getStartDate()) - movement._setStopDate(movement.getStopDate()) - movement._setSource(movement.getSource()) - movement._setDestination(movement.getDestination()) - movement._setSourceSection(movement.getSourceSection()) - movement._setDestinationSection(movement.getDestinationSection()) - - # We will reindex later - reindexable_movement_list.append(movement) - - if cell_quantity <> 0 and cell_total_price is not None: - average_price = cell_total_price/cell_quantity - else : - average_price = 0 - #LOG('object mis à jour',0,str(object_to_update.getRelativeUrl())) - object_to_update._edit(quantity = cell_quantity, - price = average_price, - force_update = 1, - ) - - - - delivery_list = [] - reindexable_movement_list = [] - - - if movement_group is not None: - # Verify the rule used to build the movements - default_rule_id = None - if len(movement_group.movement_list) > 0: - f = getattr(movement_group.movement_list[0], 'getRootAppliedRule', None) - if f is not None: - applied_rule = f() - default_rule_id = applied_rule.getSpecialiseId() - - - if default_rule_id == 'default_amortisation_rule': - delivery_module = self.getPortalObject().accounting - delivery_type = 'Amortisation Transaction' - delivery_line_type = delivery_type + ' Line' - delivery_cell_type = None - - for resource_group in movement_group.group_list: - resourceGroupProcessing(resource_group=resource_group, - delivery=None, - delivery_module=delivery_module, - delivery_type=delivery_type, - delivery_line_type=delivery_line_type, - delivery_cell_type=delivery_cell_type, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list, - default_rule_id=default_rule_id) - for movement in movement_group.movement_list: - movement.immediateReindexObject() - - - else: - for order_group in movement_group.group_list: - if orderGroupProcessing(order_group=order_group, - delivery_list=delivery_list, - reindexable_movement_list=reindexable_movement_list) == -1: - return delivery_list - - - # If we reach this point, it means we could - # create deliveries - # get_transaction().commit() - # DO NOT USE COMMIT BECAUSE OF WORKFLOW - - # Now, let us index what must be indexed - # Since we comitted changes, there should be no risk of conflict - LOG('reindexable_movement_list',0,reindexable_movement_list) - for movement in reindexable_movement_list: - LOG('will reindex this object: ',0,movement) - # We have to use 'immediate' to bypass the activity tool, - # because we will depend on these objects when we try to call buildInvoiceList - - # movement.reindexObject() # we do it now because we need to - movement.immediateReindexObject() # we do it now because we need to - # update category relation - - # Now return deliveries which were created - return delivery_list - ####################################################### # Capacity Management security.declareProtected( Permissions.ModifyPortalContent, 'updateCapacity' )