fix in mercado_libre
This commit is contained in:
parent
834530c797
commit
b59092a369
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE sale_web_channel RENAME TO web_shop;
|
||||
ALTER TABLE web_shop RENAME COLUMN creation_time TO token_create_date;
|
||||
ALTER TABLE web_shop RENAME COLUMN channel_name TO type;
|
||||
|
20
__init__.py
20
__init__.py
|
@ -9,24 +9,24 @@ from . import shopify
|
|||
from . import rappi
|
||||
from . import api_log
|
||||
from . import ir
|
||||
from . import routes
|
||||
# from . import routes
|
||||
from . import shop
|
||||
from . import web
|
||||
|
||||
|
||||
__all__ = ['register', 'routes']
|
||||
# __all__ = ['register', 'routes']
|
||||
__all__ = ['register']
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
web_channel.SaleWebChannel,
|
||||
mercado_libre.MercadoLibre,
|
||||
# web_channel.SaleWebChannel,
|
||||
web.Shop,
|
||||
# shopify.Shopify,
|
||||
sale.Sale,
|
||||
# sale.SaleForChannelStart,
|
||||
# web_channel.SynchronizeChannelOrdersStart,
|
||||
# web_channel.SynchronizeChannelOrdersDone,
|
||||
sale.SaleForChannelStart,
|
||||
web.SynchronizeChannelOrdersStart,
|
||||
web.SynchronizeChannelOrdersDone,
|
||||
# web_channel.FinishInvoicesStart,
|
||||
party.Party,
|
||||
api_log.ApiLog,
|
||||
|
@ -34,11 +34,11 @@ def register():
|
|||
module='sale_web_channel', type_='model')
|
||||
Pool.register(
|
||||
sale.SaleUploadInvoice,
|
||||
# sale.SaleForChannel,
|
||||
# web_channel.SynchronizeChannelOrders,
|
||||
sale.SaleForChannel,
|
||||
web.SynchronizeChannelOrders,
|
||||
# web_channel.FinishInvoices,
|
||||
# web_channel.SynchronizeMenuWizard,
|
||||
module='sale_web_channel', type_='wizard')
|
||||
Pool.register(
|
||||
# sale.SaleForChannelReport,
|
||||
sale.SaleForChannelReport,
|
||||
module='sale_web_channel', type_='report')
|
||||
|
|
792
mercado_libre.py
792
mercado_libre.py
|
@ -8,11 +8,13 @@ from trytond.transaction import Transaction
|
|||
import requests
|
||||
from urllib.parse import urlencode
|
||||
from datetime import datetime, date
|
||||
from .web_channel import SaleWebChannel
|
||||
# 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
|
||||
from rich import print
|
||||
|
||||
HEADERS = {
|
||||
'Accept': 'application/json',
|
||||
|
@ -20,13 +22,575 @@ HEADERS = {
|
|||
}
|
||||
|
||||
|
||||
class MercadoLibre(SaleWebChannel):
|
||||
'MercadoLibre'
|
||||
__name__ = 'sale.web_channel.mercado_libre'
|
||||
# class MercadoLibreTwo(Shop):
|
||||
# 'MercadoLibre'
|
||||
# __name__ = 'sale.web_channel.mercado_libre'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(MercadoLibre, cls).__setup__()
|
||||
# @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
|
||||
|
||||
def _get_context(self):
|
||||
user_ = self._get_user()
|
||||
|
@ -38,13 +602,6 @@ class MercadoLibre(SaleWebChannel):
|
|||
'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()
|
||||
|
@ -262,14 +819,6 @@ class MercadoLibre(SaleWebChannel):
|
|||
|
||||
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)
|
||||
|
@ -285,17 +834,22 @@ class MercadoLibre(SaleWebChannel):
|
|||
sale_order = order.json()
|
||||
ids += ',' + order_id
|
||||
sale_['order_items'].extend(sale_order['order_items'])
|
||||
# sale_['id'] = str(sale_['id']) + ids
|
||||
sale_['id'] = str(sale_['id']) + ids
|
||||
return self._create_sale(sale_)
|
||||
else:
|
||||
return self._create_sale(sale_)
|
||||
else:
|
||||
print(sale_, 'que carajos')
|
||||
return self._create_sale(sale_)
|
||||
|
||||
def _create_sale(self, sale_):
|
||||
_pool = Pool()
|
||||
Sale = _pool.get('sale.sale')
|
||||
reference = '%' + str(sale_['id']).split(',')[0] + '%'
|
||||
# reference = '%' + str(sale_['id']).split(',')[0] + '%'
|
||||
ids = [str(order['id']) for order in sale_['orders']]
|
||||
reference = ', '.join(ids)
|
||||
print(reference, 'esta es mi referencia')
|
||||
dom = [
|
||||
('reference', 'like', reference)
|
||||
]
|
||||
|
@ -357,7 +911,7 @@ class MercadoLibre(SaleWebChannel):
|
|||
'invoice_address': Party.address_get(party, type='invoice'),
|
||||
'shipment_address': Party.address_get(party, type='delivery'),
|
||||
'description': 'VENTA WEB ',
|
||||
'channel': self.id,
|
||||
'web': self.id,
|
||||
'invoice_type': self.invoice_type,
|
||||
'pack_id': str(sale_['pack_id']) if sale_['pack_id'] else '',
|
||||
}])
|
||||
|
@ -375,23 +929,10 @@ class MercadoLibre(SaleWebChannel):
|
|||
# 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
|
||||
@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',
|
||||
|
@ -399,9 +940,7 @@ class MercadoLibre(SaleWebChannel):
|
|||
'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()
|
||||
|
@ -409,170 +948,13 @@ class MercadoLibre(SaleWebChannel):
|
|||
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))
|
||||
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)
|
||||
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
|
||||
|
|
11
sale.py
11
sale.py
|
@ -15,7 +15,7 @@ class Sale(metaclass=PoolMeta):
|
|||
|
||||
is_paymented = fields.Function(fields.Boolean('Is Paymented'), 'get_is_paymented')
|
||||
products_string = fields.Char('Products String')
|
||||
channel = fields.Many2One('sale.web_channel', 'channel')
|
||||
# channel = fields.Many2One('sale.web_channel', 'channel')
|
||||
uploaded_invoice = fields.Boolean('uploaded Invoice', readonly=True)
|
||||
document_invoice = fields.Char('Document Invoice')
|
||||
tracking_number = fields.Char('Tracking Number')
|
||||
|
@ -57,10 +57,11 @@ class Sale(metaclass=PoolMeta):
|
|||
def quote(cls, sales):
|
||||
super(Sale, cls).quote(sales)
|
||||
for sale in sales:
|
||||
if sale.web_shop.type == 'rappi':
|
||||
print('si entra aqui en quote')
|
||||
rappi_rec = rappi.Rappi(sale.web_shop)
|
||||
rappi_rec.take_order(sale.web_id, 20)
|
||||
# if sale.web_shop.type == 'rappi':
|
||||
# print('si entra aqui en quote')
|
||||
# rappi_rec = rappi.Rappi(sale.web_shop)
|
||||
# rappi_rec.take_order(sale.web_id, 20)
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def confirm(cls, sales):
|
||||
|
|
|
@ -4,8 +4,8 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<data>
|
||||
<xpath expr="/form/notebook/page[@id='other']/field[@name='company']"
|
||||
position="after">
|
||||
<label name="channel"/>
|
||||
<field name="channel"/>
|
||||
<!-- <label name="channel"/>
|
||||
<field name="channel"/> -->
|
||||
<label name="uploaded_invoice"/>
|
||||
<field name="uploaded_invoice"/>
|
||||
<label name="tracking_number"/>
|
||||
|
|
|
@ -4,7 +4,7 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<data>
|
||||
<xpath expr="/tree/field[@name='state']"
|
||||
position="before">
|
||||
<field name="channel"/>
|
||||
<!-- <field name="channel"/> -->
|
||||
<field name="pack_id"/>
|
||||
<field name="tracking_number"/>
|
||||
</xpath>
|
||||
|
|
|
@ -9,7 +9,7 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig
|
|||
<label name="channel"/>
|
||||
<field name="channel" widget="selection"/>
|
||||
<!-- <label name="name_channel"/> -->
|
||||
<field name="name_channel" invisible="1"/>
|
||||
<field name="type" invisible="1"/>
|
||||
<newline/>
|
||||
<label name="operation"/>
|
||||
<field name="operation"/>
|
||||
|
|
202
web.py
202
web.py
|
@ -1,7 +1,12 @@
|
|||
from trytond.model import fields, ModelView
|
||||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.pyson import Eval, And, Or
|
||||
from trytond.pyson import Eval, And
|
||||
from datetime import datetime, timedelta
|
||||
from trytond.wizard import (Wizard, StateTransition, StateView, Button)
|
||||
from .exceptions import ErrorSynchronizingSale
|
||||
from trytond.i18n import gettext
|
||||
from trytond.transaction import Transaction
|
||||
from . mercado_libre import MercadoLibre
|
||||
|
||||
from . import rappi
|
||||
|
||||
|
@ -25,6 +30,14 @@ TYPE_INVOICE = [
|
|||
('92', 'Nota Débito Eléctronica'),
|
||||
]
|
||||
|
||||
# TODO FOR EXECUTE in database
|
||||
"""
|
||||
alter database rename table sale_web_channel to web_shop
|
||||
RENAME COLUMN channel_name by type
|
||||
|
||||
RENAME COLUMN creation_time by token_create_date
|
||||
"""
|
||||
|
||||
|
||||
class Shop(metaclass=PoolMeta):
|
||||
__name__ = 'web.shop'
|
||||
|
@ -36,6 +49,9 @@ class Shop(metaclass=PoolMeta):
|
|||
authorization_code = fields.Char('Authorization Code', states={
|
||||
'invisible': (Eval('type') != 'mercadolibre'),
|
||||
})
|
||||
shop = fields.Many2One('sale.shop', 'Shop', domain=[
|
||||
('company', '=', Eval('company'))
|
||||
])
|
||||
access_token = fields.Char('Access Token', states={
|
||||
'invisible': And(
|
||||
Eval('type') != 'mercadolibre',
|
||||
|
@ -76,6 +92,17 @@ class Shop(metaclass=PoolMeta):
|
|||
seller_id = fields.Char('Seller ID', states={
|
||||
'invisible': ~Eval('type').in_(['mercadolibre', 'rappi']),
|
||||
})
|
||||
password_api = fields.Char('Api Password', states={
|
||||
'invisible': (Eval('type') != 'shopify'),
|
||||
})
|
||||
host_name = fields.Char('Host Name', states={
|
||||
'invisible': And(
|
||||
Eval('type') != 'shopify',
|
||||
Eval('type') != 'rappi'),
|
||||
})
|
||||
api_key = fields.Char('Api Key', states={
|
||||
'invisible': (Eval('type') != 'shopify'),
|
||||
})
|
||||
price_list = fields.Many2One('product.price_list', 'Price list', ondelete="RESTRICT")
|
||||
|
||||
@classmethod
|
||||
|
@ -112,11 +139,11 @@ class Shop(metaclass=PoolMeta):
|
|||
if records:
|
||||
for record in records:
|
||||
if record.type == 'mercadolibre':
|
||||
MercadoLibre = Pool().get('sale.web_channel.mercado_libre')
|
||||
channels = MercadoLibre.search([
|
||||
('state', '=', 'active'),
|
||||
('type', '=', 'mercadolibre'),
|
||||
])
|
||||
# MercadoLibre = Pool().get('web.shop')
|
||||
mercadolibre_rec = MercadoLibre(record)
|
||||
# record.access_token, refresh_token, client_id, client_secret = mercadolibre_rec._validate_token()
|
||||
record.access_token = mercadolibre_rec._validate_token()
|
||||
record.save()
|
||||
if record.type == 'rappi':
|
||||
rappi_rec = rappi.Rappi(record)
|
||||
record.access_token = rappi_rec.get_token_access()['access_token']
|
||||
|
@ -138,3 +165,166 @@ class Shop(metaclass=PoolMeta):
|
|||
rappi_rec = rappi.Rappi(record)
|
||||
rappi_rec.create_sales()
|
||||
|
||||
|
||||
class SynchronizeChannelOrdersStart(ModelView):
|
||||
'Synchronize Channel orders Start'
|
||||
__name__ = 'sale_web_channel.synchronize_orders.start'
|
||||
company = fields.Many2One('company.company', 'Company', required=True)
|
||||
shop = fields.Many2One('sale.shop', 'Shop', required=True, domain=[
|
||||
('company', '=', Eval('company'))
|
||||
])
|
||||
channel = fields.Many2One('web.shop', 'Channel', required=True,
|
||||
domain=[
|
||||
('shop', '=', Eval('shop'))
|
||||
])
|
||||
operation = fields.Selection([
|
||||
('', ''),
|
||||
('orders_for_day', 'Orders for day'),
|
||||
('especific_order', 'Especific Orders')
|
||||
], 'Operation', required=True)
|
||||
type = fields.Selection([
|
||||
('', ''),
|
||||
('shopify', 'Shopify'),
|
||||
('mercadolibre', 'Mercado libre')
|
||||
], 'Name Channel', required=True)
|
||||
order_id = fields.Char('Order ID', states={
|
||||
'invisible': (Eval('operation') != 'especific_order'),
|
||||
'required': (Eval('operation') == 'especific_order'),
|
||||
})
|
||||
date = fields.Date('Date', states={
|
||||
'invisible': (Eval('operation') != 'orders_for_day'),
|
||||
'required': (Eval('operation') == 'orders_for_day'),
|
||||
})
|
||||
date_end = fields.Date('Finish Date', states={
|
||||
'invisible': (Eval('operation') != 'orders_for_day') | (Eval('name_channel') != 'shopify'),
|
||||
'required': (Eval('operation') == 'orders_for_day') & (Eval('name_channel') != 'mercadolibre'),
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@fields.depends('channel')
|
||||
def on_change_channel(self):
|
||||
self.type = self.channel.type if self.channel else None
|
||||
|
||||
|
||||
class SynchronizeChannelOrders(Wizard):
|
||||
'Synchronize Channel Orders'
|
||||
__name__ = 'sale_web_channel.synchronize_orders'
|
||||
start = StateView('sale_web_channel.synchronize_orders.start',
|
||||
'sale_web_channel.synchronize_orders_view_form', [
|
||||
Button('Cancel', 'end', 'tryton-cancel'),
|
||||
Button('Create', 'accept',
|
||||
'tryton-ok', default=True),
|
||||
])
|
||||
accept = StateTransition()
|
||||
done = StateView('sale_web_channel.synchronize_orders.done',
|
||||
'sale_web_channel.synchronize_orders_done', [
|
||||
Button('Done', 'end', 'tryton-ok', default=True),
|
||||
])
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(SynchronizeChannelOrders, cls).__setup__()
|
||||
|
||||
def transition_accept(self):
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.sale')
|
||||
channel = self.start.channel
|
||||
operation = self.start.operation
|
||||
if channel.type == 'mercadolibre':
|
||||
mercado_libre = MercadoLibre(channel)
|
||||
if operation == 'especific_order':
|
||||
order_id = self.start.order_id
|
||||
URI = 'https://api.mercadolibre.com/packs/%s?access_token=%s' % (
|
||||
order_id, channel.access_token)
|
||||
result = mercado_libre.get_response(URI).json()
|
||||
print(result, 'este es el result')
|
||||
if not result:
|
||||
raise ErrorSynchronizingSale(
|
||||
gettext('sale_web_channel.msg_error_synchronizing_sale', s=result))
|
||||
print(result, channel.access_token)
|
||||
sale_created = mercado_libre.validate_sale(result)
|
||||
if sale_created:
|
||||
generic_code = self.start.channel.generic_product.code if self.start.channel.generic_product else None
|
||||
product_generic = [
|
||||
line.product.code for line in sale_created.lines if line.product.code == generic_code and generic_code]
|
||||
if not sale_created.pack_id and \
|
||||
sale_created.comment in ['shipped', 'delivered'] and \
|
||||
len(product_generic) < 1:
|
||||
Sale.process([sale_created])
|
||||
else:
|
||||
date_from = str(self.start.date) + 'T00:00:00.000-00:00'
|
||||
date_to = str(self.start.date + timedelta(days=1)
|
||||
) + 'T00:00:00.000-00:00'
|
||||
URI = 'https://api.mercadolibre.com/orders/search?seller=%s&order.date_created.from=%s&order.date_created.to=%s&access_token=%s&order.status=paid' % (
|
||||
channel.seller_id, date_from, date_to, channel.access_token)
|
||||
result = MercadoLibre.get_response(URI).json()
|
||||
for res in result['results']:
|
||||
sales = Sale.search([('reference', 'like', '%' + str(res['id']) + '%' )])
|
||||
shipment_status = ''
|
||||
if not sales:
|
||||
sale_created = channel.validate_sale(res)
|
||||
shipment_status = sale_created.comment
|
||||
sales = [sale_created]
|
||||
else:
|
||||
sfm_id = res['shipping']['id']
|
||||
shipment_ = channel.get_shipment_api(sfm_id)
|
||||
shipment_status = shipment_['status']
|
||||
if res.get('pack_id') or not shipment_status:
|
||||
continue
|
||||
if shipment_status in ['shipped', 'delivered']:
|
||||
for sale in sales:
|
||||
if not sale.invoices:
|
||||
Sale.process([sale])
|
||||
if channel.type == 'shopify':
|
||||
Shopify = pool.get('sale.web_channel.shopify')
|
||||
|
||||
channel, = Shopify.search([('shop', '=', self.start.shop.id), ])
|
||||
if operation == 'especific_order':
|
||||
order_id = self.start.order_id
|
||||
URI = 'https://%s:%s@%s/admin/api/2020-10/orders.json?status=any&ids=%s' % (
|
||||
channel.api_key, channel.password_api, channel.host_name, order_id)
|
||||
result = Shopify.get_response(URI).json()
|
||||
if not result:
|
||||
raise ErrorSynchronizingSale(
|
||||
gettext('sale_web_channel.msg_error_synchronizing_sale', s=result))
|
||||
sale_created = channel._create_sale(result['orders'][0])
|
||||
if sale_created and \
|
||||
sale_created.description.count('fulfilled'):
|
||||
Sale.process([sale_created])
|
||||
else:
|
||||
date_from = str(self.start.date) + 'T00:00:00.000-00:00'
|
||||
date_to = str(self.start.date_end) + 'T00:00:00.000-00:00'
|
||||
URI = 'https://%s:%s@%s/admin/api/2020-10/orders.json?status=any&created_at_min=%s&created_at_max=%s' % (
|
||||
channel.api_key, channel.password_api, channel.host_name, date_from, date_to)
|
||||
result = Shopify.get_response(URI).json()
|
||||
print('quantity orders----> ', len(result['orders']))
|
||||
|
||||
for res in result['orders']:
|
||||
sales = Sale.search([('reference', '=', str(res['id']))])
|
||||
fulfillment_status = ''
|
||||
if not sales:
|
||||
sale_created = channel._create_sale(res)
|
||||
fulfillment_status = sale_created.description
|
||||
sales = [sale_created]
|
||||
else:
|
||||
fulfillment_status = res['fulfillment_status']
|
||||
if not fulfillment_status:
|
||||
continue
|
||||
if fulfillment_status.count('fulfilled'):
|
||||
for sale in sales:
|
||||
if not sale.invoices:
|
||||
Sale.process([sale])
|
||||
return 'done'
|
||||
|
||||
|
||||
class SynchronizeChannelOrdersDone(ModelView):
|
||||
'Synchronize Channel Orders Done'
|
||||
__name__ = 'sale_web_channel.synchronize_orders.done'
|
||||
result = fields.Char('Result', readonly=True)
|
||||
|
||||
@staticmethod
|
||||
def default_result():
|
||||
return 'successful synchronization'
|
||||
|
|
17
web.xml
17
web.xml
|
@ -8,5 +8,22 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="inherit" ref="web_shop.shop_view_form"/>
|
||||
<field name="name">web_shop_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.wizard" id="synchronize_orders_wizard">
|
||||
<field name="name">Synchronize Channel Orders</field>
|
||||
<field name="wiz_name">sale_web_channel.synchronize_orders</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="synchronize_orders_view_form">
|
||||
<field name="model">sale_web_channel.synchronize_orders.start</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">synchronize_orders_view_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="synchronize_orders_done">
|
||||
<field name="model">sale_web_channel.synchronize_orders.done</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">synchronize_orders_done</field>
|
||||
</record>
|
||||
<menuitem action="synchronize_orders_wizard" parent="sale.menu_sale"
|
||||
id="menu_synchronize_orders" sequence="100"/>
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
|
@ -113,10 +113,10 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
|
|||
'invisible': ~Eval('channel_name').in_(['mercadolibre', 'rappi']),
|
||||
'readonly': (Eval('state') != 'draft')
|
||||
})
|
||||
admin_category = fields.Many2One('product.category', 'Admin Category',
|
||||
domain=[
|
||||
('accounting', '=', False),
|
||||
])
|
||||
# admin_category = fields.Many2One('product.category', 'Admin Category',
|
||||
# domain=[
|
||||
# ('accounting', '=', False),
|
||||
# ])
|
||||
price_list = fields.Many2One('product.price_list', 'Pricelist', ondelete="RESTRICT")
|
||||
template_notification = fields.Many2One(
|
||||
'email.template', 'Template Notification')
|
||||
|
|
Loading…
Reference in New Issue