def getQTabItemList(self, display_id='getTitle', base=1, current_category=None): """ Returns a list of items which can be used as index for each tab of a matrix or to define a cell range. """ tab_category_list = self._getSortedBaseCategoryList(self.getQVariationBaseCategoryList())[2:] tab_category_item_list_list = [] for tab_category in tab_category_list: tab_category_item_list = self.getVariationRangeCategoryItemList(base_category_list = [tab_category], display_id=display_id, base=base, current_category=current_category) tab_category_item_list_list.append(tab_category_item_list) transformation = self.getParentValue() transformation_category_item_list = transformation.getVariationCategoryItemList( display_id=display_id, base=base, current_category=current_category) tab_category_item_list_list.append(transformation_category_item_list) if len(tab_category_item_list_list) > 0: product_list = cartesianProduct(tab_category_item_list_list) result = [] for item_list in product_list: value_list = [] label_list = [] for item in item_list: value_list.append(item[0]) label_list.append(item[1]) result.append((value_list, label_list)) else: result = [(None,'')] return result
def getTransformationVariationCategoryCartesianProduct(self): """ Defines which variations are of interest when indexing Transformations related to this resource. By default, this returns the cartesian Product of all possible categories using all variation axes. Override this to reduce the number of indexed rows, and/or if some variation axes do not matter when displaying Transformed inventories. XXX This should use variated_range mixin when available """ method = self._getTypeBasedMethod(\ 'getTransformationVariationCategoryCartesianProduct') if method is not None: return method() variation_list_list = [] for base_variation in self.getVariationBaseCategoryList(): variation_list = self.getVariationCategoryList( \ base_category_list=(base_variation,)) if len(variation_list) > 0: variation_list_list.append(variation_list) return cartesianProduct(variation_list_list)
def test_change_dimension_cell_change_id(self): # The dimension change, a cell is kept, but receives a new ID because its # coordinate changes matrix = self.matrix cell_range = [['1', '2',], ['a', 'b',]] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) cell.setTitle('This one') self.tic() cell_range = [['2', '3', ], ['b', 'c',]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertFalse('quantity_0_1' in matrix.objectIds()) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) self.assertEqual('This one', cell.getTitle()) self.tic() # the cell is still in catalog self.assertEqual(cell, self.portal.portal_catalog.getObject(cell.getUid()))
def test_change_dimension_cell_change_id(self): # The dimension change, a cell is kept, but receives a new ID because its # coordinate changes matrix = self.matrix cell_range = [['1', '2',], ['a', 'b',]] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell('2', 'b', **kwd) self.assertEquals('quantity_1_1', cell.getId()) cell.setTitle('This one') get_transaction().commit() self.tic() cell_range = [['2', '3', ], ['b', 'c',]] matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertFalse('quantity_0_1' in matrix.objectIds()) cell = matrix.getCell('2', 'b', **kwd) # this is the same cell, but it just changed id self.assertEquals('quantity_0_0', cell.getId()) self.assertEquals('This one', cell.getTitle()) get_transaction().commit() self.tic() # the cell is still in catalog self.assertEquals(cell, self.portal.portal_catalog.getObject(cell.getUid()))
def test_change_dimension_and_check_consistency(self): # make sure _checkConsistency does not complain about a cell # having an id outside the len of the dimension after a dimension # change if id is within acceptable values matrix = self.matrix cell_range = [['1', '2',], ['a', 'b',]] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) cell.setTitle('This one') self.tic() cell_range = [['2', ], ['b',]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEquals(set(["quantity_1_1"]), set([ x.getId() for x in matrix.objectValues()])) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) self.assertEqual('This one', cell.getTitle()) self.assertEqual(XMLMatrix._checkConsistency(matrix), []) cell.setId('quantity_2_1') error_list = XMLMatrix._checkConsistency(matrix) self.assertEqual(1, len(error_list)) self.assertTrue(error_list[0][3].find("is out of bound") > 0)
def test_change_dimension_cell_change_id(self): # The dimension change, a cell is kept, but receives a new ID because its # coordinate changes matrix = self.matrix cell_range = [["1", "2"], ["a", "b"]] kwd = {"base_id": "quantity"} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell("2", "b", **kwd) self.assertEqual("quantity_1_1", cell.getId()) cell.setTitle("This one") self.tic() cell_range = [["2", "3"], ["b", "c"]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertFalse("quantity_0_1" in matrix.objectIds()) cell = matrix.getCell("2", "b", **kwd) self.assertEqual("quantity_1_1", cell.getId()) self.assertEqual("This one", cell.getTitle()) self.tic() # the cell is still in catalog self.assertEqual(cell, self.portal.portal_catalog.getObject(cell.getUid()))
def test_decrease_and_increase_dimension(self): matrix = self.matrix cell_range = [['1', '2'], [ 'a', ]] kwd = {'base_id': 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell(*['1', 'a'], **kwd) self.tic() cell_range = [[ '1', ], ['a', 'b']] matrix.setCellRange(*cell_range, **kwd) self.assertEquals(1, len(matrix.getCellValueList(**kwd))) # previous cell is kept self.assertEquals(cell, matrix.getCell(*['1', 'a'], **kwd)) self.tic() # the cell is still in catalog self.assertEquals(cell, self.portal.portal_catalog.getObject(cell.getUid()))
def getCellKeyList(self, base_id='cell'): """Returns a list of possible keys as tuples """ if getattr(aq_base(self), 'index', None) is None: return () if not self.index.has_key(base_id): return () index = self.index[base_id] id_tuple = [v.keys() for v in index.itervalues()] if len(id_tuple) == 0: return () return cartesianProduct(id_tuple)
def getCellKeyList(self, base_id = 'cell'): """Returns a list of possible keys as tuples """ if getattr(aq_base(self), 'index', None) is None: return () if not self.index.has_key(base_id): return () index = self.index[base_id] id_tuple = [v.keys() for v in index.itervalues()] if len(id_tuple) == 0: return () return cartesianProduct(id_tuple)
def _updateXupdateInsertOrAdd(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to add elements. """ conflict_list = [] integration_site = document.context.getParentValue() # browse subnode of the insert and check what will be create for subnode in xml.getchildren(): new_tag = subnode.attrib['name'] new_value = subnode.text if new_tag == 'category': mapping = integration_site.getMappingFromCategory(new_value) base_category, variation = mapping.split('/', 1) # retrieve the variations which have a different axe from the updated # and build the cartesian variation for this new variations external_axe_list = [ tuple(x.category.split('/', 1)) for x in document.context.getProductCategoryList() if x.category.split('/', 1)[0] != base_category ] builder_variation_list = [ [(base_category, variation)], external_axe_list, ] variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: document.context.product_module.createProductAttribute( id_product=document.getId(), ) id_product_attribute = document.context.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: document.context.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=document.getId(), base_category=variation[0], variation=variation[1], ) else: keyword = { 'product_id': document.getId(), new_tag: new_value, } document.context.product_module.updateProduct(**keyword) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
def test_del_dimension(self): matrix = self.matrix cell_range = [['1', ], ['a', ]] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) self.tic() cell_range = [['1', ]] matrix.setCellRange(*cell_range, **kwd) self.assertEqual(0, len(matrix.getCellValueList(**kwd))) self.tic()
def _updateXupdateInsertOrAdd(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to add elements. """ conflict_list = [] integration_site = document.context.getParentValue() # browse subnode of the insert and check what will be create for subnode in xml.getchildren(): new_tag = subnode.attrib['name'] new_value = subnode.text if new_tag == 'category': mapping = integration_site.getMappingFromCategory(new_value) base_category, variation = mapping.split('/', 1) # retrieve the variations which have a different axe from the updated # and build the cartesian variation for this new variations external_axe_list = [ tuple(x.category.split('/', 1)) for x in document.context.getProductCategoryList() if x.category.split('/', 1)[0] != base_category ] builder_variation_list = [ [(base_category, variation)], external_axe_list, ] variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: document.context.product_module.createProductAttribute( id_product=document.getId(), ) id_product_attribute = document.context.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: document.context.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=document.getId(), base_category=variation[0], variation=variation[1], ) else: keyword = {'product_id': document.getId(), new_tag: new_value, } document.context.product_module.updateProduct(**keyword) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
def test_change_dimension_and_check_consistency(self): # make sure _checkConsistency does not complain about a cell # having an id outside the len of the dimension after a dimension # change if id is within acceptable values matrix = self.matrix cell_range = [[ '1', '2', ], [ 'a', 'b', ]] kwd = {'base_id': 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) cell.setTitle('This one') self.tic() cell_range = [[ '2', ], [ 'b', ]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEquals(set(["quantity_1_1"]), set([x.getId() for x in matrix.objectValues()])) cell = matrix.getCell('2', 'b', **kwd) self.assertEqual('quantity_1_1', cell.getId()) self.assertEqual('This one', cell.getTitle()) self.assertEqual(XMLMatrix._checkConsistency(matrix), []) cell.setId('quantity_2_1') error_list = XMLMatrix._checkConsistency(matrix) self.assertEqual(1, len(error_list)) self.assertTrue(error_list[0][3].find("is out of bound") > 0)
def test_decrease_and_increase_dimension(self): matrix = self.matrix cell_range = [["1", "2"], ["a"]] kwd = {"base_id": "quantity"} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell(*["1", "a"], **kwd) self.tic() cell_range = [["1"], ["a", "b"]] matrix.setCellRange(*cell_range, **kwd) self.assertEqual(1, len(matrix.getCellValueList(**kwd))) # previous cell is kept self.assertEqual(cell, matrix.getCell(*["1", "a"], **kwd)) self.tic() # the cell is still in catalog self.assertEqual(cell, self.portal.portal_catalog.getObject(cell.getUid()))
def getVTabItemList(self): transformation = self.getParentValue() line_id = transformation.getVariationBaseCategoryLine() column_id = transformation.getVariationBaseCategoryColumn() base_category_list = transformation.getVariationBaseCategoryList() base_category = [] for c in base_category_list: if not c in (line_id, column_id): if c in self.getVVariationBaseCategoryList(): base_category += [transformation.getCategoryMembershipList(c, base=1)] if len(base_category) > 0: clist = cartesianProduct(base_category) result = [] for c in clist: result += [(c,c)] else: result = [(None,'')] result.sort() # XXX Temp until set / list issue solved return result
def test_decrease_and_increase_dimension(self): matrix = self.matrix cell_range = [['1', '2'], ['a', ]] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) for place in cartesianProduct(cell_range): matrix.newCell(*place, **kwd) cell = matrix.getCell(*['1', 'a'], **kwd) self.tic() cell_range = [['1', ], ['a', 'b']] matrix.setCellRange(*cell_range, **kwd) self.assertEqual(1, len(matrix.getCellValueList(**kwd))) # previous cell is kept self.assertEqual(cell, matrix.getCell(*['1', 'a'], **kwd)) self.tic() # the cell is still in catalog self.assertEqual(cell, self.portal.portal_catalog.getObject(cell.getUid()))
reference_variation_category_list = variation_category_list elif reference_variation_category_list == []: reference_variation_category_list = context.getVariationCategoryList() result = [] # Separate reference_variation_category_list by base category variation_category_dict = {} for variation_category in reference_variation_category_list: base_category = variation_category.split('/',1)[0] if variation_category_dict.has_key( base_category ): variation_category_dict[base_category].append( variation_category ) else: variation_category_dict[base_category] = [variation_category] variation_key_list = cartesianProduct( variation_category_dict.values() ) for variation_key in variation_key_list: params = { 'reference_variation_category_list' : variation_key, } result.append( # Context is report form ReportSection(path=context.getPhysicalPath(), title='Resource variation', level=1, form_id='Transformation_viewExpanded', selection_name='transformation_expanded_selection', selection_params=params,
def test_02_SetCellRangeAndCatalogWithActivities(self): """ Tests if set Cell range do well catalog and uncatalog """ portal = self.portal catalog = portal.portal_catalog matrix = self.matrix url = matrix.getUrl() cell_range = [['1', '2', '3'], ['a', 'b', 'c']] kwd = {'base_id': 'quantity'} matrix.setCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) self.tic() initial_cell_id_list = list(matrix.objectIds()) for id in initial_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) cell_range = [['2', '3', '4'], ['b', 'c', 'd']] matrix.setCellRange(*cell_range, **kwd) # We must commit transaction in order to put cell reindexing in activity queue self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) next_cell_id_list = list(matrix.objectIds()) # the cells on coordinates 2b, 3b, 3b and 3c are kept self.assertEquals(4, len(next_cell_id_list)) for coord in [['2', 'b'], ['2', 'c'], ['3', 'b'], ['3', 'c']]: self.assertNotEqual(None, matrix.getCell(*coord, **kwd)) removed_id_list = filter(lambda x: x not in next_cell_id_list, initial_cell_id_list) self.tic() for id in next_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) cell_range = [['0', '1'], ['a', 'b']] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) next2_cell_id_list = list(matrix.objectIds()) removed_id_list = filter(lambda x: x not in next2_cell_id_list, next_cell_id_list) self.tic() for id in next2_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) cell_range = [['0', '1'], ['a', 'b']] kwd = {'base_id': 'movement'} matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() for id in next2_cell_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) # create some cells cell1 = matrix.newCell(*['0', 'a'], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*['1', 'a'], **kwd) cell2_path = cell2.getPath() self.commit() # if we keep the same range, nothing happens matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.assertEqual(len(matrix.getCellValueList(**kwd)), 2) self.tic() self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertTrue(catalog.hasPath(cell1_path)) self.assertTrue(catalog.hasPath(cell2_path)) # now set other ranges cell_range = [['0', '2'], [ 'a', ], ['Z']] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path)) # create cells in this new range cell1 = matrix.newCell(*['0', 'a', 'Z'], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*['2', 'a', 'Z'], **kwd) cell2_path = cell2.getPath() self.commit() cell_range = [['1', '2'], [ 'a', ], ['X']] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path))
def _createContent( self, xml=None, object=None, object_id=None, sub_object=None, # pylint: disable=redefined-builtin reset_local_roles=0, reset_workflow=0, simulate=0, **kw): LOG("TioSafeNodeConduit._createConten", 300, "xml = %s" % (etree.tostring(xml, pretty_print=1), )) # if exist namespace retrieve only the tag index = 0 if xml.nsmap not in [None, {}]: index = -1 # init the new_id of the product and the checker of the creation new_id = None # this dict contains the element to set to the product keyword = {} # this dict will contains a list of tuple (base_category, vairiation) variation_dict = {} resource_type = self.getObjectType(xml=xml).strip() # browse the xml for node in xml: # works on tags, not on comments if not isinstance(node.tag, str): continue tag = node.tag.split('}')[index] LOG("browsing tag %s, value %s" % (tag, node.text), 300, "keyword = %s" % (keyword, )) if tag == 'category': # retrieve through the mapping the base category and the variation mapping = object.getMappingFromCategory(node.text) base_category, variation = mapping.split('/', 1) variation_dict.setdefault(base_category, []).append(variation) else: keyword[tag] = node.text.encode('utf-8') # Create the product at the end of the xml browsing create_method_id = "create%s" % (resource_type, ) create_method = getattr(object, create_method_id, None) if create_method is not None: create_result = create_method(**keyword) else: raise ValueError( 'Impossible to find a create method named %s and object %s' % ( create_method_id, object.getPath(), )) if len(create_result): # We suppose the id of the object created was returned by the plugin new_id = create_result[0].getId() else: # We must ask for the id of the object previously created # XXX-AUREL : this must be changed to use gid definition instead new_id = object.IntegrationSite_lastID( type=resource_type)[0].getId() # create the full variations in the integration site if variation_dict: # XXX-Aurel : This is too specific to prestashop, must be moved and # replaced by generic code # the cartesianProduct requires to build a list of list of variations builder_variation_list = [] for key, value in variation_dict.items(): variation_list = [] for variation in value: variation_list.append((key, variation)) builder_variation_list.append(variation_list) # build and browse the list of variations variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: object.createProductAttribute(id_product=new_id) id_product_attribute = object.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: object.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=new_id, base_category=variation[0], variation=variation[1], ) return object[new_id]
def _createContent(self, xml=None, object=None, object_id=None, sub_object=None, reset_local_roles=0, reset_workflow=0, simulate=0, **kw): #LOG("TioSafeNodeConduit._createConten", 300, "xml = %s" %(etree.tostring(xml, pretty_print=1),)) # if exist namespace retrieve only the tag index = 0 if xml.nsmap not in [None, {}]: index = -1 # init the new_id of the product and the checker of the creation new_id = None product_created = False # this dict contains the element to set to the product keyword = {} # this dict will contains a list of tuple (base_category, variation) variation_dict = {} resource_type = self.getObjectType(xml=xml).strip() # browse the xml for node in xml: # works on tags, not on comments if type(node.tag) is not str: continue tag = node.tag.split('}')[index] #LOG("browsing tag %s, value %s" %(tag, node.text), 300, "keyword = %s" %(keyword,)) if tag == 'category': # retrieve through the mapping the base category and the variation LOG("_createContent", 0, node.text) mapping = object.getMappingFromCategory(node.text.encode('utf-8')) LOG("_createContent", 0, mapping) base_category, variation = mapping.split('/', 1) variation_dict.setdefault(base_category, []).append(variation) else: keyword[tag] = node.text.encode('utf-8') # Create the product at the end of the xml browsing create_method_id = "create%s" %(resource_type,) create_method = getattr(object, create_method_id, None) if create_method is not None: create_result = create_method(**keyword) else: raise ValueError, 'Impossible to find a create method named %s and object %s' %(create_method_id, object.getPath(),) LOG('VirtuemartResourceConduit: ', INFO, object.IntegrationSite_lastID(type='Product')[0].showDict()) new_id = object.IntegrationSite_lastID(type='Product')[0].getId() # create the full variations in the integration site if variation_dict: # the cartesianProduct requires to build a list of list of variations builder_variation_list = [] for key, value in variation_dict.items(): variation_list = [] for variation in value: variation_list.append((key, variation)) builder_variation_list.append(variation_list) ## build and browse the list of variations variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: for variation in var_list: object.product_module.createProductCategory( product_id=new_id, base_category=variation[0], variation=variation[1], ) return object[new_id]
] base_application_list = ', '.join(translated_base_application_list) service = paysheet_line.getResourceValue(portal_type='Service') base_contribution_list = paysheet_line.getBaseContributionList() causality = paysheet_line.getCausality() base_list = [str(translateString(base_application)) for base_application in \ paysheet_line.getBaseApplicationTitleList()] base_name = '+'.join(base_list) list_of_list = [] for base_category in base_category_list: list = paysheet_line.getVariationCategoryList(base_category_list=\ base_category) list_of_list.append(list) cartesian_product = cartesianProduct(list_of_list) previous_share = None indice = 0 if cartesian_product == [[]] or cartesian_product == []: params = { 'base':paysheet_line.getTotalPrice(), 'base_contribution_list':base_contribution_list, 'base_application_list': base_application_list, 'service': service is not None and\ service.getId() or '', 'causality': causality,} line_list.append(paysheet_line.asContext(**params)) continue
else: is_child_category = 0 category_path = '%s/%s' % (base_category, category) category_object = getCategoryValue(category_path) if category_object is None: raise RuntimeError("Security definition error (category %r not found)" % (category_path,)) portal_type = category_object.getPortalType() if portal_type == 'Person': # We define a person here user_name = category_object.Person_getUserId() if user_name is not None: user_list.append(user_name) else: category_code = (category_object.getProperty('codification') or category_object.getProperty('reference') or category_object.getId()) if is_child_category: category_code += '*' associative_list.append(category_code) # Prevent making a cartesian product with an empty set if associative_list: list_of_list.append(associative_list) # Return a list of users if any was defined if user_list: return user_list # Compute the cartesian product and return the codes # return filter(lambda x: x, map(lambda x: '_'.join(x), cartesianProduct(list_of_list))) return ['_'.join(x) for x in cartesianProduct(list_of_list) if x]
from Products.ERP5Type.Utils import cartesianProduct from Products.ERP5Type.Message import translateString updated_cell_count = 0 dependant_dimensions_dict = context.BudgetLine_getSummaryDimensionKeyDict() cell_key_list = context.getCellKeyList() # we iterate in reversed order to update the deepest cells first for cell_key in sorted(cartesianProduct(context.getCellRange()), reverse=True): for idx, dimension in enumerate(cell_key): if dimension in dependant_dimensions_dict: dependant_cell_list = [] matching_cell_key = list(cell_key) for key in dependant_dimensions_dict[dimension]: matching_cell_key[idx] = key for other_cell_key in cell_key_list: if matching_cell_key == other_cell_key: cell = context.getCell(*other_cell_key) if cell is not None: dependant_cell_list.append(cell) if dependant_cell_list: cell = context.getCell(*cell_key) if cell is None: # if summary cell does not exist, we create it. cell = context.newCell(*cell_key) cell.edit(membership_criterion_base_category_list=[ bc for bc in context.getVariationBaseCategoryList() if bc not in context.getMembershipCriterionBaseCategoryList()
def _updateXupdateUpdate(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to work on the update of elements. """ conflict_list = [] xpath_expression = xml.get('select') tag = xpath_expression.split('/')[-1] integration_site = document.context.getParentValue() new_value = xml.text # retrieve the previous xml etree through xpath previous_xml = previous_xml.xpath(xpath_expression) try: previous_value = previous_xml[0].text except IndexError: raise ValueError, 'Too little or too many value, only one is required for %s' % ( previous_xml ) # check if it'a work on product or on categories if tag.split('[')[0] == 'category': # init the base category and the variation through the mapping mapping = integration_site.getMappingFromCategory(new_value) base_category, variation = mapping.split('/', 1) updated = False # init the previous value through the mapping previous_value = integration_site.getMappingFromCategory(previous_value) # work on variations variation_brain_list = document.context.getProductCategoryList() for brain in variation_brain_list: if brain.category == previous_value: old_base_category, old_variation = previous_value.split('/', 1) # remove all variations document.context.product_module.deleteProductAttributeCombination( product_id=document.getId(), base_category=old_base_category, variation=old_variation, ) # retrieve the variations which have a different axe from the updated # and build the cartesian variation for this new variations external_axe_list = [ tuple(x.category.split('/', 1)) for x in document.context.getProductCategoryList() if x.category.split('/', 1)[0] != brain.category.split('/', 1)[0] ] builder_variation_list = [ [tuple(mapping.split('/', 1))], external_axe_list, ] variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: document.context.product_module.createProductAttribute( id_product=document.getId(), ) id_product_attribute = document.context.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: document.context.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=document.getId(), base_category=variation[0], variation=variation[1], ) else: # previous value not find, so multiple update on the same product conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(previous_value) conflict.setRemoteValue(new_value) conflict_list.append(conflict) else: # getter used to retrieve the current values and to check conflicts property_list = ['sale_price', 'purchase_price', 'ean13'] getter_value_dict = dict(zip( property_list, [ getattr(document, prop, None) for prop in property_list ] )) # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents current_value = getter_value_dict[tag] if type(current_value) == float: current_value = '%.6f' % current_value if current_value not in [new_value, previous_value]: conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(new_value) conflict_list.append(conflict) else: keyword = {'product_id': document.getId(), tag: new_value , } document.context.product_module.updateProduct(**keyword) return conflict_list
def test_01_RenameCellRange(self): """ tests renameCellRange behaviour """ matrix = self.matrix cell_range = [['1', '2', '3'], ['a', 'b', 'c']] kwd = {'base_id': 'quantity'} matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [['2', '3', '4'], ['b', 'c', 'd']] matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), i) i += 1 cell_range = [['1', '2', '3', '4'], ['a', 'b', 'c', 'd']] value_list = (0, 1, 2, None, 3, 4, 5, None, 6, 7, 8, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['1', '2'], ['a', 'b']] value_list = (0, 1, 3, 4) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['3'], ['a', 'b', 'c'], ['A', 'B', 'C']] value_list = (0, None, None, 1, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['1', '2'], ['A', 'B']] value_list = (0, 1, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [['1', '2'], ['A', 'B'], ['a', 'b']] value_list = (0, None, 1, None, 2, None, 3, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 # now commit transaction to make sure there are no activities for cells # that no longer exists. self.tic()
line_list = [] object_dict_list = [] id = 0 for model_line in model_line_list: base_category_list = model_line.getVariationBaseCategoryList() base_application_list = model_line.getBaseApplicationTitleList() translated_base_application_list = [str(translateString(x)) for x in base_application_list] base_application_list = ', '.join(translated_base_application_list) list_of_list = [] for base_category in base_category_list: list = model_line.getVariationCategoryList(base_category_list=\ base_category) list_of_list.append(list) cartesian_product = cartesianProduct(list_of_list) previous_share = None object_dict = {} if cartesian_product == [[]]: share_dict = {} if 0: share_dict[cell.getContributionShare()+'_price'] = 0 share_dict[cell.getContributionShare()+'_quantity'] = 0 continue for tuple in cartesian_product: share_dict = {} cell = model_line.getCell(*tuple) if cell is None:
def _createContent(self, xml=None, object=None, object_id=None, sub_object=None, reset_local_roles=0, reset_workflow=0, simulate=0, **kw): #LOG("TioSafeNodeConduit._createConten", 300, "xml = %s" %(etree.tostring(xml, pretty_print=1),)) # if exist namespace retrieve only the tag index = 0 if xml.nsmap not in [None, {}]: index = -1 # init the new_id of the product and the checker of the creation new_id = None product_created = False # this dict contains the element to set to the product keyword = {} # this dict will contains a list of tuple (base_category, variation) variation_dict = {} resource_type = self.getObjectType(xml=xml).strip() # browse the xml for node in xml: # works on tags, not on comments if type(node.tag) is not str: continue tag = node.tag.split('}')[index] #LOG("browsing tag %s, value %s" %(tag, node.text), 300, "keyword = %s" %(keyword,)) if tag == 'category': # retrieve through the mapping the base category and the variation LOG("_createContent", 0, node.text) mapping = object.getMappingFromCategory( node.text.encode('utf-8')) LOG("_createContent", 0, mapping) base_category, variation = mapping.split('/', 1) variation_dict.setdefault(base_category, []).append(variation) else: keyword[tag] = node.text.encode('utf-8') # Create the product at the end of the xml browsing create_method_id = "create%s" % (resource_type, ) create_method = getattr(object, create_method_id, None) if create_method is not None: create_result = create_method(**keyword) else: raise ValueError, 'Impossible to find a create method named %s and object %s' % ( create_method_id, object.getPath(), ) new_id = object.IntegrationSite_lastID(type='Product')[0].getId() # create the full variations in the integration site if variation_dict: # the cartesianProduct requires to build a list of list of variations builder_variation_list = [] for key, value in variation_dict.items(): variation_list = [] for variation in value: variation_list.append((key, variation)) builder_variation_list.append(variation_list) ## build and browse the list of variations variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: for variation in var_list: object.product_module.createProductCategory( product_id=new_id, base_category=variation[0], variation=variation[1], ) return object[new_id]
from Products.ERP5Type.Utils import cartesianProduct from Products.ERP5Type.Message import translateString updated_cell_count = 0 dependant_dimensions_dict = context.BudgetLine_getSummaryDimensionKeyDict() cell_key_list = context.getCellKeyList() def reversed(seq): seq = seq[::] seq.sort(reverse=True) return seq # we iterate in reversed order to update the deepest cells first for cell_key in reversed(cartesianProduct(context.getCellRange())): for idx, dimension in enumerate(cell_key): if dimension in dependant_dimensions_dict: dependant_cell_list = [] matching_cell_key = list(cell_key) for key in dependant_dimensions_dict[dimension]: matching_cell_key[idx] = key for other_cell_key in cell_key_list: if matching_cell_key == other_cell_key: cell = context.getCell(*other_cell_key) if cell is not None: dependant_cell_list.append(cell) if dependant_cell_list: cell = context.getCell(*cell_key) if cell is None: # if summary cell does not exist, we create it.
def render(self, field, key, value, REQUEST, render_format='html', render_prefix=None): """ This is where most things happen. This method renders a list of items """ # First grasp the variables we may need here = REQUEST['here'] form = field.aq_parent field_title = field.get_value('title') cell_base_id = field.get_value('cell_base_id') context = here getter_method_id = field.get_value('getter_method') if getter_method_id not in (None, ''): context = getattr(here, getter_method_id)() if context is None: return '' as_cell_range_script_id = field.get_value('as_cell_range_script_id') extra_dimension_category_list_list = [None] if as_cell_range_script_id: lines = [] columns = [] tabs = [] dimension_list = guarded_getattr(context, as_cell_range_script_id)( matrixbox=True, base_id=cell_base_id) len_dimension_list = len(dimension_list) if len_dimension_list: if len_dimension_list == 1: lines, = dimension_list elif len_dimension_list == 2: lines, columns = dimension_list elif len_dimension_list >= 3: lines, columns, tabs = dimension_list[:3] if len_dimension_list > 3: extra_dimension_list = dimension_list[3:] extra_dimension_category_label_dict = {} extra_dimension_category_index_dict = {} for extra_dimension in extra_dimension_list: for index, (category, label) in enumerate(extra_dimension): extra_dimension_category_label_dict[ category] = label extra_dimension_category_index_dict[ category] = index from Products.ERP5Type.Utils import cartesianProduct extra_dimension_category_list_list = cartesianProduct( [[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list]) else: lines = field.get_value('lines') columns = field.get_value('columns') tabs = field.get_value('tabs') field_errors = REQUEST.get('field_errors', {}) cell_getter_method_id = field.get_value('cell_getter_method') if cell_getter_method_id not in (None, ''): cell_getter_method = getattr(context, cell_getter_method_id) else: cell_getter_method = context.getCell editable_attributes = field.get_value('editable_attributes') url_cells = field.get_value('url_cells') url_cell_dict = dict(url_cells) # This is required when we have no tabs if len(tabs) == 0: tabs = [(None, None)] # This is required when we have no columns if len(columns) == 0: columns = [(None, None)] column_ids = [x[0] for x in columns] line_ids = [x[0] for x in lines] tab_ids = [x[0] for x in tabs] editable_attribute_ids = [x[0] for x in editable_attributes] # THIS MUST BE REMOVED - WHY IS THIS BAD ? # IT IS BAD BECAUSE TAB_IDS DO NOT DEFINE A RANGE.... # here.setCellRange(line_ids, column_ids, base_id=cell_base_id) # result for the list render list_result = [] url = REQUEST.URL list_html = '' for extra_dimension_category_list in extra_dimension_category_list_list: if extra_dimension_category_list is None: extra_dimension_label = '' extra_dimension_position = () extra_dimension_index = '' extra_dimension_category_list = [] else: extra_dimension_label = ',' + ','.join([ extra_dimension_category_label_dict[category] for category in extra_dimension_category_list ]) extra_dimension_position = tuple([ extra_dimension_category_index_dict[category] for category in extra_dimension_category_list ]) extra_dimension_index = '_' + '_'.join( map(str, extra_dimension_position)) # Create one table per tab k = 0 kwd = dict(base_id=cell_base_id) for tab in tabs: tab_id = tab[0] if (tab_id is not None) and \ (not isinstance(tab_id, (list, tuple))): tab_id = [tab_id] if render_format == 'list': list_result_tab = [[tab[1]]] # Create the header of the table - this should probably become DTML first_tab = tab[1] or '' header = """\ <!-- Matrix Content --> <div class="matrixbox_label_tab">%s</div> <div class="MatrixContent"> <table> """ % (first_tab + extra_dimension_label) # Create the footer. This should be replaced by DTML # And work as some kind of parameter footer = """\ <tr> <td colspan="%i" class="Data footer"> </td> </tr> </table> </div> """ % (len(columns) + 1) list_header = """\ <tr class="matrixbox_label_line"><td class=\"Data\"></td> """ for cname in columns: first_column = cname[1] or '' list_header = list_header + ( "<td class=\"Data\">%s</td>\n" % first_column) if render_format == 'list': list_result_tab[0].append(cname[1]) list_header = list_header + "</tr>" # Build Lines i = 0 j = 0 list_body = '' for l in lines: if not i % 2: td_css = 'DataA' else: td_css = 'DataB' list_body = list_body + '\n<tr class=\"%s\"><td class=\"matrixbox_label_column\">%s</td>' % ( td_css, str(l[1])) j = 0 if render_format == 'list': list_result_lines = [str(l[1])] for c in columns: has_error = False column_id = c[0] if (column_id is not None) and \ (not isinstance(column_id, (list, tuple))): column_id = [column_id] if column_id is None: kw = [l[0]] elif tab_id is None: kw = [l[0], c[0]] else: kw = [l[0], c[0] ] + tab_id + extra_dimension_category_list cell = cell_getter_method(*kw, **kwd) REQUEST['cell'] = cell REQUEST['cell_index'] = kw cell_body = '' cell_url = None for attribute_id in editable_attribute_ids: if attribute_id in url_cell_dict: url_method_id = url_cell_dict[attribute_id] if url_method_id not in (None, ''): url_method = getattr( cell, url_method_id, None) if url_method is not None: try: cell_url = url_method( brain=cell, cell_index=kw, cell_position=( (i, j, k) + extra_dimension_position)) except (ConflictError, RuntimeError): raise except: LOG('MatrixBox', WARNING, 'Could not evaluate the url ' 'method %r with %r' % (url_method, cell), error=sys.exc_info()) else: LOG( 'MatrixBox', WARNING, 'Could not find the url method %s' % (url_method_id, )) my_field_id = '%s_%s' % (field.id, attribute_id) if form.has_field(my_field_id): my_field = form.get_field(my_field_id) key = my_field.id + '_cell_%s_%s_%s%s' % ( i, j, k, extra_dimension_index) default_value = my_field.get_value( 'default', cell=cell, cell_index=kw, cell_position=((i, j, k) + extra_dimension_position)) display_value = default_value if field_errors: # Display previous value in case of any error in this form because # we have no cell to get value from display_value = REQUEST.get( 'field_%s' % key, default_value) if cell is not None: if render_format == 'html': cell_html = my_field.render( value=display_value, REQUEST=REQUEST, key=key) if cell_url: # don't make a link if widget is editable if not my_field.get_value( 'editable', cell=cell, cell_index=kw, cell_position=( (i, j, k) + extra_dimension_position )): cell_html = "<a href='%s'>%s</a>" % ( cell_url, cell_html) if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( cell_html, translateString( field_errors[key]. error_text)) else: cell_body += '<span class="input">%s</span>' % ( cell_html) else: if render_format == 'html': if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( my_field.render( value=display_value, REQUEST=REQUEST, key=key), translateString( field_errors[key]. error_text)) else: cell_body += '<span class="input">%s</span>' %\ my_field.render( value=display_value, REQUEST=REQUEST, key=key) if render_format == 'list': # list rendering doesn't make difference when cell exists or not list_result_lines.append({ 'default': default_value, 'value': display_value, 'key': key, 'type': my_field.meta_type if my_field.meta_type != "ProxyField" else my_field. getRecursiveTemplateField().meta_type, 'field_id': my_field.id, 'error_text': u"%s" % (translateString( field_errors[key].error_text) if key in field_errors else '') }) css = td_css if has_error: css = 'error' list_body = list_body + \ ('<td class=\"%s\">%s</td>' % (css, cell_body)) j += 1 list_body = list_body + '</tr>' i += 1 if render_format == 'list': list_result_tab.append(list_result_lines) list_html += header + list_header + \ list_body + footer k += 1 if render_format == 'list': list_result.append(list_result_tab) # XXX Does not leave garbage in REQUEST['cell'], because some other # fields also use that key... REQUEST.other.pop('cell', None) REQUEST.other.pop('cell_index', None) if render_format == 'list': return list_result return list_html
def test_02_SetCellRangeAndCatalogWithActivities(self): """ Tests if set Cell range do well catalog and uncatalog """ portal = self.portal catalog = portal.portal_catalog matrix = self.matrix url = matrix.getUrl() cell_range = [["1", "2", "3"], ["a", "b", "c"]] kwd = {"base_id": "quantity"} matrix.setCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) self.tic() initial_cell_id_list = list(matrix.objectIds()) for id in initial_cell_id_list: self.assertTrue(catalog.hasPath(url + "/" + id)) cell_range = [["2", "3", "4"], ["b", "c", "d"]] matrix.setCellRange(*cell_range, **kwd) # We must commit transaction in order to put cell reindexing in activity queue self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) next_cell_id_list = list(matrix.objectIds()) # the cells on coordinates 2b, 3b, 3b and 3c are kept self.assertEqual(4, len(next_cell_id_list)) for coord in [["2", "b"], ["2", "c"], ["3", "b"], ["3", "c"]]: self.assertNotEqual(None, matrix.getCell(*coord, **kwd)) removed_id_list = filter(lambda x: x not in next_cell_id_list, initial_cell_id_list) self.tic() for id in next_cell_id_list: self.assertTrue(catalog.hasPath(url + "/" + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + "/" + id)) cell_range = [["0", "1"], ["a", "b"]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) next2_cell_id_list = list(matrix.objectIds()) removed_id_list = filter(lambda x: x not in next2_cell_id_list, next_cell_id_list) self.tic() for id in next2_cell_id_list: self.assertTrue(catalog.hasPath(url + "/" + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + "/" + id)) cell_range = [["0", "1"], ["a", "b"]] kwd = {"base_id": "movement"} matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() for id in next2_cell_id_list: self.assertFalse(catalog.hasPath(url + "/" + id)) # create some cells cell1 = matrix.newCell(*["0", "a"], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*["1", "a"], **kwd) cell2_path = cell2.getPath() self.commit() # if we keep the same range, nothing happens matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.assertEqual(len(matrix.getCellValueList(**kwd)), 2) self.tic() self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertTrue(catalog.hasPath(cell1_path)) self.assertTrue(catalog.hasPath(cell2_path)) # now set other ranges cell_range = [["0", "2"], ["a"], ["Z"]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path)) # create cells in this new range cell1 = matrix.newCell(*["0", "a", "Z"], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*["2", "a", "Z"], **kwd) cell2_path = cell2.getPath() self.commit() cell_range = [["1", "2"], ["a"], ["X"]] matrix.setCellRange(*cell_range, **kwd) self.commit() self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path))
def validate(self, field, key, REQUEST): form = field.aq_parent # We need to know where we get the getter from # This is coppied from ERP5 Form here = getattr(form, 'aq_parent', REQUEST) cell_base_id = field.get_value('cell_base_id') as_cell_range_script_id = field.get_value('as_cell_range_script_id') context = here getter_method_id = field.get_value('getter_method') if getter_method_id not in (None, ''): context = getattr(here, getter_method_id)() if context is None: return {} extra_dimension_category_list_list = [None] if as_cell_range_script_id: lines = [] columns = [] tabs = [] dimension_list = guarded_getattr(context, as_cell_range_script_id)( matrixbox=True, base_id=cell_base_id) len_dimension_list = len(dimension_list) if len_dimension_list: if len_dimension_list == 1: lines, = dimension_list elif len_dimension_list == 2: lines, columns = dimension_list elif len_dimension_list >= 3: lines, columns, tabs = dimension_list[:3] if len_dimension_list > 3: extra_dimension_list = dimension_list[3:] extra_dimension_category_label_dict = {} extra_dimension_category_index_dict = {} for extra_dimension in extra_dimension_list: for index, (category, label) in enumerate(extra_dimension): extra_dimension_category_label_dict[ category] = label extra_dimension_category_index_dict[ category] = index from Products.ERP5Type.Utils import cartesianProduct extra_dimension_category_list_list = cartesianProduct( [[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list]) else: lines = field.get_value('lines') columns = field.get_value('columns') tabs = field.get_value('tabs') editable_attributes = field.get_value('editable_attributes') error_list = [] cell_getter_method_id = field.get_value('cell_getter_method') if cell_getter_method_id not in (None, ''): cell_getter_method = getattr(context, cell_getter_method_id) else: cell_getter_method = context.getCell # This is required when we have no tabs if len(tabs) == 0: tabs = [(None, None)] # This is required when we have no columns if len(columns) == 0: columns = [(None, None)] # XXX Copy/Paste from render... column_ids = [x[0] for x in columns] line_ids = [x[0] for x in lines] tab_ids = [x[0] for x in tabs] editable_attribute_ids = [x[0] for x in editable_attributes] result = {} for extra_dimension_category_list in extra_dimension_category_list_list: if extra_dimension_category_list is None: extra_dimension_label = '' extra_dimension_position = () extra_dimension_index = '' extra_dimension_category_list = [] else: extra_dimension_label = ',' + ','.join([ extra_dimension_category_label_dict[category] for category in extra_dimension_category_list ]) extra_dimension_position = tuple([ extra_dimension_category_index_dict[category] for category in extra_dimension_category_list ]) extra_dimension_index = '_' + '_'.join( map(str, extra_dimension_position)) k = 0 # Create one table per tab kwd = dict(base_id=cell_base_id) for tab_id in tab_ids: if (tab_id is not None) and \ (not isinstance(tab_id, (list, tuple))): tab_id = [tab_id] i = 0 j = 0 for l in line_ids: j = 0 for c in column_ids: if c is None: kw = [l] elif tab_id is None: kw = [l, c] else: kw = [l, c ] + tab_id + extra_dimension_category_list kw = tuple(kw) cell = cell_getter_method(*kw, **kwd) for attribute_id in editable_attribute_ids: my_field_id = '%s_%s' % (field.id, attribute_id) if form.has_field(my_field_id): my_field = form.get_field(my_field_id) if my_field.get_value('editable'): key = 'field_' + my_field.id + '_cell_%s_%s_%s%s' % ( i, j, k, extra_dimension_index) attribute_value = my_field.get_value( 'default', cell=cell, cell_index=kw, cell_position=( (i, j, k) + extra_dimension_position)) value = None try: # We call directly Validator's validate method to pass our own key # because Field.validate always computes the key from field properties value = my_field.validator.validate( my_field, key, REQUEST) # Unfortunately the call to external validator is implemented within # field's `validate` method. Since we call the validator's validate # directly, we need to copy&paste call to external validator from Field's validate here external_validator = my_field.get_value( 'external_validator') if external_validator and not external_validator( value, REQUEST): my_field.validator.raise_error( 'external_validator_failed', my_field) except ValidationError, err: err.field_id = my_field.id + '_cell_%s_%s_%s%s' % ( i, j, k, extra_dimension_index) error_list.append(err) if (attribute_value != value or \ attribute_value not in ('',None,(),[])) \ and not my_field.get_value('hidden'): # Only validate modified values from visible fields result.setdefault( kw, {})[attribute_id] = value elif kw in result: result[kw][attribute_id] = value j += 1 i += 1 k += 1
def render(self, field, key, value, REQUEST, render_format='html', render_prefix=None): """ This is where most things happen. This method renders a list of items """ # First grasp the variables we may need here = REQUEST['here'] form = field.aq_parent field_title = field.get_value('title') cell_base_id = field.get_value('cell_base_id') context = here getter_method_id = field.get_value('getter_method') if getter_method_id not in (None,''): context = getattr(here,getter_method_id)() if context is None: return '' as_cell_range_script_id = field.get_value('as_cell_range_script_id') extra_dimension_category_list_list = [None] if as_cell_range_script_id: lines = [] columns = [] tabs = [] dimension_list = guarded_getattr(context, as_cell_range_script_id)(matrixbox=True, base_id=cell_base_id) len_dimension_list = len(dimension_list) if len_dimension_list: if len_dimension_list == 1: lines, = dimension_list elif len_dimension_list == 2: lines, columns = dimension_list elif len_dimension_list >= 3: lines, columns, tabs = dimension_list[:3] if len_dimension_list > 3: extra_dimension_list = dimension_list[3:] extra_dimension_category_label_dict = {} extra_dimension_category_index_dict = {} for extra_dimension in extra_dimension_list: for index, (category, label) in enumerate(extra_dimension): extra_dimension_category_label_dict[category] = label extra_dimension_category_index_dict[category] = index from Products.ERP5Type.Utils import cartesianProduct extra_dimension_category_list_list = cartesianProduct( [[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list]) else: lines = field.get_value('lines') columns = field.get_value('columns') tabs = field.get_value('tabs') field_errors = REQUEST.get('field_errors', {}) cell_getter_method_id = field.get_value('cell_getter_method') if cell_getter_method_id not in (None, ''): cell_getter_method = getattr(context, cell_getter_method_id) else: cell_getter_method = context.getCell editable_attributes = field.get_value('editable_attributes') url_cells = field.get_value('url_cells') url_cell_dict = dict(url_cells) # This is required when we have no tabs if len(tabs) == 0: tabs = [(None,None)] # This is required when we have no columns if len(columns) == 0: columns = [(None,None)] column_ids = [x[0] for x in columns] line_ids = [x[0] for x in lines] tab_ids = [x[0] for x in tabs] editable_attribute_ids = [x[0] for x in editable_attributes] # THIS MUST BE REMOVED - WHY IS THIS BAD ? # IT IS BAD BECAUSE TAB_IDS DO NOT DEFINE A RANGE.... # here.setCellRange(line_ids, column_ids, base_id=cell_base_id) # result for the list render list_result = [] url = REQUEST.URL list_html = '' for extra_dimension_category_list in extra_dimension_category_list_list: if extra_dimension_category_list is None: extra_dimension_label = '' extra_dimension_position = () extra_dimension_index = '' extra_dimension_category_list = [] else: extra_dimension_label = ','+','.join([extra_dimension_category_label_dict[category] for category in extra_dimension_category_list]) extra_dimension_position = tuple([extra_dimension_category_index_dict[category] for category in extra_dimension_category_list]) extra_dimension_index = '_'+'_'.join(map(str, extra_dimension_position)) # Create one table per tab k = 0 kwd = dict(base_id=cell_base_id) for tab in tabs: tab_id = tab[0] if (tab_id is not None) and \ (not isinstance(tab_id, (list, tuple))): tab_id = [tab_id] if render_format == 'list': list_result_tab = [[tab[1]]] # Create the header of the table - this should probably become DTML first_tab = tab[1] or '' header = """\ <!-- Matrix Content --> <div class="matrixbox_label_tab">%s</div> <div class="MatrixContent"> <table cellpadding="0" cellspacing="0" border="0"> """ % (first_tab+extra_dimension_label) # Create the footer. This should be replaced by DTML # And work as some kind of parameter footer = """\ <tr> <td colspan="%s" align="center" valign="middle" class="Data footer"> </td> </tr> </table> </div> """ % len(columns) list_header = """\ <tr class="matrixbox_label_line"><td class=\"Data\"></td> """ for cname in columns: first_column = cname[1] or '' list_header = list_header + ("<td class=\"Data\">%s</td>\n" % first_column) if render_format == 'list': list_result_tab[0].append(cname[1]) list_header = list_header + "</tr>" # Build Lines i = 0 j = 0 list_body = '' for l in lines: if not i % 2: td_css = 'DataA' else: td_css = 'DataB' list_body = list_body + '\n<tr class=\"%s\"><td class=\"matrixbox_label_column\">%s</td>' % (td_css, str(l[1])) j = 0 if render_format == 'list': list_result_lines = [ str(l[1]) ] for c in columns: has_error = False column_id = c[0] if (column_id is not None) and \ (not isinstance(column_id, (list, tuple))): column_id = [column_id] if column_id is None: kw = [l[0]] elif tab_id is None: kw = [l[0], c[0]] else: kw = [l[0], c[0]] + tab_id + extra_dimension_category_list cell = cell_getter_method(*kw, **kwd) REQUEST['cell'] = cell REQUEST['cell_index'] = kw cell_body = '' cell_url = None for attribute_id in editable_attribute_ids: if attribute_id in url_cell_dict: url_method_id = url_cell_dict[attribute_id] if url_method_id not in (None, ''): url_method = getattr(cell, url_method_id, None) if url_method is not None: try: cell_url = url_method(brain=cell, cell_index=kw, cell_position=((i,j,k) + extra_dimension_position)) except (ConflictError, RuntimeError): raise except: LOG('MatrixBox', WARNING, 'Could not evaluate the url ' 'method %r with %r' % (url_method, cell), error=sys.exc_info()) else: LOG('MatrixBox', WARNING, 'Could not find the url method %s' % (url_method_id,)) my_field_id = '%s_%s' % (field.id, attribute_id) if form.has_field(my_field_id): my_field = form.get_field(my_field_id) key = my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index) if cell is not None: attribute_value = my_field.get_value('default', cell=cell, cell_index=kw, cell_position = ((i,j,k)+extra_dimension_position)) if render_format=='html': display_value = attribute_value if field_errors: # Display previous value in case of any error # in this form because we have no cell to get # value from display_value = REQUEST.get('field_%s' % key, attribute_value) else: display_value = attribute_value cell_html = my_field.render(value=display_value, REQUEST=REQUEST, key=key) if cell_url: # don't make a link if widget is editable if not my_field.get_value('editable', cell=cell, cell_index=kw, cell_position=((i,j,k)+extra_dimension_position)): cell_html = "<a href='%s'>%s</a>" % (cell_url, cell_html) if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( cell_html, translateString(field_errors[key].error_text)) else: cell_body += '<span class="input">%s</span>' % ( cell_html ) elif render_format == 'list': if not my_field.get_value('hidden'): list_result_lines.append(attribute_value) else: attribute_value = my_field.get_value('default', cell=None, cell_index=kw, cell_position=((i,j,k)+extra_dimension_position)) if render_format == 'html': if field_errors: # Display previous value in case of any error # in this form because we have no cell to get # value from display_value = REQUEST.get('field_%s' % key, attribute_value) else: display_value = attribute_value if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( my_field.render(value=display_value, REQUEST=REQUEST, key=key), translateString(field_errors[key].error_text)) else: cell_body += '<span class="input">%s</span>' %\ my_field.render( value=display_value, REQUEST=REQUEST, key=key) elif render_format == 'list': list_result_lines.append(None) css = td_css if has_error: css = 'error' list_body = list_body + \ ('<td class=\"%s\">%s</td>' % (css, cell_body)) j += 1 list_body = list_body + '</tr>' i += 1 if render_format == 'list': list_result_tab.append(list_result_lines) list_html += header + list_header + \ list_body + footer k += 1 if render_format == 'list': list_result.append(list_result_tab) # XXX Does not leave garbage in REQUEST['cell'], because some other # fields also use that key... REQUEST.other.pop('cell', None) REQUEST.other.pop('cell_index', None) if render_format == 'list': return list_result return list_html
def test_02_SetCellRangeAndCatalogWithActivities(self): """ Tests if set Cell range do well catalog and uncatalog """ portal = self.portal catalog = portal.portal_catalog matrix = self.matrix url = matrix.getUrl() cell_range = [['1', '2', '3'], ['a', 'b', 'c']] kwd = {'base_id' : 'quantity'} matrix.setCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) get_transaction().commit() self.tic() initial_cell_id_list = list(matrix.objectIds()) for id in initial_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) cell_range = [['2', '3', '4'], ['b', 'c', 'd']] matrix.setCellRange(*cell_range, **kwd) # We must commit transaction in order to put cell reindexing in activity queue get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) next_cell_id_list = list(matrix.objectIds()) # the cells on coordinates 2b, 3b, 3b and 3c are kept self.assertEquals(4, len(next_cell_id_list)) for coord in [['2', 'b'], ['2', 'c'], ['3', 'b'], ['3', 'c']]: self.assertNotEqual(None, matrix.getCell(*coord, **kwd)) removed_id_list = filter(lambda x: x not in next_cell_id_list,initial_cell_id_list) self.tic() for id in next_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) cell_range = [['0', '1'], ['a','b']] matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) next2_cell_id_list = list(matrix.objectIds()) removed_id_list = filter(lambda x: x not in next2_cell_id_list,next_cell_id_list) self.tic() for id in next2_cell_id_list: self.assertTrue(catalog.hasPath(url + '/' + id)) for id in removed_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) cell_range = [['0', '1'], ['a','b']] kwd = {'base_id' : 'movement'} matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) self.tic() for id in next2_cell_id_list: self.assertFalse(catalog.hasPath(url + '/' + id)) # create some cells cell1 = matrix.newCell(*['0', 'a'], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*['1', 'a'], **kwd) cell2_path = cell2.getPath() get_transaction().commit() # if we keep the same range, nothing happens matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) self.assertEqual(len(matrix.getCellValueList(**kwd)), 2) self.tic() self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertTrue(catalog.hasPath(cell1_path)) self.assertTrue(catalog.hasPath(cell2_path)) # now set other ranges cell_range = [['0', '2'], ['a', ], ['Z']] matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path)) # create cells in this new range cell1 = matrix.newCell(*['0', 'a', 'Z'], **kwd) cell1_path = cell1.getPath() cell2 = matrix.newCell(*['2', 'a', 'Z'], **kwd) cell2_path = cell2.getPath() get_transaction().commit() cell_range = [['1', '2'], ['a', ], ['X']] matrix.setCellRange(*cell_range, **kwd) get_transaction().commit() self.assertEqual(matrix.getCellRange(**kwd), cell_range) self.tic() # in this case, cells has been removed self.assertEqual(matrix.getCellValueList(**kwd), []) self.assertTrue(catalog.hasPath(matrix.getPath())) self.assertFalse(catalog.hasPath(cell1_path)) self.assertFalse(catalog.hasPath(cell2_path))
def validate(self, field, key, REQUEST): form = field.aq_parent # We need to know where we get the getter from # This is coppied from ERP5 Form here = getattr(form, 'aq_parent', REQUEST) cell_base_id = field.get_value('cell_base_id') as_cell_range_script_id = field.get_value('as_cell_range_script_id') context = here getter_method_id = field.get_value('getter_method') if getter_method_id not in (None,''): context = getattr(here,getter_method_id)() if context is None: return {} extra_dimension_category_list_list = [None] if as_cell_range_script_id: lines = [] columns = [] tabs = [] dimension_list = guarded_getattr(context, as_cell_range_script_id)(matrixbox=True, base_id=cell_base_id) len_dimension_list = len(dimension_list) if len_dimension_list: if len_dimension_list == 1: lines, = dimension_list elif len_dimension_list == 2: lines, columns = dimension_list elif len_dimension_list >= 3: lines, columns, tabs = dimension_list[:3] if len_dimension_list > 3: extra_dimension_list = dimension_list[3:] extra_dimension_category_label_dict = {} extra_dimension_category_index_dict = {} for extra_dimension in extra_dimension_list: for index, (category, label) in enumerate(extra_dimension): extra_dimension_category_label_dict[category] = label extra_dimension_category_index_dict[category] = index from Products.ERP5Type.Utils import cartesianProduct extra_dimension_category_list_list = cartesianProduct( [[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list]) else: lines = field.get_value('lines') columns = field.get_value('columns') tabs = field.get_value('tabs') editable_attributes = field.get_value('editable_attributes') error_list = [] cell_getter_method_id = field.get_value('cell_getter_method') if cell_getter_method_id not in (None, ''): cell_getter_method = getattr(context, cell_getter_method_id) else: cell_getter_method = context.getCell # This is required when we have no tabs if len(tabs) == 0: tabs = [(None,None)] # This is required when we have no columns if len(columns) == 0: columns = [(None,None)] # XXX Copy/Paste from render... column_ids = [x[0] for x in columns] line_ids = [x[0] for x in lines] tab_ids = [x[0] for x in tabs] editable_attribute_ids = [x[0] for x in editable_attributes] result = {} for extra_dimension_category_list in extra_dimension_category_list_list: if extra_dimension_category_list is None: extra_dimension_label = '' extra_dimension_position = () extra_dimension_index = '' extra_dimension_category_list = [] else: extra_dimension_label = ','+','.join([extra_dimension_category_label_dict[category] for category in extra_dimension_category_list]) extra_dimension_position = tuple([extra_dimension_category_index_dict[category] for category in extra_dimension_category_list]) extra_dimension_index = '_'+'_'.join(map(str, extra_dimension_position)) k = 0 # Create one table per tab kwd = dict(base_id=cell_base_id) for tab_id in tab_ids: if (tab_id is not None) and \ (not isinstance(tab_id, (list, tuple))): tab_id = [tab_id] i = 0 j = 0 for l in line_ids: j = 0 for c in column_ids: if c is None: kw = [l] elif tab_id is None: kw = [l, c] else: kw = [l, c] + tab_id + extra_dimension_category_list kw = tuple(kw) cell = cell_getter_method(*kw, **kwd) for attribute_id in editable_attribute_ids: my_field_id = '%s_%s' % (field.id, attribute_id) if form.has_field(my_field_id): my_field = form.get_field(my_field_id) if my_field.get_value('editable'): key = 'field_' + my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index) attribute_value = my_field.get_value('default', cell=cell, cell_index=kw, cell_position = ((i,j,k)+extra_dimension_position)) value = None try : value = my_field.validator.validate( my_field, key, REQUEST) except ValidationError, err : err.field_id = my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index) error_list.append(err) if (attribute_value != value or \ attribute_value not in ('',None,(),[])) \ and not my_field.get_value('hidden'): # Only validate modified values from visible fields result.setdefault(kw, {})[attribute_id] = value elif kw in result: result[kw][attribute_id] = value j += 1 i += 1 k += 1
def test_01_RenameCellRange(self): """ tests renameCellRange behaviour """ matrix = self.matrix cell_range = [['1', '2', '3'], ['a', 'b', 'c']] kwd = {'base_id' : 'quantity'} matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [['2', '3', '4'], ['b', 'c', 'd']] matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), i) i += 1 cell_range = [['1', '2', '3', '4'], ['a', 'b', 'c', 'd']] value_list = (0, 1, 2, None, 3, 4, 5, None, 6, 7, 8, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['1', '2'], ['a', 'b']] value_list = (0, 1, 3, 4) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['3'], ['a', 'b', 'c'], ['A', 'B', 'C']] value_list = (0, None, None, 1, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 cell_range = [['1', '2'], ['A', 'B']] value_list = (0, 1, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [['1', '2'], ['A', 'B'], ['a', 'b']] value_list = (0, None, 1, None, 2, None, 3, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(matrix.getCellRange(**kwd), cell_range) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, 'test_id', None), value_list[i]) i += 1 # now commit transaction to make sure there are no activities for cells # that no longer exists. get_transaction().commit() self.tic()
def _createContent(self, xml=None, object=None, object_id=None, sub_object=None, reset_local_roles=0, reset_workflow=0, simulate=0, **kw): LOG("TioSafeNodeConduit._createConten", 300, "xml = %s" %(etree.tostring(xml, pretty_print=1),)) # if exist namespace retrieve only the tag index = 0 if xml.nsmap not in [None, {}]: index = -1 # init the new_id of the product and the checker of the creation new_id = None product_created = False # this dict contains the element to set to the product keyword = {} # this dict will contains a list of tuple (base_category, vairiation) variation_dict = {} # browse the xml for node in xml: # works on tags, no on comments if type(node.tag) is not str: continue tag = node.tag.split('}')[index] LOG("browsing tag %s, value %s" %(tag, node.text), 300, "keyword = %s" %(keyword,)) if tag == 'category': # retrieve through the mapping the base category and the variation mapping = object.getMappingFromCategory(node.text) base_category, variation = mapping.split('/', 1) category_params = { 'document': object, 'base_category': base_category, 'variation': variation, } # if exists the variation set it to the builder dict if self.checkCategoryExistency(**category_params): variation_dict.setdefault(base_category, []).append(variation) else: keyword[tag] = node.text # Create the product at the end of the xml browsing object.product_module.createProduct(**keyword) # XXX-AUREL : this must be changed to use gid definition instead new_id = object.IntegrationSite_lastID(type='Product')[0].getId() # create the full variations in the integration site if variation_dict: # the cartesianProduct requires to build a list of list of variations builder_variation_list = [] for key, value in variation_dict.items(): variation_list = [] for variation in value: variation_list.append((key, variation)) builder_variation_list.append(variation_list) # build and browse the list of variations variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: object.product_module.createProductAttribute(id_product=new_id) id_product_attribute = object.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: object.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=new_id, base_category=variation[0], variation=variation[1], ) return object.product_module(id=new_id)[0]
portal = context.getPortalObject() tracking_parameters = { 'node_uid': context.getSourceUid(), 'resource_uid': context.getResourceUid(), 'at_date': context.getStartDate(), 'output': 1, 'item_catalog_title': kw.get('title') or '', 'item_catalog_reference': kw.get('reference') or '', 'item_catalog_portal_type': kw.get('portal_type') or '', 'item_catalog_validation_state': kw.get('validation_state') or '', } check_variation = bool(context.getVariationCategoryList()) acceptable_variation_category_list = \ cartesianProduct(context.getCellRange(base_id='movement')) result_list = [] for tracking_brain in portal.portal_simulation.getCurrentTrackingList( **tracking_parameters): item = tracking_brain.getObject() # XXX can this be done in SQL ? # it could, by computing all variation texts, but I don't think this is # really necessary. if check_variation and \ item.Item_getVariationCategoryList(at_date=context.getStartDate())\ not in acceptable_variation_category_list: continue result_list.append(item)
def _createContent(self, xml=None, object=None, object_id=None, sub_object=None, reset_local_roles=0, reset_workflow=0, simulate=0, **kw): LOG("TioSafeNodeConduit._createConten", 300, "xml = %s" %(etree.tostring(xml, pretty_print=1),)) # if exist namespace retrieve only the tag index = 0 if xml.nsmap not in [None, {}]: index = -1 # init the new_id of the product and the checker of the creation new_id = None product_created = False # this dict contains the element to set to the product keyword = {} # this dict will contains a list of tuple (base_category, vairiation) variation_dict = {} resource_type = self.getObjectType(xml=xml).strip() # browse the xml for node in xml: # works on tags, not on comments if type(node.tag) is not str: continue tag = node.tag.split('}')[index] LOG("browsing tag %s, value %s" %(tag, node.text), 300, "keyword = %s" %(keyword,)) if tag == 'category': # retrieve through the mapping the base category and the variation mapping = object.getMappingFromCategory(node.text) base_category, variation = mapping.split('/', 1) variation_dict.setdefault(base_category, []).append(variation) else: keyword[tag] = node.text.encode('utf-8') # Create the product at the end of the xml browsing create_method_id = "create%s" %(resource_type,) create_method = getattr(object, create_method_id, None) if create_method is not None: create_result = create_method(**keyword) else: raise ValueError, 'Impossible to find a create method named %s and object %s' %(create_method_id, object.getPath(),) if len(create_result): # We suppose the id of the object created was returned by the plugin new_id = create_result[0].getId() else: # We must ask for the id of the object previously created # XXX-AUREL : this must be changed to use gid definition instead new_id = object.IntegrationSite_lastID(type=resource_type)[0].getId() # create the full variations in the integration site if variation_dict: # XXX-Aurel : This is too specific to prestashop, must be moved and # replaced by generic code # the cartesianProduct requires to build a list of list of variations builder_variation_list = [] for key, value in variation_dict.items(): variation_list = [] for variation in value: variation_list.append((key, variation)) builder_variation_list.append(variation_list) # build and browse the list of variations variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: object.createProductAttribute(id_product=new_id) id_product_attribute = object.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: object.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=new_id, base_category=variation[0], variation=variation[1], ) return object[new_id]
def test_01_RenameCellRange(self): """ tests renameCellRange behaviour """ matrix = self.matrix cell_range = [["1", "2", "3"], ["a", "b", "c"]] kwd = {"base_id": "quantity"} matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [["2", "3", "4"], ["b", "c", "d"]] matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), i) i += 1 cell_range = [["1", "2", "3", "4"], ["a", "b", "c", "d"]] value_list = (0, 1, 2, None, 3, 4, 5, None, 6, 7, 8, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), value_list[i]) i += 1 cell_range = [["1", "2"], ["a", "b"]] value_list = (0, 1, 3, 4) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), value_list[i]) i += 1 cell_range = [["3"], ["a", "b", "c"], ["A", "B", "C"]] value_list = (0, None, None, 1, None, None, None, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), value_list[i]) i += 1 cell_range = [["1", "2"], ["A", "B"]] value_list = (0, 1, None, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), value_list[i]) i += 1 i = 0 for place in cartesianProduct(cell_range): cell = matrix.newCell(portal_type="Purchase Order Cell", *place, **kwd) cell.test_id = i i += 1 cell_range = [["1", "2"], ["A", "B"], ["a", "b"]] value_list = (0, None, 1, None, 2, None, 3, None) matrix.renameCellRange(*cell_range, **kwd) self.assertEqual(map(set, matrix.getCellRange(**kwd)), map(set, cell_range)) i = 0 for place in cartesianProduct(cell_range): cell = matrix.getCell(*place, **kwd) if value_list[i] is None: self.assertEqual(cell, None) else: self.assertNotEqual(cell, None) self.assertEqual(getattr(cell, "test_id", None), value_list[i]) i += 1 # now commit transaction to make sure there are no activities for cells # that no longer exists. self.tic()
from Products.ERP5Type.Message import translateString updated_cell_count = 0 dependant_dimensions_dict = context.BudgetLine_getSummaryDimensionKeyDict() cell_key_list = context.getCellKeyList() def reversed(seq): seq = seq[::] seq.sort(reverse=True) return seq # we iterate in reversed order to update the deepest cells first for cell_key in reversed(cartesianProduct(context.getCellRange())): for idx, dimension in enumerate(cell_key): if dimension in dependant_dimensions_dict: dependant_cell_list = [] matching_cell_key = list(cell_key) for key in dependant_dimensions_dict[dimension]: matching_cell_key[idx] = key for other_cell_key in cell_key_list: if matching_cell_key == other_cell_key: cell = context.getCell(*other_cell_key) if cell is not None: dependant_cell_list.append(cell) if dependant_cell_list: cell = context.getCell(*cell_key) if cell is None:
def _updateCategory(self, document=None, xml=None, previous_value=None, signature=None): """ This method allows to update a Category in the Integration Site. """ LOG("_updateCategory", 300, "previous_value = %s, new_value = %s" %(previous_value, xml.text)) conflict_list = [] integration_site = document.context.getParentValue() new_value = xml.text # init the base category and the variation through the mapping mapping = integration_site.getMappingFromCategory(new_value) base_category, variation = mapping.split('/', 1) # init the previous value through the mapping mapped_previous_value = integration_site.getMappingFromCategory(previous_value) # work on variations variation_brain_list = document.context.getProductCategoryList() for brain in variation_brain_list: if brain.category == mapped_previous_value: old_base_category, old_variation = mapped_previous_value.split('/', 1) # remove old variation document.context.product_module.deleteProductAttributeCombination( product_id=document.getId(), base_category=old_base_category, variation=old_variation, ) # retrieve the variations which have a different axe from the updated # and build the cartesian variation for this new variations external_axe_list = [ tuple(x.category.split('/', 1)) for x in document.context.getProductCategoryList() if x.category.split('/', 1)[0] != brain.category.split('/', 1)[0] ] builder_variation_list = [ [tuple(mapping.split('/', 1))], external_axe_list, ] variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: document.context.product_module.createProductAttribute( id_product=document.getId(), ) id_product_attribute = document.context.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: document.context.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=document.getId(), base_category=variation[0], variation=variation[1], ) break else: # previous value not find, so multiple update on the same product conflict = signature.newContent(portal_type='SyncML Conflict', origin=document.getPhysicalPath(), property_id=xml.get('select').split('/')[-1], diff_chunk=etree.tostring(xml, encoding='utf-8'), local_value=previous_value, remove_value=new_value ) conflict_list.append(conflict) return conflict_list
else: is_child_category = 0 category_path = '%s/%s' % (base_category, category) category_object = getCategoryValue(category_path) if category_object is None: raise RuntimeError("Security definition error (category %r not found)" % (category_path,)) portal_type = category_object.getPortalType() if portal_type == 'Person': # We define a person here user_name = category_object.getReference() if user_name is not None: user_list.append(user_name) else: category_code = (category_object.getProperty('codification') or category_object.getProperty('reference') or category_object.getId()) if is_child_category: category_code += '*' associative_list.append(category_code) # Prevent making a cartesian product with an empty set if associative_list: list_of_list.append(associative_list) # Return a list of users if any was defined if user_list: return user_list # Compute the cartesian product and return the codes # return filter(lambda x: x, map(lambda x: '_'.join(x), cartesianProduct(list_of_list))) return ['_'.join(x) for x in cartesianProduct(list_of_list) if x]
def _updateCategory(self, document=None, xml=None, previous_value=None, signature=None): """ This method allows to update a Category in the Integration Site. """ LOG("_updateCategory", 300, "previous_value = %s, new_value = %s" % (previous_value, xml.text)) conflict_list = [] integration_site = document.context.getParentValue() new_value = xml.text # init the base category and the variation through the mapping mapping = integration_site.getMappingFromCategory(new_value) base_category, variation = mapping.split('/', 1) # init the previous value through the mapping mapped_previous_value = integration_site.getMappingFromCategory( previous_value) # work on variations variation_brain_list = document.context.getProductCategoryList() for brain in variation_brain_list: if brain.category == mapped_previous_value: old_base_category, old_variation = mapped_previous_value.split( '/', 1) # remove old variation document.context.product_module.deleteProductAttributeCombination( product_id=document.getId(), base_category=old_base_category, variation=old_variation, ) # retrieve the variations which have a different axe from the updated # and build the cartesian variation for this new variations external_axe_list = [ tuple(x.category.split('/', 1)) for x in document.context.getProductCategoryList() if x.category.split('/', 1)[0] != brain.category.split( '/', 1)[0] ] builder_variation_list = [ [tuple(mapping.split('/', 1))], external_axe_list, ] variation_list = cartesianProduct(builder_variation_list) for var_list in variation_list: document.context.product_module.createProductAttribute( id_product=document.getId(), ) id_product_attribute = document.context.IntegrationSite_lastID( type='Product Attribute', )[0].getId() for variation in var_list: document.context.product_module.createProductAttributeCombination( id_product_attribute=id_product_attribute, id_product=document.getId(), base_category=variation[0], variation=variation[1], ) break else: # previous value not find, so multiple update on the same product conflict = signature.newContent( portal_type='SyncML Conflict', origin=document.getPhysicalPath(), property_id=xml.get('select').split('/')[-1], diff_chunk=etree.tostring(xml, encoding='utf-8'), local_value=previous_value, remove_value=new_value) conflict_list.append(conflict) return conflict_list
tracking_parameters = { 'node_uid': context.getSourceUid(), 'resource_uid': context.getResourceUid(), 'at_date': context.getStartDate(), 'output': 1, 'item_catalog_title': kw.get('title') or '', 'item_catalog_reference': kw.get('reference') or '', 'item_catalog_portal_type': kw.get('portal_type') or '', 'item_catalog_validation_state': kw.get('validation_state') or '', } check_variation = bool(context.getVariationCategoryList()) acceptable_variation_category_list = \ cartesianProduct(context.getCellRange(base_id='movement')) result_list = [] for tracking_brain in portal.portal_simulation.getCurrentTrackingList( **tracking_parameters): item = tracking_brain.getObject() # XXX can this be done in SQL ? # it could, by computing all variation texts, but I don't think this is # really necessary. if check_variation and \ item.Item_getVariationCategoryList(at_date=context.getStartDate())\ not in acceptable_variation_category_list: continue result_list.append(item)
try: return container.REQUEST[script.id] except KeyError: pass dependant_dimensions_dict = context.BudgetLine_getSummaryDimensionKeyDict() summary_key_dict = {} from Products.ERP5Type.Utils import cartesianProduct # also add all cell coordinates in the dictionnary for cell_key in cartesianProduct(context.getCellRange()): for key in cell_key: if key in dependant_dimensions_dict: summary_key_dict[tuple(cell_key)] = 1 break container.REQUEST.set(script.id, summary_key_dict) return summary_key_dict
if matrixbox: # XXX matrixbox is right_display (not as listfield) => invert display and value in item base_category.extend([ (x[1], x[0]) for x in transformation.getVariationCategoryItemList( base_category_list=(c, )) ]) else: base_category.extend( transformation.getVariationCategoryList( base_category_list=(c, ))) if len(base_category) > 0: # Then make a cartesian product # to calculate all possible combinations clist = cartesianProduct(base_category) # XXX is it possible to remove repr ? for c in clist: if matrixbox == 1: # XXX matrixbox is right display tab.append((repr([x[0] for x in c]), repr([x[1] for x in c]))) else: tab.append(repr(c)) # Try fill line first, then column, and after tab for _ in range(2): if line == []: tmp = line line = column column = tmp