def default_start(self, data): """ Check the amazon settings for the current account :param data: Wizard data """ MWSAccount = Pool().get('amazon.mws.account') account = MWSAccount(Transaction().context.get('active_id')) res = {} api = mws.Feeds( access_key=account.access_key, secret_key=account.secret_key, account_id=account.merchant_id, ) try: api.get_feed_submission_count().parsed res['status'] = 'Account settings have been configured correctly' except mws.MWSError: res['status'] = "Something went wrong. Please check account " + \ "settings again" return res
def run(self): """ Sends API requests to the amazon webstore and publishes all new products """ product_dict = [] xml = ( '<?xml version="1.0" encoding="UTF-8"?>' '<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">' '<Header>' '<DocumentVersion>1.02</DocumentVersion>' '<MerchantIdentifier>M_BESTDEALS_17316086</MerchantIdentifier>' '</Header>' '<MessageType>Product</MessageType>' '<PurgeAndReplace>false</PurgeAndReplace>' '<Message>' '<MessageID>1</MessageID>' '<OperationType>Update</OperationType>' ) for product in self.products: xml += ('<Product>' '<SKU>' + str(product.id) + '</SKU>' '<StandardProductID>' '<Type>ASIN</Type>' '<Value>' + str(product.ASIN) + '</Value>' '</StandardProductID>' '</Product>' '<ProductTaxCode>A_GEN_NOTAX</ProductTaxCode>' '<DescriptionData>' '<Title>Example Product Title</Title>' '<Brand>Example Product Brand</Brand>' '<Description>This is an example product description.</Description>' '<MSRP currency="USD">25.19</MSRP>' '<Manufacturer>Example Product Manufacturer</Manufacturer>' '<ItemType>example-item-type</ItemType>' '</DescriptionData>' ) # xml += xml1 xml += '</Message></AmazonEnvelope>' feed_content = xml raw_input(xml) feed_type = "_POST_PRODUCT_DATA_" req = mws.Feeds( access_key=AWS_ACCESS_KEY_ID, secret_key=SECRET_KEY, account_id=SELLER_ID, region="US" ) try: res = req.submit_feed( feed=xml, feed_type=feed_type ) return res.__dict__ except: traceback.print_exc()
def get_amazon_feed_api(self): """ Return an instance of feed api """ return mws.Feeds( access_key=self.amazon_access_key, secret_key=self.amazon_secret_key, account_id=self.amazon_merchant_id, )
def handle(self, *args, **options): feed_submission_id = args[0] req = mws.Feeds(access_key=AWS_ACCESS_KEY_ID, secret_key=SECRET_KEY, account_id=SELLER_ID, region="US") try: res = req.get_feed_submission_result(feedid=feed_submission_id) print res.__dict__ except: traceback.print_exc()
def export_inventory_to_amazon(cls, products): """Export inventory of the products to the Amazon account in context :param products: List of active records of products """ MWSAccount = Pool().get('amazon.mws.account') mws_account = MWSAccount(Transaction().context['amazon_mws_account']) NS = "http://www.w3.org/2001/XMLSchema-instance" location_attribute = '{%s}noNamespaceSchemaLocation' % NS inventory_xml = [] for product in products: with Transaction().set_context( {'locations': [mws_account.warehouse.id]}): quantity = product.quantity if not quantity: continue if mws_account in [acc.account for acc in product.mws_accounts]: inventory_xml.append( E.Message( E.MessageID(str(product.id)), E.OperationType('Update'), E.Inventory( E.SKU(product.code), E.Quantity(str(round(quantity))), E.FulfillmentLatency( str(product.template.delivery_time)), ))) envelope_xml = E.AmazonEnvelope( E.Header(E.DocumentVersion('1.01'), E.MerchantIdentifier(mws_account.merchant_id)), E.MessageType('Inventory'), E.PurgeAndReplace('false'), *(inv_xml for inv_xml in inventory_xml)) envelope_xml.set(location_attribute, 'amznenvelope.xsd') feeds_api = mws.Feeds(mws_account.access_key, mws_account.secret_key, mws_account.merchant_id) response = feeds_api.submit_feed( etree.tostring(envelope_xml), feed_type='_POST_INVENTORY_AVAILABILITY_DATA_', marketplaceids=[mws_account.marketplace_id]) return response.parsed
def get_feed_submission_list(seller_id, auth_token, feed_ids): feeds_api = mws.Feeds(access_key=MWS_ACCESS_KEY, secret_key=MWS_SECRET_KEY, account_id=seller_id, auth_token=auth_token) feed_submission_return = feeds_api.get_feed_submission_list( feedids=feed_ids, feedtypes=[ '_POST_PRODUCT_DATA_', '_POST_PRODUCT_PRICING_DATA_', '_POST_INVENTORY_AVAILABILITY_DATA_' ], processingstatuses=[ '_DONE_', '_CANCELLED_', '_AWAITING_ASYNCHRONOUS_REPLY_', '_IN_PROGRESS_', '_IN_SAFETY_NET_', '_SUBMITTED_', '_UNCONFIRMED_' ]) return feed_submission_return.parsed['FeedSubmissionInfo']
def get_feed_submission_result(seller_id, auth_token, feed_id): feeds_api = mws.Feeds(access_key=MWS_ACCESS_KEY, secret_key=MWS_SECRET_KEY, account_id=seller_id, auth_token=auth_token) feed_submission_result_return = feeds_api.get_feed_submission_result( feed_id) content_md5 = calc_md5( feed_submission_result_return.response.content).decode('utf-8') if feed_submission_result_return.response.headers[ 'Content-MD5'] != content_md5: logger.error('DATA CORRUPTION') logger.error(feed_submission_result_return.original) logger.error( 'header md5 :: %(header_md5)s != content md5 :: %(content_md5)s' % { 'header_md5': feed_submission_result_return.response.headers['Content-MD5'], 'content_md5': content_md5 }) raise DataCorruptionException() processing_report = feed_submission_result_return.parsed[ 'ProcessingReport'] result_status = ['_DONE_'] log_result = False if processing_report['StatusCode']['value'] != 'Complete': log_result = True result_status.append(processing_report['StatusCode']['value'].upper()) result_status.append('_') processing_summary = processing_report['ProcessingSummary'] if processing_summary: messages_with_error = int( processing_summary['MessagesWithError']['value']) messages_with_warning = int( processing_summary['MessagesWithWarning']['value']) if messages_with_error > 0: log_result = True result_status.append('_WITH_ERROR_') if messages_with_error > 0 and messages_with_warning > 0: result_status.append('_AND_') if messages_with_warning > 0: log_result = True result_status.append('_WITH_WARNING_') if log_result: logger.error(feed_submission_result_return.original) return ''.join(result_status)
def export_pricing_to_amazon(cls, products): """Export prices of the products to the Amazon account in context :param products: List of active records of products """ MWSAccount = Pool().get('amazon.mws.account') mws_account = MWSAccount(Transaction().context['amazon_mws_account']) NS = "http://www.w3.org/2001/XMLSchema-instance" location_attribute = '{%s}noNamespaceSchemaLocation' % NS pricing_xml = [] for product in products: if mws_account in [acc.account for acc in product.mws_accounts]: pricing_xml.append( E.Message( E.MessageID(str(product.id)), E.OperationType('Update'), E.Price( E.SKU(product.code), E.StandardPrice( # TODO: Use a pricelist str(product.template.list_price), currency=mws_account.company.currency.code), ))) envelope_xml = E.AmazonEnvelope( E.Header(E.DocumentVersion('1.01'), E.MerchantIdentifier(mws_account.merchant_id)), E.MessageType('Price'), E.PurgeAndReplace('false'), *(price_xml for price_xml in pricing_xml)) envelope_xml.set(location_attribute, 'amznenvelope.xsd') feeds_api = mws.Feeds(mws_account.access_key, mws_account.secret_key, mws_account.merchant_id) response = feeds_api.submit_feed( etree.tostring(envelope_xml), feed_type='_POST_PRODUCT_PRICING_DATA_', marketplaceids=[mws_account.marketplace_id]) return response.parsed
def update_store(store, items, operation='update'): seller_id = store.seller_id auth_token = store.auth_token store_last_execution = store.last_execution store_name = store.name feeds_api = mws.Feeds(access_key=MWS_ACCESS_KEY, secret_key=MWS_SECRET_KEY, account_id=seller_id, auth_token=auth_token) # NO THROTTLING -> MINUTES=0 if store_last_execution is None or datetime.now( tz=timezone.utc) >= (store_last_execution + timedelta(minutes=0)): if operation == 'update': product_return = feeds_api.submit_feed( build_product_feed_body(seller_id, items), '_POST_PRODUCT_DATA_') price_return = feeds_api.submit_feed( build_price_feed_body(seller_id, items), '_POST_PRODUCT_PRICING_DATA_') inventory_return = feeds_api.submit_feed( build_inventory_feed_body(seller_id, items), '_POST_INVENTORY_AVAILABILITY_DATA_') # logger.info(product_return.response.headers) # logger.info(price_return.response.headers) # logger.info(inventory_return.response.headers) return datetime.now( tz=timezone.utc ), product_return.parsed, price_return.parsed, inventory_return.parsed # SAVE DATETIME NOW FOR THE 20 MINUTES CHECK elif operation == 'delete': product_return = feeds_api.submit_feed( build_product_delete_feed_body(seller_id, items), '_POST_PRODUCT_DATA_') return datetime.now( tz=timezone.utc), product_return.parsed, None, None else: time_left = (store_last_execution + timedelta(minutes=20)) - datetime.now(tz=timezone.utc) minutes = time_left.seconds // 60 raise ThrottlingException( 'Throttling: %(store)s - %(minutes)s minute(s) remaining' % { 'store': store_name, 'minutes': minutes })
def export_to_amazon(cls, products): """Export the products to the Amazon account in context :param products: List of active records of products """ MWSAccount = Pool().get('amazon.mws.account') mws_account = MWSAccount(Transaction().context['amazon_mws_account']) NS = "http://www.w3.org/2001/XMLSchema-instance" location_attribute = '{%s}noNamespaceSchemaLocation' % NS products_xml = [] for product in products: if not product.code: cls.raise_user_error('missing_product_code', {'product': product.template.name}) if not product.codes: cls.raise_user_error('missing_product_codes', {'product': product.template.name}) # Get the product's code to be set as standard ID to amazon product_standard_id = (product.asin or product.ean or product.upc or product.isbn or product.gtin) products_xml.append( E.Message( E.MessageID(str(product.id)), E.OperationType('Update'), E.Product( E.SKU(product.code), E.StandardProductID( E.Type(product_standard_id.code_type.upper()), E.Value(product_standard_id.code), ), E.DescriptionData( E.Title(product.template.name), E.Description(product.description), ), # Amazon needs this information so as to place the product # under a category. # FIXME: Either we need to create all that inside our # system or figure out a way to get all that via API E.ProductData( E.Miscellaneous(E.ProductType('Misc_Other'), ), ), ))) envelope_xml = E.AmazonEnvelope( E.Header(E.DocumentVersion('1.01'), E.MerchantIdentifier(mws_account.merchant_id)), E.MessageType('Product'), E.PurgeAndReplace('false'), *(product_xml for product_xml in products_xml)) envelope_xml.set(location_attribute, 'amznenvelope.xsd') feeds_api = mws.Feeds(mws_account.access_key, mws_account.secret_key, mws_account.merchant_id) response = feeds_api.submit_feed( etree.tostring(envelope_xml), feed_type='_POST_PRODUCT_DATA_', marketplaceids=[mws_account.marketplace_id]) cls.write( products, { 'mws_accounts': [('create', [{ 'product': product.id, 'account': mws_account.id, } for product in products])] }) return response.parsed