Initial commit of connector_walmart for Odoo 11.0 (using beta version of connector_ecommerce)

This commit is contained in:
Jared Kipe
2018-07-07 12:43:35 -07:00
parent b7096b5187
commit cfd25c425b
34 changed files with 2518 additions and 2 deletions

View File

@@ -0,0 +1,2 @@
from . import common
from . import exporter

View File

@@ -0,0 +1,95 @@
# © 2017,2018 Hibou Corp.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import api, models, fields
from odoo.addons.queue_job.job import job, related_action
from odoo.addons.component.core import Component
from odoo.addons.queue_job.exception import RetryableJobError
_logger = logging.getLogger(__name__)
class WalmartStockPicking(models.Model):
_name = 'walmart.stock.picking'
_inherit = 'walmart.binding'
_inherits = {'stock.picking': 'odoo_id'}
_description = 'Walmart Delivery Order'
odoo_id = fields.Many2one(comodel_name='stock.picking',
string='Stock Picking',
required=True,
ondelete='cascade')
walmart_order_id = fields.Many2one(comodel_name='walmart.sale.order',
string='Walmart Sale Order',
ondelete='set null')
@job(default_channel='root.walmart')
@related_action(action='related_action_unwrap_binding')
@api.multi
def export_picking_done(self):
""" Export a complete or partial delivery order. """
self.ensure_one()
with self.backend_id.work_on(self._name) as work:
exporter = work.component(usage='record.exporter')
return exporter.run(self)
class StockPicking(models.Model):
_inherit = 'stock.picking'
walmart_bind_ids = fields.One2many(
comodel_name='walmart.stock.picking',
inverse_name='odoo_id',
string="Walmart Bindings",
)
class StockPickingAdapter(Component):
_name = 'walmart.stock.picking.adapter'
_inherit = 'walmart.adapter'
_apply_on = 'walmart.stock.picking'
def create(self, id, lines):
api_instance = self.api_instance
_logger.warn('BEFORE SHIPPING %s list: %s' % (str(id), str(lines)))
record = api_instance.orders.ship(id, lines)
_logger.warn('AFTER SHIPPING RECORD: ' + str(record))
if 'order' in record:
return record['order']
raise RetryableJobError('Shipping Order %s did not return an order response. (lines: %s)' % (str(id), str(lines)))
class WalmartBindingStockPickingListener(Component):
_name = 'walmart.binding.stock.picking.listener'
_inherit = 'base.event.listener'
_apply_on = ['walmart.stock.picking']
def on_record_create(self, record, fields=None):
record.with_delay().export_picking_done()
class WalmartStockPickingListener(Component):
_name = 'walmart.stock.picking.listener'
_inherit = 'base.event.listener'
_apply_on = ['stock.picking']
def on_picking_dropship_done(self, record, picking_method):
return self.on_picking_out_done(record, picking_method)
def on_picking_out_done(self, record, picking_method):
"""
Create a ``walmart.stock.picking`` record. This record will then
be exported to Walmart.
:param picking_method: picking_method, can be 'complete' or 'partial'
:type picking_method: str
"""
sale = record.sale_id
if not sale:
return
for walmart_sale in sale.walmart_bind_ids:
self.env['walmart.stock.picking'].create({
'backend_id': walmart_sale.backend_id.id,
'odoo_id': record.id,
'walmart_order_id': walmart_sale.id,
})

View File

@@ -0,0 +1,78 @@
# © 2017,2018 Hibou Corp.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields
from odoo.addons.component.core import Component
from odoo.addons.queue_job.exception import NothingToDoJob
from logging import getLogger
_logger = getLogger(__name__)
class WalmartPickingExporter(Component):
_name = 'walmart.stock.picking.exporter'
_inherit = 'walmart.exporter'
_apply_on = ['walmart.stock.picking']
def _get_args(self, binding, lines):
sale_binder = self.binder_for('walmart.sale.order')
walmart_sale_id = sale_binder.to_external(binding.walmart_order_id)
return walmart_sale_id, lines
def _get_lines(self, binding):
"""
Normalizes picking line data into the format to export to Walmart.
:param binding: walmart.stock.picking
:return: list[ dict(number, amount, carrier, methodCode, trackingNumber, trackingUrl=None) ]
"""
ship_date = binding.date_done
# in ms
ship_date_time = int(fields.Datetime.from_string(ship_date).strftime('%s')) * 1000
lines = []
for line in binding.move_lines:
sale_line = line.procurement_id.sale_line_id
if not sale_line.walmart_bind_ids:
continue
# this is a particularly interesting way to get this,
walmart_sale_line = next(
(line for line in sale_line.walmart_bind_ids
if line.backend_id.id == binding.backend_id.id),
None
)
if not walmart_sale_line:
continue
number = walmart_sale_line.walmart_number
amount = 1 if line.product_qty > 0 else 0
carrier = binding.carrier_id.walmart_carrier_code
methodCode = binding.walmart_order_id.shipping_method_code
trackingNumber = binding.carrier_tracking_ref
trackingUrl = None
lines.append(dict(
shipDateTime=ship_date_time,
number=number,
amount=amount,
carrier=carrier,
methodCode=methodCode,
trackingNumber=trackingNumber,
trackingUrl=trackingUrl,
))
return lines
def run(self, binding):
"""
Export the picking to Walmart
:param binding: walmart.stock.picking
:return:
"""
if binding.external_id:
return 'Already exported'
lines = self._get_lines(binding)
if not lines:
raise NothingToDoJob('Cancelled: the delivery order does not contain '
'lines from the original sale order.')
args = self._get_args(binding, lines)
external_id = self.backend_adapter.create(*args)
self.binder.bind(external_id, binding)