mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
148 lines
6.1 KiB
Python
148 lines
6.1 KiB
Python
# © 2021 Hibou Corp.
|
|
|
|
from base64 import b64encode
|
|
|
|
from odoo import api, models, fields, _
|
|
from odoo.addons.queue_job.job import job, related_action
|
|
from odoo.addons.component.core import Component
|
|
|
|
import logging
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AmazonStockPicking(models.Model):
|
|
_name = 'amazon.stock.picking'
|
|
_inherit = 'amazon.binding'
|
|
_inherits = {'stock.picking': 'odoo_id'}
|
|
_description = 'Amazon Delivery Order'
|
|
|
|
odoo_id = fields.Many2one(comodel_name='stock.picking',
|
|
string='Stock Picking',
|
|
required=True,
|
|
ondelete='cascade')
|
|
amazon_order_id = fields.Many2one(comodel_name='amazon.sale.order',
|
|
string='Amazon Sale Order',
|
|
ondelete='set null')
|
|
|
|
@job(default_channel='root.amazon')
|
|
@related_action(action='related_action_unwrap_binding')
|
|
@api.multi
|
|
def export_picking_done(self):
|
|
""" Export a complete or partial delivery order. """
|
|
self.ensure_one()
|
|
self = self.sudo()
|
|
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'
|
|
|
|
amazon_bind_ids = fields.One2many(
|
|
comodel_name='amazon.stock.picking',
|
|
inverse_name='odoo_id',
|
|
string="Amazon Bindings",
|
|
)
|
|
|
|
def has_amazon_pii(self):
|
|
self.ensure_one()
|
|
partner = self.partner_id
|
|
if not partner or not partner.email:
|
|
return False
|
|
return partner.email.find('@marketplace.amazon.com') >= 0
|
|
|
|
|
|
class StockPickingAdapter(Component):
|
|
_name = 'amazon.stock.picking.adapter'
|
|
_inherit = 'amazon.adapter'
|
|
_apply_on = 'amazon.stock.picking'
|
|
|
|
def _api(self):
|
|
return self.api_instance.feeds()
|
|
|
|
def create(self, amazon_picking, carrier_code, carrier_name, shipping_method, tracking):
|
|
amazon_order = amazon_picking.amazon_order_id
|
|
# api_instance = self.api_instance
|
|
# feeds_api = self._api()
|
|
|
|
order_line_qty = self._process_picking_items(amazon_picking)
|
|
feed_root, _message = self._order_fulfillment_feed(amazon_picking, amazon_order, order_line_qty, carrier_code, carrier_name, shipping_method, tracking)
|
|
feed_data = self._feed_string(feed_root)
|
|
|
|
feed = self.env['amazon.feed'].create({
|
|
'backend_id': amazon_order.backend_id.id,
|
|
'type': 'POST_ORDER_FULFILLMENT_DATA',
|
|
'content_type': 'text/xml',
|
|
'data': b64encode(feed_data),
|
|
'amazon_stock_picking_id': amazon_picking.id,
|
|
})
|
|
|
|
feed.with_delay(priority=20).submit_feed()
|
|
_logger.info('Feed for Amazon Order %s for tracking number %s created.' % (amazon_order.external_id, tracking))
|
|
return True
|
|
|
|
def _process_picking_items(self, amazon_picking):
|
|
amazon_order_line_to_qty = {}
|
|
amazon_so_lines = amazon_picking.move_lines.mapped('sale_line_id.amazon_bind_ids')
|
|
for so_line in amazon_so_lines:
|
|
stock_moves = amazon_picking.move_lines.filtered(lambda sm: sm.sale_line_id.amazon_bind_ids in so_line and sm.quantity_done)
|
|
if stock_moves:
|
|
amazon_order_line_to_qty[so_line.external_id] = sum(stock_moves.mapped('quantity_done'))
|
|
return amazon_order_line_to_qty
|
|
|
|
def _order_fulfillment_feed(self, amazon_picking, amazon_order, order_line_qty, carrier_code, carrier_name, shipping_method, tracking):
|
|
root, message = self._feed('OrderFulfillment', amazon_order.backend_id)
|
|
order_fulfillment = self.ElementTree.SubElement(message, 'OrderFulfillment')
|
|
self.ElementTree.SubElement(order_fulfillment, 'AmazonOrderID').text = amazon_order.external_id
|
|
self.ElementTree.SubElement(order_fulfillment, 'FulfillmentDate').text = fields.Datetime.from_string(amazon_picking.create_date).isoformat()
|
|
fulfillment_data = self.ElementTree.SubElement(order_fulfillment, 'FulfillmentData')
|
|
self.ElementTree.SubElement(fulfillment_data, 'CarrierCode').text = carrier_code
|
|
self.ElementTree.SubElement(fulfillment_data, 'CarrierName').text = carrier_name
|
|
self.ElementTree.SubElement(fulfillment_data, 'ShippingMethod').text = shipping_method
|
|
self.ElementTree.SubElement(fulfillment_data, 'ShipperTrackingNumber').text = tracking
|
|
for num, qty in order_line_qty.items():
|
|
item = self.ElementTree.SubElement(order_fulfillment, 'Item')
|
|
self.ElementTree.SubElement(item, 'AmazonOrderItemCode').text = num
|
|
self.ElementTree.SubElement(item, 'Quantity').text = str(int(qty)) # always whole
|
|
return root, message
|
|
|
|
|
|
class AmazonBindingStockPickingListener(Component):
|
|
_name = 'amazon.binding.stock.picking.listener'
|
|
_inherit = 'base.event.listener'
|
|
_apply_on = ['amazon.stock.picking']
|
|
|
|
def on_record_create(self, record, fields=None):
|
|
record.with_delay(priority=10).export_picking_done()
|
|
|
|
|
|
class AmazonStockPickingListener(Component):
|
|
_name = 'amazon.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 ``amazon.stock.picking`` record. This record will then
|
|
be exported to Amazon.
|
|
|
|
:param picking_method: picking_method, can be 'complete' or 'partial'
|
|
:type picking_method: str
|
|
"""
|
|
sale = record.sale_id
|
|
if not sale:
|
|
return
|
|
if record.carrier_id.delivery_type == 'amazon_sp_mfn':
|
|
# buying postage through Amazon already marks it shipped.
|
|
return
|
|
for amazon_sale in sale.amazon_bind_ids:
|
|
self.env['amazon.stock.picking'].sudo().create({
|
|
'backend_id': amazon_sale.backend_id.id,
|
|
'odoo_id': record.id,
|
|
'amazon_order_id': amazon_sale.id,
|
|
})
|