示例#1
0
    def update_presta_data(self, data_list):
        """data_list = """
        domain = self.shop.domain
        authheader = self.shop.authheader
        headers = {"Authorization": self.shop.authheader}
        total_results = {'errors': []}

        # count how many products were updated
        total_price = 0
        total_count = 0
        # set to true if we find products that depend on stock
        depends_on_stock = False

        for row in data_list:
            id = row[0]
            id_attribute = row[1]
            is_combination = bool(id_attribute != '0')

            # PRICE update goes first -----------------
            if is_combination:
                resource = 'combinations/' + str(id_attribute)
            else:
                resource = 'products/' + str(id)

            if 'base_price' in row[2]:
                try:
                    # TODO: we're always replacing the price here, so we don't actually need it, but keep it for consistency with 1.4
                    req = urllib2.Request("http://%s/api/%s?price[base_price][use_reduction]=0&price[base_price][use_tax]=0" % (domain, resource),
                                          headers={'Content-Type': 'text/xml',
                                                   'Authorization': authheader})
                    xml = urllib2.urlopen(req).read()
                    xml = clean_chunked_data(xml)
                    xml = xml.decode('utf-8')

                    # replace base_price with price for combinations
                    if is_combination:
                        price = re.findall(ur'<price>(.*)</price>', xml)[0]
                        xml = re.sub(ur'(?<=<base_price>)(.*)(?=</base_price>)', price, xml)

                    for attr_name, attr_value in row[2].items():
                        xml = re.sub(ur'<{0}>(.*)</{0}>'.format(attr_name),
                                     u'<{0}>{1}</{0}>'.format(attr_name, '<![CDATA[{0}]]>'.format(attr_value)), xml)
                    # remove non-settable fields
                    xml = re.sub(r'<id_default_image(.+)</id_default_image>', '', xml)
                    xml = re.sub(r'<position_in_category(.+)</position_in_category>', '', xml)
                    xml = re.sub(r'<manufacturer_name(.+)</manufacturer_name>', '', xml)
                    xml = re.sub(r'<associations>(.+)</associations>(?s)', '', xml)
                    # replace price with base_price
                    base_price = re.findall(ur'<base_price>(.*)</base_price>', xml)[0]
                    xml = re.sub(ur'(?<=<price>)(.*)(?=</price>)', base_price, xml)
                    # replace quantity. it's not writable anymore
                    xml = re.sub(r'<quantity(.*)</quantity>', '', xml)

                    req = urllib2.Request(str("http://%s/api/%s" % (domain, resource)),
                                          headers={'Content-Type': 'application/x-www-form-urlencoded',
                                                   'Authorization': authheader})
                    req.get_method = lambda: 'PUT'
                    urllib2.urlopen(req, data=xml.encode('utf-8'))
                    total_price += 1
                except urllib2.HTTPError as e:
                    err_msg = e.fp.read()
                    total_results['errors'].append({'message': str(e), 'details': err_msg,
                                                    'product': id,
                                                    'combination': int(id_attribute)})
                except HTTPException as e:
                    total_results['errors'].append({'message': str(e), 'details': e.message,
                                                    'product': id,
                                                    'combination': int(id_attribute)})
            # END PRICE ---------------------------------

            # Quantity is not present for main product with combinations
            if 'quantity' in row[2]:
                # find right stock id
                stocks = get_xml_data("http://%s/api/%s?filter[id_product]=[%s]&filter[id_product_attribute]=[%s]"
                                      % (domain, 'stock_availables', id, id_attribute), headers)
                stock_id = stocks.findall('.//stock_available')
                if stock_id:
                    stock_id = stock_id[0].attrib['id']
                    req = urllib2.Request("http://%s/api/%s/%s" % (domain, 'stock_availables', stock_id),
                                          headers={'Content-Type': 'text/xml',
                                                   'Authorization': authheader})
                    xml = urllib2.urlopen(req).read()
                    xml = clean_chunked_data(xml)
                    xml = xml.decode('utf-8')
                    for attr_name, attr_value in row[2].items():
                        xml = re.sub(r'<{0}>(.*)</{0}>'.format(attr_name),
                                     '<{0}>{1}</{0}>'.format(attr_name, attr_value), xml)

                    # TODO: write test for it, otherwise prestashop returns error
                    if id_attribute == '0':
                        xml = xml.replace('<id_product_attribute></id_product_attribute>',
                                          '<id_product_attribute>0</id_product_attribute>')

                    # TODO: write test for depends on stock
                    if '<depends_on_stock><![CDATA[1]]></depends_on_stock>' in xml:
                        depends_on_stock = True
                        continue

                    try:
                        req = urllib2.Request(str("http://%s/api/%s/%s" % (domain, 'stock_availables', stock_id)),
                                              headers={'Content-Type': 'application/x-www-form-urlencoded',
                                                       'Authorization': authheader})
                        req.get_method = lambda: 'PUT'
                        urllib2.urlopen(req, data=xml.encode('utf-8'))
                        total_count += 1
                    except urllib2.HTTPError as e:
                        err_msg = e.fp.read()
                        total_results['errors'].append({'message': str(e), 'details': err_msg,
                                                        'product': id, 'combination': int(id_attribute)})
                    except HTTPException as e:
                        total_results['errors'].append({'message': str(e), 'details': e.message,
                                                        'product': id, 'combination': int(id_attribute)})
                else:
                    # stock not available, report it
                    total_results['errors'].append({'message': _('No stock available'), 'details': _('No stock available'),
                                                    'product': id, 'combination': int(id_attribute)})
        if depends_on_stock:
            total_results['result'] = '15_depends_on_stock'
        if total_count or total_price:
            total_results['result'] = 'update_ok'
        else:
            total_results['result'] = '14_update_permission'
        total_results['count'] = total_count
        return total_results
