trytonpsk-sale_web_channel/mercado_libre.py

995 lines
41 KiB
Python

# -*- 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)