以编程方式将产品添加到购物车 – Odoo 13

Programmatically add products to a cart – Odoo 13

我有一个创建表单的自定义模块。根据此表单中的答案,我正在生成订单行。用户发送此表单后,我将使用生成的订单行中的所有产品创建销售订单。

所以从 JavaScript 我要发送一个 JSON 和要购买的产品:

order_data = [{product_id: 1, amount: 10, …},{product_id: 2, …}, …];
note = '';
this._rpc({
        route: '/api/create_order',
        params: { order_products: order_data, note: note }
    }).then((data) => {
        window.location = '/contactus-thank-you';
    }).catch((error) => {
        console.error(error);
    });

然后在 Python 中,我根据 JSON 创建销售订单:

@http.route('/api/create_order', type='json', auth='user', website=True)
def create_order(self, **kw):
    uid = http.request.env.context.get('uid')
    partner_id = http.request.env['res.users'].search([('id','=',uid)]).partner_id.id
    
    order_products = kw.get('order_products', [])
    note = kw.get('note', '')
    order_line = []

    for product in order_products:

        amount = 0
        if 'custom_amount' in product:
            amount = product['custom_amount']
        else:
            amount = product['amount']

        if amount > 0:
            order_line.append(
                (0, 0, {
                    'product_id': product['product_id'],
                    'product_uom_qty': amount,
                }))

    order_data = {
        'name': http.request.env['ir.sequence'].with_user(SUPERUSER_ID).next_by_code('sale.order') or _('New'),
        'partner_id': partner_id,
        'order_line': order_line,
        'note': note,
    }

    result_insert_record = http.request.env['sale.order'].with_user(SUPERUSER_ID).create(order_data)
    return result_insert_record.id

但是我需要使用 Odoo 的电子商务插件中的工作流而不是直接生成销售订单。这样用户就可以编辑送货地址,选择付款等。所以我认为我只需要以编程方式将所有产品放入购物车中,然后其余部分将由 Odoo 内置功能处理。 但是怎么办?我试图在 Odoo 源代码中找到一些东西,但很难掌握任何东西。

Odoo 使用典型的销售订单来处理购物车内的产品。但是这个过程并不像使用某些产品创建销售订单那么简单。 Odoo 需要知道哪个订单与哪个购物车相关联等。

幸运的是,Odoo 有处理它的方法。有一种 sale_get_order() 方法可让您获取当前与购物车关联的订单,或者在没有购物车时创建新订单。

我不确定它是否在源代码之外的任何地方记录,所以这里是代码的一部分 (/addons/website_sale/models/website.py):

def sale_get_order(self, force_create=False, code=None, update_pricelist=False, force_pricelist=False):
    """ Return the current sales order after mofications specified by params.
    :param bool force_create: Create sales order if not already existing
    :param str code: Code to force a pricelist (promo code)
                        If empty, it's a special case to reset the pricelist with the first available else the default.
    :param bool update_pricelist: Force to recompute all the lines from sales order to adapt the price with the current pricelist.
    :param int force_pricelist: pricelist_id - if set,  we change the pricelist with this one
    :returns: browse record for the current sales order
    """
# ...

我将它与另一种方法 _cart_update() 一起使用,可以让我轻松更新此订单中的产品。还有 sale_reset(),我使用它只是为了确保当前会话每次都会使用特定的销售订单进行更新。

sale_order = request.website.sale_get_order(force_create=True)
request.website.sale_reset()
sale_order.write({'order_line':[(5, 0, 0)]})

for product in order_products:
    sale_order._cart_update(product_id=product['product_id'], line_id=None, add_qty=None, set_qty=product['amount'])