示例#2
0
    def update_presta_data(self, data_list):
        """data_list = """
        domain = self.shop.domain
        authheader = self.shop.authheader
        total_results = {'errors': []}

        total = 0
        for row in data_list:
            id = row[0]
            id_attribute = row[1]
            is_combination = bool(id_attribute != '0')

            if is_combination:
                resource = 'combinations/' + str(id_attribute)
            else:
                resource = 'products/' + str(id)

            req = urllib2.Request("http://%s/api/%s?price[base_price][use_reduction]=0&price[base_price][use_tax]=0" % (domain, resource),
                                  headers={'Content-Type': 'text/xml',
                                           'Authorization': authheader})
            try:
                xml = urllib2.urlopen(req).read()
            except urllib2.HTTPError as e:
                err_msg = e.fp.read()
                total_results['errors'].append({'message': str(e), 'details': err_msg,
                                                'product': id, 'combination': int(id_attribute)})
                continue

            xml = clean_chunked_data(xml)
            xml = xml.decode('utf-8')
            # replace base_price with price for combinations
            if is_combination:
                price = re.findall(ur'<price>(.*)</price>', xml)[0]
                xml = re.sub(ur'(?<=<base_price>)(.*)(?=</base_price>)', price, xml)

            for attr_name, attr_value in row[2].items():
                xml = re.sub(ur'<{0}>(.*)</{0}>'.format(attr_name),
                             u'<{0}>{1}</{0}>'.format(attr_name, attr_value), xml)
            # remove non-settable fields
            xml = re.sub(r'<id_default_image(.+)</id_default_image>', '', xml)
            xml = re.sub(r'<position_in_category(.+)</position_in_category>', '', xml)
            xml = re.sub(r'<manufacturer_name(.+)</manufacturer_name>', '', xml)
            xml = re.sub(r'<associations>(.+)</associations>(?s)', '', xml)
            # replace price with base_price
            base_price = re.findall(ur'<base_price>(.*)</base_price>', xml)[0]
            xml = re.sub(ur'(?<=<price>)(.*)(?=</price>)', base_price, xml)
            # replace empty price
            xml = xml.replace(u'<price></price>', u'<price>0</price>')

            req = urllib2.Request(str("http://%s/api/%s" % (domain, resource)),
                                  headers={'Content-Type': 'application/x-www-form-urlencoded',
                                           'Authorization': authheader})
            req.get_method = lambda: 'PUT'

            try:
                urllib2.urlopen(req, data=xml.encode('utf-8'))
                total += 1
            except urllib2.HTTPError as e:
                err_msg = e.fp.read()
                total_results['errors'].append({'message': str(e), 'details': err_msg,
                                                'product': id, 'combination': int(id_attribute)})
            except HTTPException as e:
                total_results['errors'].append({'message': str(e), 'details': e.message,
                                                'product': id, 'combination': int(id_attribute)})

        if total:
            total_results['result'] = 'update_ok'
        else:
            total_results['result'] = '14_update_permission'
        total_results['count'] = total
        return total_results