diff --git a/mercado_libre.py b/mercado_libre.py
index 602b24b..59c9a0c 100644
--- a/mercado_libre.py
+++ b/mercado_libre.py
@@ -12,6 +12,7 @@ from web_channel import SaleWebChannel
import json
from .exceptions import NotProductFoundError, NotProductFound
from trytond.i18n import gettext
+from trytond.exceptions import UserError
HEADERS = {
'Accept': 'application/json',
@@ -181,72 +182,19 @@ class MercadoLibre(SaleWebChannel):
dev_sales.append(return_sale)
return dev_sales
- def _create_sale(self, sale_):
+ def process_pack(self, sales):
+ for sale in sales:
+ sale.state = 'confirmed'
+ sale.save()
+
+ def create_lines_sale(self, sale, sale_, freight=False):
_pool = Pool()
- Sale = _pool.get('sale.sale')
- sales = Sale.search([
- ('reference', '=', str(sale_['id']))
- ])
- # print(sales[0].number)
-
- 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
SaleLine = _pool.get('sale.line')
- Party = _pool.get('party.party')
Product = _pool.get('product.product')
- User = _pool.get('res.user')
- sfm_id = sale_['shipping']['id']
- shipment_ = self.get_shipment_api(sfm_id)
- if sale_.get('buyer'):
- billing_info = self.get_billing_info_api(sale_['id'])
- customer = sale_['buyer']
- dom_party = [('id_reference', '=', str(customer['id']))]
- if billing_info and billing_info['billing_info'].get('doc_number'):
- dom_party = [('id_number', '=', str(billing_info['billing_info']['doc_number']))]
- parties = Party.search(dom_party)
- if parties:
- party = parties[0]
- else:
- customer['receiver_address'] = shipment_['receiver_address']
- customer['billing_info'] = billing_info['billing_info']
- for dic in customer['billing_info']['additional_info']:
- customer['billing_info'][dic.values()[0].lower()] = dic.values()[1]
- customer['billing_info']['additional_info'].pop()
- party = self._create_party(customer)
- sale_items = sale_['order_items']
create_lines = []
+ sale_items = sale_['order_items']
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 '',
- }])
-
+ sfm_id = sale_['shipping']['id']
with Transaction().set_context(ctx):
for line in sale_items:
item = line['item']
@@ -256,9 +204,11 @@ class MercadoLibre(SaleWebChannel):
generic = False
if sku_code.count('+') > 0:
codes = sku_code.split('+')
- line['unit_price'] = Decimal(round((line['unit_price'] / 2), 2))
+ line['unit_price'] = Decimal(
+ round((line['unit_price'] / 2), 2))
else:
codes = [sku_code]
+
products = Product.search([
('code', 'in', codes),
('active', '=', True)
@@ -290,9 +240,10 @@ class MercadoLibre(SaleWebChannel):
'taxes': [('add', product.customer_taxes_used)],
'description': description,
})
- if self.freight_product:
+ 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)
+ 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({
@@ -306,12 +257,97 @@ class MercadoLibre(SaleWebChannel):
'description': 'FLETE',
})
SaleLine.create(create_lines)
+ return generic
+
+ def _create_sale(self, sale_):
+ _pool = Pool()
+ Sale = _pool.get('sale.sale')
+
+ if sale_.get('pack_id'):
+ sales = self.search([
+ ('pack_id', '=', sale_['pack_id'])
+ ])
+ if sales:
+ self.create_lines_sale(
+ sales[0], sale_, freight=False)
+ return False
+ sales = Sale.search([
+ ('reference', '=', str(sale_['id']))
+ ])
+
+ 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'):
+ 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'][dic.values()[0].lower()
+ ] = 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'
+ elif sale_.get('pack_id'):
+ with Transaction().set_context(
+ queue_name='process_pack_id',
+ queue_scheduled_at=10):
+ self.__class__.__queue__.process_pack([sale])
else:
Sale.quote([sale])
- if generic:
+ if not generic:
sale.state = 'confirmed'
sale.save()
# if shipment_['status'] in ['shipped', 'delivered']:
@@ -417,7 +453,8 @@ class MercadoLibre(SaleWebChannel):
return response
if len(sales) > 1:
- channel.upload_note(sale, 'Error, al generar factura orden duplicada')
+ channel.upload_note(
+ sale, 'Error, al generar factura orden duplicada')
return response
if shipment_.get('tracking_number'):
@@ -500,4 +537,5 @@ class MercadoLibre(SaleWebChannel):
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)
+ self.send_mail_notification(
+ 'error al crear nota en orden ' + sale.reference)
diff --git a/message.xml b/message.xml
index 0ac8fa3..7508c2c 100644
--- a/message.xml
+++ b/message.xml
@@ -9,5 +9,8 @@ this repository contains the full copyright notices and license terms. -->
Product Generic Not Found, Verify in Configuration
+
+ Error: "(msg)s"
+
diff --git a/tryton.cfg b/tryton.cfg
index 070d0f3..2d4c18c 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
[tryton]
-version=6.0.0
+version=6.0.1
depends:
sale_pos
product_reference
diff --git a/web_channel.py b/web_channel.py
index 4ae021f..57243d4 100644
--- a/web_channel.py
+++ b/web_channel.py
@@ -52,9 +52,9 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
_rec_name = 'name'
name = fields.Char('Name Channel')
channel_name = fields.Selection(CHANNELS,
- 'Channel', select=True, required=True, states=STATES)
+ 'Channel', select=True, required=True, states=STATES)
company = fields.Many2One('company.company', 'Company', required=True,
- states=STATES)
+ states=STATES)
shop = fields.Many2One('sale.shop', 'Shop', domain=[
('company', '=', Eval('company'))
], states=STATES)
@@ -90,7 +90,7 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
('finished', 'Finished'),
], 'State', select=True, readonly=True)
freight_product = fields.Many2One('product.product', 'Freight Product',
- states=STATES)
+ states=STATES)
bonus_product = fields.Many2One('product.product', 'Bonus Product', states={
'invisible': (Eval('channel_name') != 'mercadolibre'),
'readonly': (Eval('state') != 'draft')
@@ -111,7 +111,8 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
'invisible': (Eval('channel_name') != 'mercadolibre'),
'readonly': (Eval('state') != 'draft')
})
- template_notification = fields.Many2One('email.template', 'Template Notification')
+ template_notification = fields.Many2One(
+ 'email.template', 'Template Notification')
api_key = fields.Char('Api Key', states={
'invisible': (Eval('channel_name') != 'shopify'),
})
@@ -123,7 +124,7 @@ class SaleWebChannel(Workflow, ModelSQL, ModelView):
})
party = fields.Many2One('party.party', 'party', required=False)
payment_term = fields.Many2One('account.invoice.payment_term',
- 'Payment Term')
+ 'Payment Term')
@classmethod
def __setup__(cls):
@@ -229,9 +230,9 @@ class SynchronizeChannelOrdersStart(ModelView):
('company', '=', Eval('company'))
])
channel = fields.Many2One('sale.web_channel', 'Channel', required=True,
- domain=[
- ('shop', '=', Eval('shop'))
- ])
+ domain=[
+ ('shop', '=', Eval('shop'))
+ ])
operation = fields.Selection([
('', ''),
('orders_for_day', 'Orders for day'),
@@ -268,15 +269,16 @@ 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),
- ])
+ '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),
- ])
+ 'sale_web_channel.synchronize_orders_done', [
+ Button('Done', 'end', 'tryton-ok', default=True),
+ ])
@classmethod
def __setup__(cls):
@@ -300,17 +302,20 @@ class SynchronizeChannelOrders(Wizard):
raise ErrorSynchronizingSale(
gettext('sale_web_channel.msg_error_synchronizing_sale', s=result))
sale_created = channel._create_sale(result)
- 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 sale_created and line.product.code == generic_code and generic_code]
- if sale_created and \
- not sale_created.pack_id and \
- sale_created.comment in ['shipped', 'delivered'] and \
- len(product_generic) < 1:
- Sale.process([sale_created])
+ 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)
+ 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']:
@@ -344,7 +349,7 @@ class SynchronizeChannelOrders(Wizard):
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_created.description.count('fulfilled'):
Sale.process([sale_created])
else:
date_from = str(self.start.date) + 'T00:00:00.000-00:00'
@@ -394,15 +399,16 @@ class FinishInvoices(Wizard):
'Finish Invoices'
__name__ = 'sale_web_channel.finish_invoices'
start = StateView('sale_web_channel.finish_invoices.start',
- 'sale_web_channel.finish_invoices_view_form', [
- Button('Cancel', 'end', 'tryton-cancel'),
- Button('Create', 'accept', 'tryton-ok', default=True),
- ])
+ 'sale_web_channel.finish_invoices_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),
- ])
+ 'sale_web_channel.synchronize_orders_done', [
+ Button('Done', 'end', 'tryton-ok', default=True),
+ ])
@classmethod
def __setup__(cls):