def _updateXupdateDel(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to remove elements. """ conflict_list = [] tag = xml.get('select').split('/')[-1] integration_site = document.context.getParentValue() LOG( "Xupdate delete", 0, "tag=%s, previous_xml=%s, xml=%s, kw=%s" % (tag, previous_xml, xml, kw)) if tag.split('[')[0] == 'category': # retrieve the previous xml etree through xpath previous_xml = previous_xml.xpath(tag) try: previous_value = integration_site.getMappingFromCategory( previous_xml[0].text.encode('utf-8'), ) except IndexError: raise IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml) # retrieve the current value to check if exists a conflict current_value = etree.XML(document.asXML()).xpath(tag)[0].text LOG("updateXupdateDel", 0, current_value) current_value = integration_site.getMappingFromCategory( current_value.encode('utf-8')) LOG("updateXupdateDel", 0, current_value) # work on variations variation_brain_list = document.context.getProductCategoryList() for brain in variation_brain_list: if brain.category == current_value and previous_value == current_value: base_category, variation = current_value.split('/', 1) document.context.product_module.deleteProductCategory( product_id=document.getId(), base_category=base_category, variation=variation, ) else: # previous value different from current value conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(previous_value) conflict.setRemoteValue(current_value) conflict_list.append(conflict) else: keyword = { 'product_id': document.getId(), tag: 'NULL', } document.context.product_module.updateProduct(**keyword) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _generateConflict(self, path, tag, xml, current_value, new_value): """ Generate the conflict object """ conflict = Conflict( object_path=path, keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(new_value) return conflict
def _updateXupdateDel(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to remove elements. """ conflict_list = [] tag = xml.get('select').split('/')[-1] integration_site = document.context.getParentValue() LOG("Xupdate delete", 0, "tag=%s, previous_xml=%s, xml=%s, kw=%s" % (tag, previous_xml, xml, kw)) if tag.split('[')[0] == 'category': # retrieve the previous xml etree through xpath previous_xml = previous_xml.xpath(tag) try: previous_value = integration_site.getMappingFromCategory( previous_xml[0].text.encode('utf-8'), ) except IndexError: raise IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml ) # retrieve the current value to check if exists a conflict current_value = etree.XML(document.asXML()).xpath(tag)[0].text LOG("updateXupdateDel", 0, current_value) current_value = integration_site.getMappingFromCategory(current_value.encode('utf-8')) LOG("updateXupdateDel", 0, current_value) # work on variations variation_brain_list = document.context.getProductCategoryList() for brain in variation_brain_list: if brain.category == current_value and previous_value == current_value: base_category, variation = current_value.split('/', 1) document.context.product_module.deleteProductCategory( product_id=document.getId(), base_category=base_category, variation=variation, ) else: # previous value different from current value conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(previous_value) conflict.setRemoteValue(current_value) conflict_list.append(conflict) else: keyword = {'product_id': document.getId(), tag: 'NULL' , } document.context.product_module.updateProduct(**keyword) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateInsertOrAdd(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to add elements. """ conflict_list = [] for subnode in xml.getchildren(): tag = subnode.attrib['name'] value = subnode.text if tag == 'address': keyword = { 'person_id': document.getId(), } my_phone = '' for my_subnode in xml.getchildren(): if my_subnode.attrib['name'] == "phone": my_phone = my_subnode.text if my_phone: keyword['phone'] = my_phone else: keyword['phone'] = '' for subsubnode in subnode.getchildren(): if subsubnode.tag == 'country': # through the mapping retrieve the country keyword[subsubnode. tag] = document.context.getMappingFromCategory( 'region/%s' % subsubnode.text, ).split( '/', 1)[-1] else: keyword[subsubnode.tag] = subsubnode.text document.context.person_module.createPersonAddress(**keyword) elif tag in ['street', 'zip', 'city', 'country']: try: # work on the case: "/node/address[x]" address_index = int( xml.get('select').split('address[')[-1].split(']') [0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [(' '.join([ getattr(address, i, '') for i in ['street', 'zip', 'city', 'country'] ]), address) for address in address_list] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict.setRemoteValue(value) conflict_list.append(conflict) return conflict_list # set the keyword dict which defines what will be updated keyword = { 'person_id': document.getId(), 'address_id': address.getId(), } if tag == 'country': # through the mapping retrieve the country mapping = document.context.getMappingFromCategory( 'region/%s' % value) value = mapping.split('/', 1)[-1] keyword[tag] = value document.context.person_module.updatePersonAddress( address.getId(), **keyword) else: # XXX: when the DateTime format will be required to sync date # - 1 - retrieve the format through the integration site # - 2 - through using of DateTime build the date and render it # if tag == 'birthday': # integration_site = self.getIntegrationSite(kw.get('domain')) # date_format = integration_site.getDateFormat() # # build the required format # format = dict_format[date_format] -> render "%Y/%m/%d", ... # value = DateTime(value).strftime(format) keyword = { 'person_id': document.getId(), tag: value, } document.context.person_module.updatePerson(**keyword) new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateDel(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to remove elements. """ conflict_list = [] tag = xml.get('select').split('/')[-1] # this variable is used to retrieve the id of address and to not remove the # orginal tag (address, street, zip, city or country) tag_for_id = tag # specific work for address and address elements if tag.split('[')[0] in [ 'address', 'street', 'zip', 'city', 'country' ]: # work on the good part of the xml to retrieve the address id if tag_for_id.split('[')[0] != 'address': tag_for_id = xml.get('select') try: # work on the case: "/node/address[x]" address_index = int( tag_for_id.split('[')[-1].split(']')[0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [(' '.join([ getattr(address, i, '') for i in ['street', 'zip', 'city', 'country'] ]), address) for address in address_list] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict_list.append(conflict) return conflict_list # remove the corresponding address or the element of the address keyword = { 'person_id': document.getId(), 'address_id': address.getId() } if tag.split('[')[0] == 'address': document.context.person_module.deletePersonAddress(**keyword) else: # set the keyword dict which defines what will be updated keyword[tag] = 'NULL' document.context.person_module.updatePersonAddress(**keyword) else: keyword = { 'person_id': document.getId(), tag: 'NULL', } document.context.person_module.updatePerson(**keyword) new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) # it always return conflict_list but it's empty return conflict_list
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] 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 IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml) # check if it'a work on person or on address if tag in ['street', 'zip', 'city', 'country']: try: # work on the case: "/node/address[x]" address_index = \ int(xpath_expression.split('address[')[-1].split(']')[0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [(' '.join( [address.street, address.zip, address.city, address.country]), address) for address in address_list] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict.setRemoteValue(value) conflict_list.append(conflict) return conflict_list current_value = getattr(address, tag, None) if current_value not in [value, previous_value]: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(value) conflict_list.append(conflict) else: # set the keyword dict which defines what will be updated keyword = { 'address_id': address.getId(), 'person_id': document.getId(), } if tag == 'country': # through the mapping retrieve the country mapping = document.context.getMappingFromCategory( 'region/%s' % value) value = mapping.split('/', 1)[-1] keyword[tag] = value document.context.person_module.updatePersonAddress(**keyword) else: # getter used to retrieve the current values and to check conflicts property_list = [ 'birthday', 'phone', 'fax', ] getter_value_dict = dict([ (prop, getattr(document, prop)) for prop in property_list if getattr(document, prop, None) is not None ]) # 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 current_value not in [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(value) conflict_list.append(conflict) else: # XXX: when the DateTime format will be required to sync date # - 1 - retrieve the format through the integration site # - 2 - through using of DateTime build the date and render it # if tag == 'birthday': # integration_site = self.getIntegrationSite(kw.get('domain')) # date_format = integration_site.getDateFormat() # # build the required format # format = dict_format[date_format] -> render "%Y/%m/%d", ... # value = DateTime(value).strftime(format) keyword = { 'person_id': document.getId(), tag: value, } document.context.person_module.updatePerson(**keyword) new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateUpdate(self, document=None, xml=None, previous_xml=None, request_parameter_dict=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] 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 IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml) if previous_value is None: previous_value = "" conflicted = False if tag in ADDRESS_TAG_LIST: LOG("updating tag %s to %s" % (tag, value), 300, "") # There is just one address in oxatis, it is the billing one current_value = getattr(document, tag, '') if current_value not in [value, previous_value]: conflicted = True else: if tag == "country": mapping = document.context.getMappingFromCategory( 'region/%s' % value) value = mapping.split('/', 1)[-1] request_parameter_dict['billing_address_country'] = value elif tag == 'street': request_parameter_dict["billing_address_street"] = value # also add lines street_lines = value.split('\n') i = 1 for street_line in street_lines: request_parameter_dict["billing_address_street_l%s" % (i)] = street_line i += 1 else: request_parameter_dict["billing_address_%s" % (tag)] = value else: # Not specific tags current_value = getattr(document, tag, '') if current_value not in [value, previous_value]: conflicted = True # Update tag to specific name if tag in BILLING_TAG_LIST: tag = "billing_%s" % (tag) request_parameter_dict[tag] = value # Return conflict if any if conflicted: conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(value) conflict_list.append(conflict) LOG("update returns %s / %s" % (conflict_list, request_parameter_dict), 300, "") return conflict_list, request_parameter_dict
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 ) if isinstance(previous_value, unicode): previous_value = previous_value.encode('utf-8') if isinstance(new_value, unicode): new_value = new_value.encode('utf-8') # check if it'a work on product or on categories if tag.split('[')[0] == 'category': # call the method which allows to work on a specific part, the update of # categories conflict_list += self._updateCategory(document, xml, previous_value) 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 isinstance(current_value, unicode): current_value = current_value.encode('utf-8') 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) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
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] 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 IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml ) # check if it'a work on person or on address if tag in ['street', 'zip', 'city', 'country']: try: # work on the case: "/node/address[x]" address_index = \ int(xpath_expression.split('address[')[-1].split(']')[0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [ (' '.join([address.street, address.zip, address.city, address.country]), address) for address in address_list] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict.setRemoteValue(value) conflict_list.append(conflict) return conflict_list current_value = getattr(address, tag, None) if current_value not in [value, previous_value]: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(value) conflict_list.append(conflict) else: # set the keyword dict which defines what will be updated keyword = { 'address_id': address.getId(), 'person_id': document.getId(), } if tag == 'country': # through the mapping retrieve the country mapping = document.context.getMappingFromCategory('region/%s' % value) value = mapping.split('/', 1)[-1] keyword[tag] = value document.context.person_module.updatePersonAddress(**keyword) else: # getter used to retrieve the current values and to check conflicts property_list = ['birthday', ] getter_value_dict = dict([ (prop, getattr(document, prop)) for prop in property_list if getattr(document, prop, None) is not None ]) # 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 current_value not in [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(value) conflict_list.append(conflict) else: # XXX: when the DateTime format will be required to sync date # - 1 - retrieve the format through the integration site # - 2 - through using of DateTime build the date and render it # if tag == 'birthday': # integration_site = self.getIntegrationSite(kw.get('domain')) # date_format = integration_site.getDateFormat() # # build the required format # format = dict_format[date_format] -> render "%Y/%m/%d", ... # value = DateTime(value).strftime(format) keyword = {'person_id': document.getId(), tag: value, } document.context.person_module.updatePerson(**keyword) new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateInsertOrAdd(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to add elements. """ conflict_list = [] for subnode in xml.getchildren(): tag = subnode.attrib['name'] value = subnode.text if tag == 'address': keyword = {'person_id': document.getId(), } for subsubnode in subnode.getchildren(): if subsubnode.tag == 'country': # through the mapping retrieve the country keyword[subsubnode.tag] = document.context.getMappingFromCategory( 'region/%s' % subsubnode.text, ).split('/', 1)[-1] else: keyword[subsubnode.tag] = subsubnode.text document.context.person_module.createPersonAddress(**keyword) elif tag in ['street', 'zip', 'city', 'country']: try: # work on the case: "/node/address[x]" address_index = int(xml.get('select').split('address[')[-1].split(']')[0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [ (' '.join([ getattr(address, i, '') for i in ['street', 'zip', 'city','country']] ), address) for address in address_list ] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict.setRemoteValue(value) conflict_list.append(conflict) return conflict_list # set the keyword dict which defines what will be updated keyword = { 'person_id': document.getId(), 'address_id': address.getId(), } if tag == 'country': # through the mapping retrieve the country mapping = document.context.getMappingFromCategory('region/%s' % value) value = mapping.split('/', 1)[-1] keyword[tag] = value document.context.person_module.updatePersonAddress(**keyword) else: # XXX: when the DateTime format will be required to sync date # - 1 - retrieve the format through the integration site # - 2 - through using of DateTime build the date and render it # if tag == 'birthday': # integration_site = self.getIntegrationSite(kw.get('domain')) # date_format = integration_site.getDateFormat() # # build the required format # format = dict_format[date_format] -> render "%Y/%m/%d", ... # value = DateTime(value).strftime(format) keyword = {'person_id': document.getId(), tag:value, } document.context.person_module.updatePerson(**keyword) new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateDel(self, document=None, xml=None, previous_xml=None, **kw): """ This method is called in updateNode and allows to remove elements. """ conflict_list = [] tag = xml.get('select').split('/')[-1] # this variable is used to retrieve the id of address and to not remove the # orginal tag (address, street, zip, city or country) tag_for_id = tag # specific work for address and address elements if tag.split('[')[0] in ['address', 'street', 'zip', 'city', 'country']: # work on the good part of the xml to retrieve the address id if tag_for_id.split('[')[0] != 'address': tag_for_id = xml.get('select') try: # work on the case: "/node/address[x]" address_index = int(tag_for_id.split('[')[-1].split(']')[0]) - 1 except ValueError: # Work on the case: "/node/address" address_index = 0 # build the address list address_list = document.context.person_module.getPersonAddressList( person_id=document.getId(), ) # FIXME: Is the sort can be removed ??? # Build a list of tuple which contains : # - first, the title build to realise the sort # - the second element is the brain itself sorted_address_list = [ (' '.join([ getattr(address, i, '') for i in ['street', 'zip', 'city','country']] ), address) for address in address_list ] sorted_address_list.sort() address_list = [t[1] for t in sorted_address_list] try: address = address_list[address_index] except IndexError: # create and fill a conflict when the integration site value, the erp5 # value and the previous value are differents conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(None) conflict_list.append(conflict) return conflict_list # remove the corresponding address or the element of the address keyword = {'person_id': document.getId(), 'address_id': address.getId()} if tag.split('[')[0] == 'address': document.context.person_module.deletePersonAddress(**keyword) else: # set the keyword dict which defines what will be updated keyword[tag] = 'NULL' document.context.person_module.updatePersonAddress(**keyword) else: keyword = {'person_id': document.getId(), tag: 'NULL', } document.context.person_module.updatePerson(**keyword) # it always return conflict_list but it's empty new_document = document.context.person_module[document.getId()] document.updateProperties(new_document) return conflict_list
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) if isinstance(previous_value, unicode): previous_value = previous_value.encode('utf-8') if isinstance(new_value, unicode): new_value = new_value.encode('utf-8') # check if it's a work on product or on categories if tag.split('[')[0] == 'category': # call the method which allows to work on a specific part, the update of # categories LOG("_updateXupdateUpdate ", 0, "previous_value=%s" % previous_value) LOG("_updateXupdateUpdate ", 0, "new_value=%s" % new_value) conflict_list += self._updateCategory(document, xml, previous_value, new_value) else: # getter used to retrieve the current values and to check conflicts property_list = ['title', 'reference', 'description', 'sale_price'] 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 isinstance(current_value, unicode): current_value = current_value.encode('utf-8') 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, } #LOG("update product", 0, "update keyword=%s" % keyword) document.context.product_module.updateProduct(**keyword) new_document = document.context.product_module[document.getId()] document.updateProperties(new_document) return conflict_list
def _updateXupdateUpdate(self, document=None, xml=None, previous_xml=None, request_parameter_dict=None, **kw): """ This method is called in updateNode and allows to work on the update of elements. """ LOG("calling updateXupdateUpdate", 300, request_parameter_dict) conflict_list = [] xpath_expression = xml.get('select') tag = xpath_expression.split('/')[-1] 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 IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml ) if previous_value is None: previous_value = "" conflicted = False if tag in ADDRESS_TAG_LIST: LOG("updating tag %s to %s" %(tag, value), 300, "") # There is just one address in oxatis, it is the billing one current_value = getattr(document, tag, '') if current_value not in [value, previous_value]: conflicted = True else: if tag == "country": mapping = document.context.getMappingFromCategory('region/%s' % value) value = mapping.split('/', 1)[-1] request_parameter_dict['country'] = value else: request_parameter_dict["%s" %(tag)] = value else: # Not specific tags current_value = getattr(document, tag, '') if current_value not in [value, previous_value]: conflicted = True # Update tag to specific name if tag in BILLING_TAG_LIST: tag = "%s" %(tag) request_parameter_dict[tag] = value # Return conflict if any if conflicted: conflict = Conflict( object_path=document.getPhysicalPath(), keyword=tag, ) conflict.setXupdate(etree.tostring(xml, encoding='utf-8')) conflict.setLocalValue(current_value) conflict.setRemoteValue(value) conflict_list.append(conflict) LOG("update returns %s / %s" %(conflict_list, request_parameter_dict), 300, "") return conflict_list, request_parameter_dict
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 = ['title', '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 _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] new_value = xml.text keyword = {} # retrieve the previous xml etree through xpath previous_xml = previous_xml.xpath(xpath_expression) try: previous_value = previous_xml[0].text except IndexError: raise IndexError, 'Too little or too many value, only one is required for %s' % ( previous_xml, ) if isinstance(previous_value, unicode): previous_value = previous_value.encode('utf-8') if isinstance(new_value, unicode): new_value = new_value.encode('utf-8') # check if it'a work on product or on categories if tag.split('[')[0] == 'category': # init base category, variation and boolean which check update base_category, variation = new_value.split('/', 1) old_base_category, old_variation = previous_value.split('/', 1) # retrieve the base_categories and the variations base_category_list = document.getVariationBaseCategoryList() variation_list = document.getVariationCategoryList() # about shared and individual variations, it's necessary to check the # mapping existency shared_variation = True try: # Try to access the category category = document.getPortalObject().portal_categories.restrictedTraverse(new_value) except KeyError: # This is an individual variation shared_variation = False # the mapping of an element must only be defined one time individual_variation = document.searchFolder( portal_type='Product Individual Variation', title=old_variation, base_category=old_base_category, ) # If this is badly defined, fix the objects if len(individual_variation) > 1: id_to_remove = [] for individual in individual_variation[1:]: id_to_remove.append(individual.getId()) document.manage_delObjects(id_to_remove) if len(individual_variation) and previous_value in variation_list: for individual in individual_variation: id_to_remove.append(individual.getId()) document.manage_delObjects(id_to_remove) # Update variation if not shared_variation: # work on the cases : # new = individual variation # old = individual variation -> update # old = shared variation -> remoce shared and add individual # Fist check individual base if base_category not in document.getIndividualVariationBaseCategoryList(): base_category_list = document.getIndividualVariationBaseCategoryList() base_category_list.append(base_category) document.setIndividualVariationBaseCategoryList(base_category_list) self.updateSystemPreference(document.getPortalObject(), base_category, True) # Then update or add variation if len(individual_variation): individual_variation = individual_variation[0].getObject() individual_variation.setTitle(variation) individual_variation.setVariationBaseCategory(base_category) else: # create the individual variation document.newContent( portal_type='Product Individual Variation', title=variation, base_category=base_category, ) else: # work on the cases : # new = shared variation # old = individual variation -> remove individual and add shared # old = shared variation -> update shared if len(individual_variation): # remove individual if previous was that document.manage_delObjects([individual_variation[0].getId(), ]) else: # remove the shared from the list if it's a shared variation_list.remove(previous_value) # set the base category and the variations if base_category not in document._baseGetVariationBaseCategoryList(): base_category_list = document._baseGetVariationBaseCategoryList() base_category_list.append(base_category) document.setVariationBaseCategoryList(base_category_list) self.updateSystemPreference(document.getPortalObject(), base_category) if new_value not in variation_list: variation_list.append(new_value) document.setVariationCategoryList(variation_list) else: # getter used to retrieve the current values and to check conflicts getter_value_dict = { 'title': document.getTitle(), 'reference': document.getReference(), 'ean13': document.getEan13Code(), 'description': document.getDescription(), } # 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 isinstance(current_value, float): current_value = '%.6f' % current_value if isinstance(current_value, unicode): current_value = current_value.encode('utf-8') 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[tag] = new_value self.editDocument(object=document, **keyword) return conflict_list