# -*- coding: UTF-8 -*- # This file is part electronic_mail_template module for Tryton. # The COPYRIGHT file at the top level of this repository contains # the full copyright notices and license terms. from decimal import Decimal from trytond.pool import Pool from trytond.transaction import Transaction import requests from urllib.parse import urlencode from datetime import datetime, date # from .web_channel import SaleWebChannel # from .web import Shop import json from .exceptions import NotProductFoundError, NotProductFound from trytond.i18n import gettext from trytond.exceptions import UserError HEADERS = { 'Accept': 'application/json', 'Content-type': 'application/json' } # class MercadoLibreTwo(Shop): # 'MercadoLibre' # __name__ = 'sale.web_channel.mercado_libre' # @classmethod # def __setup__(cls): # super(MercadoLibre, cls).__setup__() # def _get_context(self): # user_ = self._get_user() # return { # 'company': user_.company.id, # 'user': user_.id, # 'shops': [user_.shop.id], # 'shop': user_.shop.id, # 'language': 'es' # } # def _get_user(self): # User = Pool().get('res.user') # user, = User.search([ # ('login', '=', 'mercado.libre') # ]) # return user # def _create_product(self, codes, line={}): # item = line['item'] # pool = Pool() # Product = pool.get('product.product') # Template = pool.get('product.template') # description = '' # if item.get('variation_attributes'): # var = item['variation_attributes'][0] # if var['id'] and var['name']: # description = var['id'] + ' ' + var['name'] # create_template = { # 'name': item['title'], # 'list_price': line['unit_price'], # 'sale_price_w_tax': line['full_unit_price'], # 'type': 'goods', # 'salable': True, # 'purchasable': True, # 'purchase_uom': 1, # 'sale_uom': 1, # 'default_uom': 1, # 'account_category': 7, # } # template, = Template.create([create_template]) # create_product = [] # for code in codes: # create_product.append({ # 'code': code, # 'description': description, # 'template': template.id # }) # return Product.create(create_product) # def _create_party(self, customer): # _pool = Pool() # City = _pool.get('party.city_code') # Party = _pool.get('party.party') # PartyObligationTax = _pool.get('party.obligation_tax') # email = customer.get('email', '@') # shipment_address, phone, city = '', '', None # if customer.get('receiver_address'): # receiver_address = customer['receiver_address'] # shipment_address = receiver_address['address_line'] # phone = receiver_address['receiver_phone'] or '000' # city_name = receiver_address['city']['name'] # if city_name: # cities = City.search([ # ('name', '=', city_name) # ]) # if cities: # city = cities[0] # if customer['billing_info']['doc_type'] == 'NIT': # type_document = '31' # customer_name = customer['billing_info']['business_name'] # type_person = 'persona_juridica' # else: # customer_name = customer['billing_info']['first_name'] + ' ' + customer['billing_info']['last_name'] # type_document = '13' # type_person = 'persona_natural' # create_customer = { # 'id_reference': str(customer['id']), # 'name': customer_name.upper(), # 'type_document': type_document, # 'type_person': type_person, # 'id_number': customer['billing_info']['doc_number'], # 'addresses': [('create', [{ # 'street': shipment_address, # }])], # 'contact_mechanisms': [ # ('create', [ # {'type': 'phone', 'value': phone}, # {'type': 'email', 'value': email}, # ]) # ] # } # if not city: # city = City(149) # create_customer['addresses'][0][1][0]['department_code'] = city.department.id # create_customer['addresses'][0][1][0]['city_code'] = city.id # party, = Party.create([create_customer]) # PartyObligationTax.create([{ # 'party': party.id, # 'obligation_fiscal': 6, # }]) # return party # def get_shipment_api(self, shipment_id): # if not shipment_id: # return None # URI = 'https://api.mercadolibre.com/shipments/%s?access_token=%s' % ( # shipment_id, self.access_token) # res = self.get_response(URI) # return res.json() # def get_billing_info_api(self, order_id): # if not order_id: # return None # URI = 'https://api.mercadolibre.com/orders/%s/billing_info?access_token=%s' % ( # order_id, self.access_token) # res = self.get_response(URI) # return res.json() # def _return_sale(self, sale): # pool = Pool() # Sale = pool.get('sale.sale') # Date = pool.get('ir.date') # ctx = self._get_context() # dev_sales = [] # sales = [sale] # if sale.pack_id: # sales = Sale.search([ # ('pack_id', '=', sale.pack_id) # ]) # with Transaction().set_context(ctx): # return_sales = Sale.copy(sales) # for return_sale, sale in zip(return_sales, sales): # return_sale.origin = sale # return_sale.reference = sale.reference # return_sale.state = 'draft' # return_sale.sale_date = Date.today() # if sale.invoice_type == '1': # return_sale.invoice_type = '91' # for line in return_sale.lines: # if line.type == 'line': # line.quantity *= -1 # line.save() # if return_sale.untaxed_amount_cache: # return_sale.untaxed_amount_cache *= -1 # if return_sale.tax_amount_cache: # return_sale.tax_amount_cache *= -1 # if return_sale.total_amount_cache: # return_sale.total_amount_cache *= -1 # return_sale.save() # Sale.quote([return_sale]) # Sale.write([return_sale], {'state': 'confirmed'}) # dev_sales.append(return_sale) # return dev_sales # def create_lines_sale(self, sale, sale_, freight=False): # _pool = Pool() # SaleLine = _pool.get('sale.line') # Product = _pool.get('product.product') # create_lines = [] # sale_items = sale_['order_items'] # ctx = self._get_context() # sfm_id = sale_['shipping']['id'] # # reference = sale.reference.split(',') # # reference_order = str(sale_['id']) # # if reference_order not in reference: # # sale.referece = sale.reference + ',' + reference_order # # sale.save() # with Transaction().set_context(ctx): # for line in sale_items: # item = line['item'] # sku_code = item['seller_sku'] # if sku_code: # generic = False # if sku_code.count('+') > 0: # codes = sku_code.split('+') # line['unit_price'] = Decimal( # round((line['unit_price'] / 2), 2)) # else: # codes = [sku_code] # products = Product.search([ # ('code', 'in', codes), # ('active', '=', True) # ]) # description = '' # if not products: # products = self._create_product(codes, line) # else: # if not self.generic_product: # raise NotProductFoundError( # gettext('sale_web_channel.msg_product_generic_not_found')) # products = [self.generic_product] # generic = True # description = '' # raise NotProductFound( # gettext('sale_web_channel.msg_product_not_found', s=self.generic_product.rec_name)) # for product in products: # Tax = _pool.get('account.tax') # un_price = Tax.reverse_compute(Decimal(line['unit_price']), # product.customer_taxes_used) # create_lines.append({ # 'sale': sale.id, # 'type': 'line', # 'unit': product.default_uom.id, # 'quantity': line['quantity'], # 'unit_price': round(Decimal(un_price), 3), # 'unit_price_full': Decimal(line['unit_price']), # 'product': product.id, # 'taxes': [('add', product.customer_taxes_used)], # 'description': description, # }) # if freight and self.freight_product: # product = self.freight_product # URI = 'https://api.mercadolibre.com/shipments/%s/costs?access_token=%s' % ( # sfm_id, self.access_token) # result = self.get_response(URI).json() # shipping_amount = result['receiver']['cost'] # create_lines.append({ # 'sale': sale.id, # 'type': 'line', # 'unit': product.default_uom.id, # 'quantity': 1, # 'unit_price': Decimal(shipping_amount), # 'unit_price_full': Decimal(shipping_amount), # 'product': product.id, # 'description': 'FLETE', # }) # SaleLine.create(create_lines) # return generic # def validate_sale(self, sale_): # if sale_.get('pack_id'): # # if not sale_.get('shipping'): # # return # # shipment_id = sale_['shipping']['id'] # # URI = 'https://api.mercadolibre.com/shipments/%s/items?access_token=%s' % ( # # shipment_id, self.access_token) # # res = self.get_response(URI) # # shipment_items = res.json() # # if len(shipment_items) > 1: # URI = 'https://api.mercadolibre.com/packs/%s?access_token=%s' % ( # sale_.get('pack_id'), self.access_token) # response = self.get_response(URI) # response = response.json() # if response.get('orders'): # ids = '' # for item in response['orders']: # order_id = str(item['id']) # if order_id != str(sale_['id']): # URI2 = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % ( # order_id, self.access_token) # order = self.get_response(URI2) # sale_order = order.json() # ids += ',' + order_id # sale_['order_items'].extend(sale_order['order_items']) # sale_['id'] = str(sale_['id']) + ids # return self._create_sale(sale_) # else: # return self._create_sale(sale_) # else: # return self._create_sale(sale_) # def _create_sale(self, sale_): # _pool = Pool() # Sale = _pool.get('sale.sale') # print(sale_, 'que eres amigo') # reference = '%' + str(sale_['id']).split(',')[0] + '%' # dom = [ # ('reference', 'like', reference) # ] # sales = Sale.search(dom) # if sales: # if len(sales) == 1 and sale_['status'] == 'cancelled': # sale = sales[0] # if not sale.invoices: # self.cancel_sales([sale], sale.pack_id) # else: # dev_sales = self._return_sale(sale) # self._finish_sale(dev_sales[0], type='return') # return True # return False # Party = _pool.get('party.party') # User = _pool.get('res.user') # sfm_id = sale_['shipping']['id'] # shipment_ = self.get_shipment_api(sfm_id) # if sale_.get('buyer'): # sale_id = str(sale_['id']).split(',')[0] # billing_info = self.get_billing_info_api(sale_id) # customer = sale_['buyer'] # dom_party = [('id_reference', '=', str(customer['id']))] # if billing_info and billing_info['billing_info'].get('doc_number'): # dom_party = [('id_number', '=', str( # billing_info['billing_info']['doc_number']))] # parties = Party.search(dom_party) # if parties: # party = parties[0] # else: # customer['receiver_address'] = shipment_['receiver_address'] # customer['billing_info'] = billing_info['billing_info'] # for dic in customer['billing_info']['additional_info']: # customer['billing_info'][list(dic.values())[0].lower() # ] = list(dic.values())[1] # try: # customer['billing_info']['additional_info'].pop() # except Exception as e: # msg = 'sin informacion de tercero' + e # raise UserError( # gettext('sale_web_channel.msg_billing_info', msg=msg)) # party = self._create_party(customer) # ctx = self._get_context() # user_ = User(ctx['user']) # date_created = sale_['date_created'].split('T') # year, month, day = date_created[0].split('-') # sale_date = date(int(year), int(month), int(day)) # with Transaction().set_user(ctx['user']): # sale, = Sale.create([{ # 'payment_term': 1, # 'party': party.id, # 'sale_date': sale_date, # 'comment': shipment_['status'], # 'state': 'draft', # 'company': ctx['company'], # 'currency': user_.company.currency.id, # 'shop': user_.shop.id, # 'reference': str(sale_['id']), # 'invoice_address': Party.address_get(party, type='invoice'), # 'shipment_address': Party.address_get(party, type='delivery'), # 'description': 'VENTA WEB ', # 'channel': self.id, # 'invoice_type': self.invoice_type, # 'pack_id': str(sale_['pack_id']) if sale_['pack_id'] else '', # }]) # generic = self.create_lines_sale( # sale, sale_, freight=True) # sale.untaxed_amount_cache = sale.untaxed_amount # if sale_['status'] == 'cancelled': # sale.state = 'cancelled' # else: # Sale.quote([sale]) # if not generic: # sale.state = 'confirmed' # sale.save() # # if shipment_['status'] in ['shipped', 'delivered']: # # self._finish_sale(sale) # return sale # def cancel_sales(self, sales, pack_id=None): # Sale = Pool().get('sale.sale') # if pack_id: # sales = Sale.search([('pack_id', '=', pack_id)]) # for sale in sales: # sale.state = 'cancelled' # sale.save() # def _get_shipment_amount(self, order_id, shipment={}): # URI = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % ( # order_id, self.access_token) # res = self.get_response(URI) # sale_ = res.json() # shipping_amount = 0 # if sale_.get('payments'): # shipping_amount = sale_['payments'][0]['shipping_cost'] # return shipping_amount # def get_access_token(self, refresh_token, client_id, client_secret): # params = {'grant_type': 'refresh_token', # 'client_id': client_id, # 'client_secret': client_secret, # 'refresh_token': refresh_token # } # uri = 'https://api.mercadolibre.com/oauth/token' # response = requests.post(uri, params=urlencode(params), # headers=HEADERS, data=params) # res = response.json() # if res.get('error', None): # raise UserError(res.get('message') + ' Error:' + res.get('error')) # return res['access_token'], res['refresh_token'] # @classmethod # def get_response(cls, URI, params={}): # response = requests.get(URI, headers=HEADERS, params=urlencode(params)) # print(response) # return response # def _validate_token(self): # access_token = self.access_token # refresh_token = self.refresh_token # client_id = self.app_id # client_secret = self.secret_key # if self.status_token != 'active': # access_token, refresh_token = self.get_access_token( # refresh_token, client_id, client_secret # ) # self.write([self], {'access_token': access_token, # 'refresh_token': refresh_token, # 'creation_time': datetime.now() # }) # return access_token, refresh_token, client_id, client_secret # @classmethod # def _get_channel(cls): # channels = cls.search([ # ('state', '=', 'active'), # ('channel_name', '=', 'mercadolibre'), # ]) # if channels: # return channels[0] # else: # return None # @classmethod # def request_api(cls, data): # channel = cls._get_channel() # response = {'status': 'error', 'msg_response': 'Fail in process !!!'} # if not channel: # return response # access_token, refresh_token, client_id, client_secret = channel._validate_token() # if data.get('resource') and data['resource'].count('orders'): # order_id = str(data['resource'].replace('/orders/', '')) # URI = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % ( # order_id, access_token) # result = cls.get_response(URI).json() # res = channel.validate_sale(result) # if res: # response = { # 'status': 'ok', # 'msg_response': 'Successfull process !!!', # 'order': order_id # } # else: # response = { # 'status': 'ok', # 'msg_response': 'Sale processed before !!!', # 'order': order_id # } # elif data.get('resource') and data['resource'].count('shipments'): # shipment_id = str(data['resource'].replace('/shipments/', '')) # shipment_ = channel.get_shipment_api(shipment_id) # order_id = shipment_['order_id'] # Sale = Pool().get('sale.sale') # sales = Sale.search([ # ('reference', 'ilike', '%' + str(order_id) + '%') # ]) # response.update({'order': order_id}) # if not sales: # return response # sale = sales[0] # if sale.invoices: # return response # if len(sales) > 1: # channel.upload_note( # sale, 'Error, al generar factura orden duplicada') # return response # if shipment_.get('tracking_number'): # Sale.write([sale], { # 'description': 'GUIA DE ENVIO NO. ' + shipment_['tracking_number'], # 'tracking_number': shipment_['tracking_number'] # }) # if shipment_['status'] in ['shipped', 'delivered']: # try: # channel._finish_sale(sale) # except: # channel.upload_note(sale, 'Error al finalizar factura') # response = {'status': 'ok', # 'msg_response': 'Successfull process !!!', # 'order': order_id} # else: # return {'status': 'none', 'msg_response': 'Don`t process this topic'} # return response # def _finish_sale(self, sale, type='invoice'): # ctx = self._get_context() # pool = Pool() # Sale = pool.get('sale.sale') # Invoice = pool.get('account.invoice') # Date = pool.get('ir.date') # with Transaction().set_context(ctx): # Sale.process([sale]) # if not sale.invoices: # return # invoice = sale.invoices[0] # invoice.invoice_date = Date.today() # if type == 'return': # sale_origin = sale.origin # if sale_origin.invoices: # inv_origin = sale_origin.invoices[0] # invoice.credit_note_concept = '2' # invoice.original_invoice = inv_origin.id # invoice.save() # Invoice.validate_invoice([invoice]) # if invoice.invoice_type not in ('C', 'P', 'M'): # try: # invoice.submit([invoice]) # if not invoice.cufe: # return # except: # self.upload_note(sale, 'Error de envio DIAN') # try: # Invoice.post([invoice]) # self.upload_note(sale, 'Factura generada') # self.upload_invoice(sale) # except: # pass # def upload_invoice(self, sale): # if not sale.reference or not sale.invoices: # return # invoice = sale.invoices[0] # pack_id = sale.reference # if sale.pack_id: # pack_id = sale.pack_id # URI = 'https://api.mercadolibre.com/packs/%s/fiscal_documents?access_token=%s' % ( # pack_id, self.access_token) # if sale.uploaded_invoice: # response = requests.delete(URI) # report = self.render_report(invoice) # file = {"fiscal_document": report} # response = requests.post(URI, files=file) # print(response.status_code) # message = 'Error al subir factura' # if response.status_code in [200, 201, 202]: # res = response.json() # upload_ids = 'Upload ids: ' + ', '.join(list(res['ids'])) # sale.write([sale], { # 'uploaded_invoice': True, # 'document_invoice': upload_ids, # }) # message = 'Factura Cargada exitosamente' # self.upload_note(sale, message) # def upload_note(self, sale, message): # URI = 'https://api.mercadolibre.com/orders/%s/notes?access_token=%s' % ( # sale.reference, self.access_token) # params = {"note": message} # request = json.dumps(params) # response = requests.post(URI, headers=HEADERS, data=request) # if not response.status_code in [200, 201, 202]: # self.send_mail_notification( # 'error al crear nota en orden ' + sale.reference) class MercadoLibre: 'MercadoLibre' def __init__(self, web_shop): self.access_token = web_shop.access_token if web_shop.access_token else '' self.generic_product = web_shop.generic_product self.refresh_token = web_shop.refresh_token self.id = web_shop.id self.app_id = web_shop.app_id self.secret_key = web_shop.secret_key self.freight_product = web_shop.freight_product self.invoice_type = web_shop.invoice_type def _get_context(self): user_ = self._get_user() return { 'company': user_.company.id, 'user': user_.id, 'shops': [user_.shop.id], 'shop': user_.shop.id, 'language': 'es' } def _get_user(self): User = Pool().get('res.user') user, = User.search([ ('login', '=', 'mercado.libre') ]) return user def _create_product(self, codes, line={}): item = line['item'] pool = Pool() Product = pool.get('product.product') Template = pool.get('product.template') description = '' if item.get('variation_attributes'): var = item['variation_attributes'][0] if var['id'] and var['name']: description = var['id'] + ' ' + var['name'] create_template = { 'name': item['title'], 'list_price': line['unit_price'], 'sale_price_w_tax': line['full_unit_price'], 'type': 'goods', 'salable': True, 'purchasable': True, 'purchase_uom': 1, 'sale_uom': 1, 'default_uom': 1, 'account_category': 7, } template, = Template.create([create_template]) create_product = [] for code in codes: create_product.append({ 'code': code, 'description': description, 'template': template.id }) return Product.create(create_product) def _create_party(self, customer): _pool = Pool() City = _pool.get('party.city_code') Party = _pool.get('party.party') PartyObligationTax = _pool.get('party.obligation_tax') email = customer.get('email', '@') shipment_address, phone, city = '', '', None if customer.get('receiver_address'): receiver_address = customer['receiver_address'] shipment_address = receiver_address['address_line'] phone = receiver_address['receiver_phone'] or '000' city_name = receiver_address['city']['name'] if city_name: cities = City.search([ ('name', '=', city_name) ]) if cities: city = cities[0] if customer['billing_info']['doc_type'] == 'NIT': type_document = '31' customer_name = customer['billing_info']['business_name'] type_person = 'persona_juridica' else: customer_name = customer['billing_info']['first_name'] + ' ' + customer['billing_info']['last_name'] type_document = '13' type_person = 'persona_natural' create_customer = { 'id_reference': str(customer['id']), 'name': customer_name.upper(), 'type_document': type_document, 'type_person': type_person, 'id_number': customer['billing_info']['doc_number'], 'addresses': [('create', [{ 'street': shipment_address, }])], 'contact_mechanisms': [ ('create', [ {'type': 'phone', 'value': phone}, {'type': 'email', 'value': email}, ]) ] } if not city: city = City(149) create_customer['addresses'][0][1][0]['department_code'] = city.department.id create_customer['addresses'][0][1][0]['city_code'] = city.id party, = Party.create([create_customer]) PartyObligationTax.create([{ 'party': party.id, 'obligation_fiscal': 6, }]) return party def get_shipment_api(self, shipment_id): if not shipment_id: return None URI = 'https://api.mercadolibre.com/shipments/%s?access_token=%s' % ( shipment_id, self.access_token) res = self.get_response(URI) return res.json() def get_billing_info_api(self, order_id): if not order_id: return None URI = 'https://api.mercadolibre.com/orders/%s/billing_info?access_token=%s' % ( order_id, self.access_token) res = self.get_response(URI) return res.json() def _return_sale(self, sale): pool = Pool() Sale = pool.get('sale.sale') Date = pool.get('ir.date') ctx = self._get_context() dev_sales = [] sales = [sale] if sale.pack_id: sales = Sale.search([ ('pack_id', '=', sale.pack_id) ]) with Transaction().set_context(ctx): return_sales = Sale.copy(sales) for return_sale, sale in zip(return_sales, sales): return_sale.origin = sale return_sale.reference = sale.reference return_sale.state = 'draft' return_sale.sale_date = Date.today() if sale.invoice_type == '1': return_sale.invoice_type = '91' for line in return_sale.lines: if line.type == 'line': line.quantity *= -1 line.save() if return_sale.untaxed_amount_cache: return_sale.untaxed_amount_cache *= -1 if return_sale.tax_amount_cache: return_sale.tax_amount_cache *= -1 if return_sale.total_amount_cache: return_sale.total_amount_cache *= -1 return_sale.save() Sale.quote([return_sale]) Sale.write([return_sale], {'state': 'confirmed'}) dev_sales.append(return_sale) return dev_sales def create_lines_sale(self, sale, sale_items, sfm_id, freight=False): _pool = Pool() SaleLine = _pool.get('sale.line') Product = _pool.get('product.product') create_lines = [] # sale_items = sale_['order_items'] ctx = self._get_context() # sfm_id = sale_items[0]['shipping']['id'] # reference = sale.reference.split(',') # reference_order = str(sale_['id']) # if reference_order not in reference: # sale.referece = sale.reference + ',' + reference_order # sale.save() with Transaction().set_context(ctx): for line in sale_items: sku_code = line['item']['seller_sku'] if sku_code: generic = False if sku_code.count('+') > 0: codes = sku_code.split('+') line['unit_price'] = Decimal( round((line['unit_price'] / 2), 2)) else: codes = [sku_code] products = Product.search([ ('code', 'in', codes), ('active', '=', True) ]) description = '' if not products: products = self._create_product(codes, line) else: if not self.generic_product: raise NotProductFoundError( gettext('sale_web_channel.msg_product_generic_not_found')) products = [self.generic_product] generic = True description = '' raise NotProductFound( gettext('sale_web_channel.msg_product_not_found', s=self.generic_product.rec_name)) for product in products: Tax = _pool.get('account.tax') un_price = Tax.reverse_compute(Decimal(line['unit_price']), product.customer_taxes_used) create_lines.append({ 'sale': sale.id, 'type': 'line', 'unit': product.default_uom.id, 'quantity': line['quantity'], 'unit_price': round(Decimal(un_price), 3), 'unit_price_full': Decimal(line['unit_price']), 'product': product.id, 'taxes': [('add', product.customer_taxes_used)], 'description': description, }) if freight and self.freight_product: product = self.freight_product URI = 'https://api.mercadolibre.com/shipments/%s/costs?access_token=%s' % ( sfm_id, self.access_token) result = self.get_response(URI).json() shipping_amount = result['receiver']['cost'] create_lines.append({ 'sale': sale.id, 'type': 'line', 'unit': product.default_uom.id, 'quantity': 1, 'unit_price': Decimal(shipping_amount), 'unit_price_full': Decimal(shipping_amount), 'product': product.id, 'description': 'FLETE', }) SaleLine.create(create_lines) return generic def validate_sale(self, sale_): if sale_.get('id'): # URI = 'https://api.mercadolibre.com/packs/%s?access_token=%s' % ( # sale_.get('pack_id'), self.access_token) # response = self.get_response(URI) # response = response.json() # print(response.get('orders'), 'response.get') if sale_.get('orders'): ids = '' sale_['order_items'] = [] for item in sale_['orders']: order_id = str(item['id']) URI2 = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % ( order_id, self.access_token) order = self.get_response(URI2) sale_order = order.json() ids += ',' + order_id sale_['order_items'].append(sale_order) sale_['id'] = str(sale_['id']) + ids # sale_['id'] = str(sale_['id']) + ids return self._create_sale(sale_) else: return self._create_sale(sale_) else: return self._create_sale(sale_) def _create_sale(self, sale_): _pool = Pool() Sale = _pool.get('sale.sale') # reference = '%' + str(sale_['id']).split(',')[0] + '%' try: ids = [str(order['id']) for order in sale_['orders']] pack_id = str(sale_['id']).split(',')[0] reference = ', '.join(ids) sfm_id = sale_['order_items'][0]['shipping']['id'] sale_id = str(sale_['id']).split(',')[1] sale_items = sale_['order_items'][0]['order_items'] except KeyError: ids = sale_['id'] pack_id = None reference = sale_['id'] sfm_id = sale_['shipping']['id'] sale_id = sale_['id'] sale_items = sale_['order_items'] dom = [ ('reference', 'like', reference) ] sales = Sale.search(dom) if sales: if len(sales) == 1 and sale_['status'] == 'cancelled': sale = sales[0] if not sale.invoices: self.cancel_sales([sale], sale.pack_id) else: dev_sales = self._return_sale(sale) self._finish_sale(dev_sales[0], type='return') return True return False sale_data = sale_['order_items'][0] Party = _pool.get('party.party') User = _pool.get('res.user') shipment_ = self.get_shipment_api(sfm_id) if sale_.get('buyer'): billing_info = self.get_billing_info_api(sale_id) customer = sale_['buyer'] dom_party = [('id_reference', '=', str(customer['id']))] if billing_info and billing_info['billing_info'].get('doc_number'): dom_party = [('id_number', '=', str( billing_info['billing_info']['doc_number']))] parties = Party.search(dom_party) if parties: party = parties[0] else: customer['receiver_address'] = shipment_['receiver_address'] customer['billing_info'] = billing_info['billing_info'] for dic in customer['billing_info']['additional_info']: customer['billing_info'][list(dic.values())[0].lower() ] = list(dic.values())[1] try: customer['billing_info']['additional_info'].pop() except Exception as e: msg = 'sin informacion de tercero' + e raise UserError( gettext('sale_web_channel.msg_billing_info', msg=msg)) party = self._create_party(customer) ctx = self._get_context() user_ = User(ctx['user']) date_created = sale_['date_created'].split('T') year, month, day = date_created[0].split('-') sale_date = date(int(year), int(month), int(day)) with Transaction().set_user(ctx['user']): sale, = Sale.create([{ 'payment_term': 1, 'party': party.id, 'sale_date': sale_date, 'comment': shipment_['status'], 'state': 'draft', 'company': ctx['company'], 'currency': user_.company.currency.id, 'shop': user_.shop.id, 'reference': reference, 'invoice_address': Party.address_get(party, type='invoice'), 'shipment_address': Party.address_get(party, type='delivery'), 'description': 'VENTA WEB ', 'web_shop': self.id, 'web_id': pack_id if pack_id else sale_id, 'invoice_type': self.invoice_type, 'pack_id': pack_id, }]) generic = self.create_lines_sale( sale, sale_items, sfm_id, freight=True) sale.untaxed_amount_cache = sale.untaxed_amount if sale_['status'] == 'cancelled': sale.state = 'cancelled' else: Sale.quote([sale]) if not generic: sale.state = 'confirmed' sale.save() # if shipment_['status'] in ['shipped', 'delivered']: # self._finish_sale(sale) return sale @classmethod def get_response(cls, URI, params={}): response = requests.get(URI, headers=HEADERS, params=urlencode(params)) return response def get_access_token(self, refresh_token, client_id, client_secret): params = {'grant_type': 'refresh_token', 'client_id': client_id, 'client_secret': client_secret, 'refresh_token': refresh_token } uri = 'https://api.mercadolibre.com/oauth/token' response = requests.post(uri, params=urlencode(params), headers=HEADERS, data=params) res = response.json() if res.get('error', None): raise UserError(res.get('message') + ' Error:' + res.get('error')) return res['access_token'], res['refresh_token'] def _validate_token(self): access_token = self.access_token refresh_token = self.refresh_token client_id = self.app_id client_secret = self.secret_key access_token, refresh_token = self.get_access_token( refresh_token, client_id, client_secret ) # return access_token, refresh_token, client_id, client_secret return access_token def _validate_number_id(self, number_id, access_token): URI = 'https://api.mercadolibre.com/packs/%s?access_token=%s' % ( number_id, access_token) result = self.get_response(URI).json() if result['status'] != 404: return self.validate_sale(result) else: URI = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % ( number_id, access_token) result = self.get_response(URI).json() if result['pack_id']: URI = 'https://api.mercadolibre.com/packs/%s?access_token=%s' % ( result['pack_id'], access_token) result2 = self.get_response(URI).json() return self.validate_sale(result2) return self._create_sale(result)