add wizard synchronize orders for channel
This commit is contained in:
parent
712dbca907
commit
836b57e23d
|
@ -13,12 +13,15 @@ def register():
|
|||
mercado_libre.MercadoLibre,
|
||||
sale.Sale,
|
||||
sale.SaleForChannelStart,
|
||||
web_channel.SynchronizeChannelOrdersStart,
|
||||
web_channel.SynchronizeChannelOrdersDone,
|
||||
party.Party,
|
||||
product.Template,
|
||||
module='sale_web_channel', type_='model')
|
||||
Pool.register(
|
||||
sale.SaleUploadInvoice,
|
||||
sale.SaleForChannel,
|
||||
web_channel.SynchronizeChannelOrders,
|
||||
module='sale_web_channel', type_='wizard')
|
||||
Pool.register(
|
||||
sale.SaleForChannelReport,
|
||||
|
|
104
locate/es.po
104
locate/es.po
|
@ -46,6 +46,10 @@ msgctxt "error:sale.web_channel.mercado_libre:"
|
|||
msgid "Product Not Found"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "error:sale_web_channel.synchronize_orders:"
|
||||
msgid "%s"
|
||||
msgstr "%s"
|
||||
|
||||
msgctxt "field:party.party,id_reference:"
|
||||
msgid "ID Reference Api"
|
||||
msgstr ""
|
||||
|
@ -110,6 +114,10 @@ msgctxt "field:sale.web_channel,channel_name:"
|
|||
msgid "Channel"
|
||||
msgstr "Canal"
|
||||
|
||||
msgctxt "field:sale.web_channel,company:"
|
||||
msgid "Company"
|
||||
msgstr "Empresa"
|
||||
|
||||
msgctxt "field:sale.web_channel,create_date:"
|
||||
msgid "Create Date"
|
||||
msgstr "Fecha de Creación"
|
||||
|
@ -154,6 +162,14 @@ msgctxt "field:sale.web_channel,secret_key:"
|
|||
msgid "Secret Key"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "field:sale.web_channel,seller_id:"
|
||||
msgid "Seller ID"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "field:sale.web_channel,shop:"
|
||||
msgid "Shop"
|
||||
msgstr "Tienda"
|
||||
|
||||
msgctxt "field:sale.web_channel,state:"
|
||||
msgid "State"
|
||||
msgstr "Estado"
|
||||
|
@ -190,6 +206,10 @@ msgctxt "field:sale.web_channel.mercado_libre,channel_name:"
|
|||
msgid "Channel"
|
||||
msgstr "Canal"
|
||||
|
||||
msgctxt "field:sale.web_channel.mercado_libre,company:"
|
||||
msgid "Company"
|
||||
msgstr "Empresa"
|
||||
|
||||
msgctxt "field:sale.web_channel.mercado_libre,create_date:"
|
||||
msgid "Create Date"
|
||||
msgstr "Fecha de Creación"
|
||||
|
@ -234,6 +254,14 @@ msgctxt "field:sale.web_channel.mercado_libre,secret_key:"
|
|||
msgid "Secret Key"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "field:sale.web_channel.mercado_libre,seller_id:"
|
||||
msgid "Seller ID"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "field:sale.web_channel.mercado_libre,shop:"
|
||||
msgid "Shop"
|
||||
msgstr "Tienda"
|
||||
|
||||
msgctxt "field:sale.web_channel.mercado_libre,state:"
|
||||
msgid "State"
|
||||
msgstr "Estado"
|
||||
|
@ -278,6 +306,42 @@ msgctxt "field:sale_web_channel.sale_for_channel.start,start_date:"
|
|||
msgid "Start Date"
|
||||
msgstr "Inicio"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.done,id:"
|
||||
msgid "ID"
|
||||
msgstr "UP"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.done,result:"
|
||||
msgid "Result"
|
||||
msgstr "Resultado"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,channel:"
|
||||
msgid "Channel"
|
||||
msgstr "Canal"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,company:"
|
||||
msgid "Company"
|
||||
msgstr "Empresa"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,date:"
|
||||
msgid "Date"
|
||||
msgstr "Fecha Transacción"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,id:"
|
||||
msgid "ID"
|
||||
msgstr "UP"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,operation:"
|
||||
msgid "Operation"
|
||||
msgstr "Operación"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,order_id:"
|
||||
msgid "Order ID"
|
||||
msgstr "Order ID"
|
||||
|
||||
msgctxt "field:sale_web_channel.synchronize_orders.start,shop:"
|
||||
msgid "Shop"
|
||||
msgstr "Tienda"
|
||||
|
||||
msgctxt "model:ir.action,name:act_sale_upload_invoice"
|
||||
msgid "Sale Upload Invoice"
|
||||
msgstr "Subir Factura"
|
||||
|
@ -290,6 +354,10 @@ msgctxt "model:ir.action,name:sale_for_channel_report"
|
|||
msgid "Sale For Channel"
|
||||
msgstr "Ventas Por Canal"
|
||||
|
||||
msgctxt "model:ir.action,name:synchronize_orders_wizard"
|
||||
msgid "Synchronize Channel Orders"
|
||||
msgstr "Sincronizar Ordenes por Canal"
|
||||
|
||||
msgctxt "model:ir.action,name:wizard_sale_for_channel"
|
||||
msgid "Sale For Channel Report"
|
||||
msgstr "Ventas Por Canal"
|
||||
|
@ -298,6 +366,10 @@ msgctxt "model:ir.ui.menu,name:menu_sale_for_channel"
|
|||
msgid "Sale For Channel Report"
|
||||
msgstr "Ventas Por Canal"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_synchronize_orders"
|
||||
msgid "Synchronize Channel Orders"
|
||||
msgstr "Sincronizar Ordenes por Canal"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_web_channel"
|
||||
msgid "Channels"
|
||||
msgstr "Canales"
|
||||
|
@ -314,6 +386,14 @@ msgctxt "model:sale_web_channel.sale_for_channel.start,name:"
|
|||
msgid "Sale For Channel Start"
|
||||
msgstr "Ventas Por Canal"
|
||||
|
||||
msgctxt "model:sale_web_channel.synchronize_orders.done,name:"
|
||||
msgid "Synchronize Channel Orders Done"
|
||||
msgstr "Sincronizar Ordenes por Canal"
|
||||
|
||||
msgctxt "model:sale_web_channel.synchronize_orders.start,name:"
|
||||
msgid "Synchronize Channel orders Start"
|
||||
msgstr "Sincronizar Ordenes por Canal"
|
||||
|
||||
msgctxt "report:sale_web_channel.sale_for_channel_report:"
|
||||
msgid "$"
|
||||
msgstr "$"
|
||||
|
@ -666,6 +746,18 @@ msgctxt "selection:sale.web_channel.mercado_libre,status_token:"
|
|||
msgid "Expired"
|
||||
msgstr "Vencido"
|
||||
|
||||
msgctxt "selection:sale_web_channel.synchronize_orders.start,operation:"
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgctxt "selection:sale_web_channel.synchronize_orders.start,operation:"
|
||||
msgid "Especific Orders"
|
||||
msgstr "Orden Especifica"
|
||||
|
||||
msgctxt "selection:sale_web_channel.synchronize_orders.start,operation:"
|
||||
msgid "Orders for day"
|
||||
msgstr "Ordenes Por Día"
|
||||
|
||||
msgctxt "view:sale.web_channel:"
|
||||
msgid "Active"
|
||||
msgstr "Activo"
|
||||
|
@ -685,3 +777,15 @@ msgstr "Cancelar"
|
|||
msgctxt "wizard_button:sale_web_channel.sale_for_channel,start,print_:"
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
msgctxt "wizard_button:sale_web_channel.synchronize_orders,done,end:"
|
||||
msgid "Done"
|
||||
msgstr "Terminado"
|
||||
|
||||
msgctxt "wizard_button:sale_web_channel.synchronize_orders,start,accept:"
|
||||
msgid "Create"
|
||||
msgstr "Crear"
|
||||
|
||||
msgctxt "wizard_button:sale_web_channel.synchronize_orders,start,end:"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
|
|
@ -274,10 +274,13 @@ class MercadoLibre(SaleWebChannel):
|
|||
sale.untaxed_amount_cache = sale.untaxed_amount
|
||||
if sale_['status'] == 'cancelled':
|
||||
sale.state = 'cancel'
|
||||
sale.save()
|
||||
else:
|
||||
Sale.quote([sale])
|
||||
sale.state = 'confirmed'
|
||||
sale.save()
|
||||
sale.save()
|
||||
if shipment_['status'] in ['shipped', 'delivered']:
|
||||
self._finish_sale(sale)
|
||||
return True
|
||||
|
||||
def _get_shipment_amount(self, order_id, shipment={}):
|
||||
|
@ -288,8 +291,6 @@ class MercadoLibre(SaleWebChannel):
|
|||
shipping_amount = 0
|
||||
if sale_.get('payments'):
|
||||
shipping_amount = sale_['payments'][0]['shipping_cost']
|
||||
# if shipping_amount == 0 and shipment.get('shipping_option'):
|
||||
# shipping_amount = shipment['shipping_option']['list_cost']
|
||||
return shipping_amount
|
||||
|
||||
def get_access_token(self, refresh_token, client_id, client_secret):
|
||||
|
@ -309,7 +310,8 @@ class MercadoLibre(SaleWebChannel):
|
|||
res = response.json()
|
||||
return res['access_token'], res['refresh_token']
|
||||
|
||||
def get_response(self, URI, params={}):
|
||||
@classmethod
|
||||
def get_response(cls, URI, params={}):
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-type': 'application/json'
|
||||
|
@ -352,8 +354,9 @@ class MercadoLibre(SaleWebChannel):
|
|||
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 = channel.get_response(URI).json()
|
||||
URI = 'https://api.mercadolibre.com/orders/%s?access_token=%s' % (
|
||||
order_id, access_token)
|
||||
result = cls.get_response(URI).json()
|
||||
res = channel._create_sale(result)
|
||||
if res:
|
||||
response = {
|
||||
|
@ -413,8 +416,6 @@ class MercadoLibre(SaleWebChannel):
|
|||
if not invoice.cufe:
|
||||
return
|
||||
Invoice.post([invoice])
|
||||
# cursor = Transaction().connection.cursor()
|
||||
# cursor.execute('UPDATE account_invoice set shop=%s where id=%s' % (ctx['shop'], invoice.id))
|
||||
self.upload_invoice(sale)
|
||||
|
||||
def process_sale_pack(self, sale):
|
||||
|
@ -427,28 +428,3 @@ class MercadoLibre(SaleWebChannel):
|
|||
'state': 'processing',
|
||||
'invoice_number': invoice_number
|
||||
})
|
||||
|
||||
|
||||
# def _create_invoice_pack(self, sale, type):
|
||||
# invoice = sale._get_invoice_sale()
|
||||
# Sale = Pool().get('sale.sale')
|
||||
# sales = Sale.search([
|
||||
# ('pack_id', '=', sale.pack_id)
|
||||
# ])
|
||||
# lines = []
|
||||
# for sale in sales:
|
||||
# if type == 'return' and sale.total_amount > 0:
|
||||
# continue
|
||||
# elif type == 'invoice' and sale.total_amount < 0:
|
||||
# continue
|
||||
# for ln in sale.lines:
|
||||
# lines.append(ln.get_invoice_line())
|
||||
# lines = list(chain(*lines))
|
||||
# if lines:
|
||||
# if getattr(invoice, 'lines', None):
|
||||
# lines = list(invoice.lines) + lines
|
||||
# invoice.lines = lines
|
||||
# invoice.shop = None
|
||||
# invoice.save()
|
||||
# invoice.update_taxes([invoice])
|
||||
# return invoice
|
||||
|
|
|
@ -4,10 +4,16 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig
|
|||
<form>
|
||||
<label name="channel_name"/>
|
||||
<field name="channel_name"/>
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="app_id"/>
|
||||
<field name="app_id"/>
|
||||
<label name="shop"/>
|
||||
<field name="shop"/>
|
||||
<label name="secret_key"/>
|
||||
<field name="secret_key"/>
|
||||
<label name="seller_id"/>
|
||||
<field name="seller_id"/>
|
||||
<label name="redirect_uri"/>
|
||||
<field name="redirect_uri"/>
|
||||
<label name="authorization_code"/>
|
||||
|
@ -28,8 +34,6 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig
|
|||
<field name="bonus_product"/>
|
||||
<label name="invoice_type"/>
|
||||
<field name="invoice_type"/>
|
||||
<!-- <label name="minimal_amount_freight"/>
|
||||
<field name="minimal_amount_freight"/> -->
|
||||
<group col="6" colspan="4" id="state_buttons">
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<tree >
|
||||
<field name="channel_name"/>
|
||||
<field name="shop"/>
|
||||
<field name="redirect_uri"/>
|
||||
<field name="access_token"/>
|
||||
<field name="refresh_token"/>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part sale_shop module for Tryton.
|
||||
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="result"/>
|
||||
<field name="result"/>
|
||||
</form>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part sale_shop module for Tryton.
|
||||
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="company"/>
|
||||
<field name="company" widget="selection"/>
|
||||
<label name="shop"/>
|
||||
<field name="shop" widget="selection"/>
|
||||
<label name="channel"/>
|
||||
<field name="channel" widget="selection"/>
|
||||
<label name="operation"/>
|
||||
<field name="operation"/>
|
||||
<label name="order_id"/>
|
||||
<field name="order_id"/>
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
</form>
|
105
web_channel.py
105
web_channel.py
|
@ -4,11 +4,14 @@
|
|||
# the full copyright notices and license terms.
|
||||
from trytond.model import Workflow, ModelView, ModelSQL, fields
|
||||
from trytond.pyson import Eval
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from trytond.pool import Pool
|
||||
import requests
|
||||
from trytond.wizard import (Wizard, StateTransition, StateView, Button)
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
__all__ = ['SaleWebChannel']
|
||||
__all__ = ['SaleWebChannel', 'SynchronizeChannelOrdersStart',
|
||||
'SynchronizeChannelOrders', 'SynchronizeChannelOrdersDone']
|
||||
|
||||
STATES = {
|
||||
'readonly': (Eval('state') != 'draft')
|
||||
|
@ -34,12 +37,19 @@ TYPE_INVOICE = [
|
|||
('92', 'Nota Débito Eléctronica'),
|
||||
]
|
||||
|
||||
ORDERS_CREATED = 0
|
||||
|
||||
class SaleWebChannel(Workflow, ModelSQL, ModelView):
|
||||
'Web Channel'
|
||||
__name__ = 'sale.web_channel'
|
||||
_rec_name = 'channel_name'
|
||||
channel_name = fields.Selection(CHANNELS, 'Channel', select=True,
|
||||
required=True, states=STATES)
|
||||
company = fields.Many2One('company.company', 'Company', required=True,
|
||||
states=STATES)
|
||||
shop = fields.Many2One('sale.shop', 'Shop', required=True, domain=[
|
||||
('company', '=', Eval('company'))
|
||||
], states=STATES)
|
||||
secret_key = fields.Char('Secret Key', states=STATES)
|
||||
app_id = fields.Char('Application ID', states=STATES)
|
||||
redirect_uri = fields.Char('Redirect URI', states=STATES)
|
||||
|
@ -63,6 +73,11 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
|
|||
report = fields.Many2One('ir.action.report', 'Report', states=STATES)
|
||||
invoice_type = fields.Selection(TYPE_INVOICE, 'Type Invoice',
|
||||
states=STATES)
|
||||
seller_id = fields.Char('Seller ID', states={
|
||||
'invisible': (Eval('channel_name') != 'mercadolibre'),
|
||||
'readonly': (Eval('state') != 'draft')
|
||||
})
|
||||
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
|
@ -85,6 +100,10 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
|
|||
},
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
@classmethod
|
||||
def import_data(cls, fields_names, data):
|
||||
pool = Pool()
|
||||
|
@ -176,3 +195,85 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
|
|||
report = Report.execute([record.id], {'id': record.id})
|
||||
ext, data, filename, file_name = report
|
||||
return data
|
||||
|
||||
|
||||
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('sale.web_channel', 'Channel', required=True, domain=[
|
||||
('shop', '=', Eval('shop'))
|
||||
])
|
||||
operation = fields.Selection([
|
||||
('', ''),
|
||||
('orders_for_day', 'Orders for day'),
|
||||
('especific_order', 'Especific Orders')
|
||||
], 'Operation', 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'),
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company')
|
||||
|
||||
|
||||
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__()
|
||||
cls._error_messages.update({
|
||||
'error': ('%s'),
|
||||
})
|
||||
|
||||
def transition_accept(self):
|
||||
pool = Pool()
|
||||
channel = self.start.channel
|
||||
operation = self.start.operation
|
||||
if channel.channel_name == 'mercadolibre':
|
||||
MercadoLibre = pool.get('sale.web_channel.mercado_libre')
|
||||
if operation == 'especific_order':
|
||||
order_id = self.start.order_id
|
||||
res = MercadoLibre.request_api({"resource":"/orders/" + order_id})
|
||||
if not res:
|
||||
self.raise_user_error('error', res)
|
||||
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 sale in result['results']:
|
||||
channel = MercadoLibre(channel)
|
||||
res = channel._create_sale(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'
|
||||
|
|
|
@ -31,5 +31,23 @@ The COPYRIGHT file at the top level of this repository contains the full copyrig
|
|||
<menuitem action="act_sale_web_channel" parent="sale.menu_configuration"
|
||||
id="menu_web_channel" sequence="90"/>
|
||||
|
||||
|
||||
<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>
|
||||
|
|
Loading…
Reference in New Issue