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
Beispiel #2
0
 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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
  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
Beispiel #9
0
  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
Beispiel #10
0
  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
Beispiel #11
0
  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
Beispiel #13
0
  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
Beispiel #15
0
  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