trytonpsk-sale_web_channel/mercado_libre.py

995 lines
41 KiB
Python
Raw Permalink Normal View History

# -*- 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
2023-11-28 23:23:11 +01:00
# from .web_channel import SaleWebChannel
# from .web import Shop
import json
2021-07-21 00:22:58 +02:00
from .exceptions import NotProductFoundError, NotProductFound
from trytond.i18n import gettext
from trytond.exceptions import UserError
HEADERS = {
'Accept': 'application/json',
'Content-type': 'application/json'
}
2023-11-28 23:23:11 +01:00
# 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'
2023-11-28 23:23:11 +01:00
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
2023-12-02 15:34:42 +01:00
self.freight_product = web_shop.freight_product
2023-12-05 14:20:07 +01:00
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'
}
2023-12-02 15:34:42 +01:00
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')
2021-12-29 20:51:16 +01:00
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]
2021-05-29 18:31:26 +02:00
if customer['billing_info']['doc_type'] == 'NIT':
type_document = '31'
customer_name = customer['billing_info']['business_name']
type_person = 'persona_juridica'
2022-02-14 17:41:39 +01:00
else:
customer_name = customer['billing_info']['first_name'] + ' ' + customer['billing_info']['last_name']
type_document = '13'
type_person = 'persona_natural'
2021-07-21 00:22:58 +02:00
create_customer = {
'id_reference': str(customer['id']),
'name': customer_name.upper(),
2021-05-29 18:31:26 +02:00
'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()
2021-04-22 22:12:47 +02:00
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()
2020-08-18 05:57:20 +02:00
def _return_sale(self, sale):
pool = Pool()
Sale = pool.get('sale.sale')
Date = pool.get('ir.date')
ctx = self._get_context()
2020-08-18 03:17:58 +02:00
dev_sales = []
2020-08-18 05:57:20 +02:00
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
2020-08-18 03:30:55 +02:00
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
2020-09-29 06:07:20 +02:00
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()
2020-09-29 06:07:20 +02:00
Sale.quote([return_sale])
Sale.write([return_sale], {'state': 'confirmed'})
2020-08-18 03:17:58 +02:00
dev_sales.append(return_sale)
return dev_sales
2023-12-05 23:34:38 +01:00
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 = []
2023-12-05 23:34:38 +01:00
# sale_items = sale_['order_items']
ctx = self._get_context()
2023-12-05 23:34:38 +01:00
# sfm_id = sale_items[0]['shipping']['id']
2021-11-08 16:29:02 +01:00
# 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:
2023-12-05 23:34:38 +01:00
sku_code = line['item']['seller_sku']
2021-04-22 22:12:47 +02:00
2021-03-24 20:06:51 +01:00
if sku_code:
2021-03-29 21:09:51 +02:00
generic = False
2021-03-24 20:06:51 +01:00
if sku_code.count('+') > 0:
codes = sku_code.split('+')
line['unit_price'] = Decimal(
2023-12-05 23:34:38 +01:00
round((line['unit_price'] / 2), 2))
2021-03-24 20:06:51 +01:00
else:
codes = [sku_code]
2021-03-24 20:06:51 +01:00
products = Product.search([
('code', 'in', codes),
('active', '=', True)
])
description = ''
if not products:
products = self._create_product(codes, line)
else:
2021-03-24 20:06:51 +01:00
if not self.generic_product:
2021-07-21 00:22:58 +02:00
raise NotProductFoundError(
gettext('sale_web_channel.msg_product_generic_not_found'))
2021-03-24 20:06:51 +01:00
products = [self.generic_product]
generic = True
description = ''
2021-07-21 00:22:58 +02:00
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')
2023-12-05 23:34:38 +01:00
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,
2023-12-05 23:34:38 +01:00
'quantity': line['quantity'],
'unit_price': round(Decimal(un_price), 3),
2023-12-05 23:34:38 +01:00
'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
2021-11-08 13:55:41 +01:00
def validate_sale(self, sale_):
2023-12-05 14:20:07 +01:00
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'):
2021-11-08 16:29:02 +01:00
ids = ''
2023-12-05 14:20:07 +01:00
sale_['order_items'] = []
for item in sale_['orders']:
2022-08-16 21:19:05 +02:00
order_id = str(item['id'])
2023-12-05 14:20:07 +01:00
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
2023-11-28 23:23:11 +01:00
# sale_['id'] = str(sale_['id']) + ids
2021-11-08 16:29:02 +01:00
return self._create_sale(sale_)
2021-11-08 13:55:41 +01:00
else:
2021-11-08 16:29:02 +01:00
return self._create_sale(sale_)
2021-11-08 13:55:41 +01:00
else:
2021-11-08 16:29:02 +01:00
return self._create_sale(sale_)
2021-11-08 13:55:41 +01:00
def _create_sale(self, sale_):
_pool = Pool()
Sale = _pool.get('sale.sale')
2023-11-28 23:23:11 +01:00
# reference = '%' + str(sale_['id']).split(',')[0] + '%'
2023-12-05 23:34:38 +01:00
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']
2021-11-08 16:29:02 +01:00
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
2023-12-05 14:20:07 +01:00
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'):
2021-11-08 16:29:02 +01:00
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']:
2022-03-26 16:07:45 +01:00
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,
2023-12-05 14:20:07 +01:00
'reference': reference,
'invoice_address': Party.address_get(party, type='invoice'),
'shipment_address': Party.address_get(party, type='delivery'),
'description': 'VENTA WEB ',
2023-12-05 14:20:07 +01:00
'web_shop': self.id,
2023-12-05 23:34:38 +01:00
'web_id': pack_id if pack_id else sale_id,
'invoice_type': self.invoice_type,
2023-12-05 14:20:07 +01:00
'pack_id': pack_id,
}])
generic = self.create_lines_sale(
2023-12-05 23:34:38 +01:00
sale, sale_items, sfm_id, freight=True)
sale.untaxed_amount_cache = sale.untaxed_amount
2020-08-18 05:57:20 +02:00
if sale_['status'] == 'cancelled':
2021-09-04 16:27:03 +02:00
sale.state = 'cancelled'
2020-08-18 05:57:20 +02:00
else:
Sale.quote([sale])
if not generic:
2021-03-24 20:06:51 +01:00
sale.state = 'confirmed'
2020-09-30 03:52:38 +02:00
sale.save()
# if shipment_['status'] in ['shipped', 'delivered']:
# self._finish_sale(sale)
return sale
2023-11-28 23:23:11 +01:00
@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()
2022-10-14 23:03:34 +02:00
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
2023-11-28 23:23:11 +01:00
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
2023-12-05 23:34:38 +01:00
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)