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
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