跳至内容

对接 DHL 经验记录

1. delivery.carrier表

系统中有一张delivery.carrier表,定义了运输类型的相关信息

2. delivery_dhl模块

  1. odoo15内置的dhl对接模块,用的是XMLPI接口,对接的是DHL Express。DHL下面分了很多服务,不同服务有不同接口,如果不是DHL Express,要使用其他相应的接口
  2. delivery_dhl是结合delivery_carrier表开发的
  3. delivery_carrier表中有一个字段Provider【delivery_type】,可以用来配置类型,在代码中会根据类型执行对应的方法
  4. 在delivery模块的delivery_carrier.py中,定义了一个方法send_shipping,代码如下
def send_shipping(self, pickings):
    ''' Send the package to the service provider

    :param pickings: A recordset of pickings
    :return list: A list of dictionaries (one per picking) containing of the form::
                     { 'exact_price': price,
                       'tracking_number': number }
                       # TODO missing labels per package
                       # TODO missing currency
                       # TODO missing success, error, warnings
    '''
    self.ensure_one()
    if hasattr(self, '%s_send_shipping' % self.delivery_type):
        return getattr(self, '%s_send_shipping' % self.delivery_type)(pickings)
  1. 可以看到,这里会根据delivery_type调用方法,调用的方法名为

'%s_send_shipping' % self.delivery_type

DHL即为dhl_send_shipping

a. dhl_send_shipping方法

  1. 在dhl_request.py文件中,提供了DHLProvider对象,用来处理dhl对接请求,和delivery_type中的设置对应
  2. 在调用dhl_send_shipping时,使用DHLProvider处理请求
  3. 方法的返回值为
{
    'exact_price': 0,
    'tracking_number': traking_number,
}
  1. 返回值会交给调用send_shipping方法的前一方法send_to_shipper,该方法会根据carrier上的设置,对运输价格运单号进行设置和处理。

b. get_return_label方法

  1. 在delivery_carrier.py中,定义了get_return_label
  2. 代码如下
def get_return_label(self,pickings, tracking_number=None, origin_date=None):
    self.ensure_one()
    if self.can_generate_return:
        return getattr(self, '%s_get_return_label' % self.delivery_type)(pickings, tracking_number, origin_date)

c. can_generate_return字段

  1. 通过_compute_can_generate_return方法计算,默认为false
  2. get_return_label方法依赖这个字段,字段为true才会调用相应的return label方法
  3. 可以自行改写_compute_can_generate_return,示例
def _compute_can_generate_return(self):
    super(Providerdhl, self)._compute_can_generate_return()
    for carrier in self:
        if carrier.delivery_type == 'dhl':
            carrier.can_generate_return = True

d. 调用流程

在系统操作完成transfer单 → 触发内部的方法【多个方法,请阅读action_done源码,此处略过】 → 触发send_shipping → 触发 %s_send_shipping 【内部调用Provider对象】

e. 注意

一直向前追溯,可以发现,该方法是在transfer【stock.picking】action_done时触发的,也就是transfer单完成时,会自动触发send_shipping的对接功能

3. 扩展思路

a. 流程

    1. 当我们需要扩展对接功能或者新增对接时,为了和系统保持一致性,建议保持和系统相似的逻辑
    2. 新增对应的Provider类型
      1. 新增对应send_shipping方法,用于对接操作
        1. 需要确保方法的返回值与系统的一致,以确保兼容性
    3. 在carrier增加相关的配置信息,用于请求时的处理
    4. carrier上有个Invoicing Policy,可以设置运费的计算方式

b. Provider对象

ⅰ. 用于处理对接请求

ⅱ. 初始化时

1. 设置url

      1. 沙盒
      2. 生产

2. 请求类型

      1. 根据类型初始化不同的参数

3. debug_logger

      1. 接收carrier内置的log_xml函数对象
      2. 用于调试模式时使用
      3. 记录请求和相应参数


Odoo
Odoo 学习笔记-2