You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 17:通过API为销售订单创建发票的正确方法

问题:通过Odoo API为销售订单创建发票的正确方式

我已使用sale.order模型及以下请求体创建了Odoo销售订单(测试时所有订单行使用同一Odoo产品ID):

{
    "company_id": 1,
    "name": "10000",
    "partner_id": 17,
    "partner_invoice_id": 22,
    "partner_shipping_id": 23,
    "client_order_ref": "10000",
    "carrier_id": 2,
    "order_line": [
        [
            0,
            0,
            {
                "product_id": 414,
                "display_name": "Product #2",
                "name_short": "Product #2",
                "name": "Product #2",
                "product_uom_qty": 1,
                "price_unit": 103.36,
                "purchase_price": 40,
                "price_tax": 19.64
            }
        ],
        [
            0,
            0,
            {
                "product_id": 414,
                "display_name": "Demo Product with Variants",
                "name_short": "Demo Product with Variants",
                "name": "Demo Product with Variants",
                "product_uom_qty": 1,
                "price_unit": 84.03,
                "purchase_price": 40,
                "price_tax": 15.97
            }
        ],
        [
            0,
            0,
            {
                "product_id": 414,
                "display_name": "Shipping Costs",
                "name_short": "Shipping Costs",
                "name": "Shipping Costs",
                "product_uom_qty": 1,
                "price_unit": 8.4,
                "purchase_price": 40,
                "price_tax": 0
            }
        ]
    ]
}

之后尝试为该销售订单创建发票时,发现action_invoice_generate方法已废弃,于是改用account.move模型手动创建发票,请求体如下(通过invoice_origin关联销售订单):

{
    "partner_id": 22,
    "move_type": "out_invoice",
    "invoice_date": "2024-04-19",
    "invoice_line_ids": [...],
    "invoice_origin": "10000"
}

现在发票已创建并关联销售订单,但重新打开销售订单时,「Create Invoice」按钮仍可用,且未显示该发票。我考虑手动将发票ID添加到sale.order的invoice_ids列表,并设置invoice_status,但不确定invoice_count、amount_invoiced等字段该如何处理,请问通过API为销售订单创建发票的最佳方式是什么?


解决方案

优先使用Odoo标准API方法

废弃action_invoice_generate后,Odoo提供了**sale.order模型的action_create_invoice方法**,这是前端「Create Invoice」按钮对应的后台方法,能自动处理所有关联逻辑、状态更新和字段计算,是最优方案。

调用该方法的核心优势:

  • 自动创建与销售订单双向关联的发票(同步销售订单invoice_ids和发票sale_order_ids)
  • 自动更新销售订单的invoice_status、invoice_count、amount_invoiced等计算字段
  • 自动同步订单行已开票数量(qty_invoiced),保证数据一致性
  • 无需手动处理复杂的关联逻辑

调用示例(JSON-RPC)

import json
import requests

url = "http://your-odoo-instance/jsonrpc"
payload = {
    "jsonrpc": "2.0",
    "method": "call",
    "params": {
        "model": "sale.order",
        "method": "action_create_invoice",
        "args": [[1]],  # 1为目标销售订单ID,传入列表格式
        "kwargs": {
            # 可选:自定义发票参数,如开票日期
            "invoice_date": "2024-04-19"
        },
        "context": {"lang": "zh_CN", "tz": "Asia/Shanghai"}
    },
    "id": 1
}

response = requests.post(url, json=payload)
result = response.json()
# 返回结果包含创建的发票ID列表
invoice_ids = result.get("result", [])

特殊场景下手动创建发票的完整流程

如果因业务需求必须手动创建account.move,需要完成以下步骤保证数据完全同步:

  1. 创建发票时关联销售订单及订单行
    创建account.move时,不仅要通过sale_order_ids关联销售订单,还要为每个发票行通过sale_line_ids关联对应销售订单行,示例:

    {
        "partner_id": 22,
        "move_type": "out_invoice",
        "invoice_date": "2024-04-19",
        "invoice_line_ids": [
            [
                0,
                0,
                {
                    "product_id": 414,
                    "name": "Product #2",
                    "quantity": 1,
                    "price_unit": 103.36,
                    "sale_line_ids": [[4, 123]]  # 123为对应销售订单行ID
                }
            ]
        ],
        "sale_order_ids": [[4, 1]]  # 1为目标销售订单ID
    }
    
  2. 更新销售订单的关联与状态
    调用sale.order的write方法,将发票ID添加到invoice_ids并设置正确的发票状态:

    {
        "model": "sale.order",
        "method": "write",
        "args": [
            [1],  # 目标销售订单ID
            {
                "invoice_ids": [[4, invoice_id]],  # invoice_id为刚创建的发票ID
                "invoice_status": "invoiced"  # 根据实际情况设置:invoiced/to invoice/no invoice
            }
        ]
    }
    
  3. 强制触发计算字段更新
    如果invoice_count、amount_invoiced等字段未自动更新,可手动调用销售订单的计算方法:

    {
        "model": "sale.order",
        "method": "_compute_invoice_count",
        "args": [[1]]
    }
    
    {
        "model": "sale.order",
        "method": "_compute_amount_invoiced",
        "args": [[1]]
    }
    

总结

  • 绝大多数场景下,直接调用action_create_invoice方法是最简单、最可靠的方式,完全避免手动处理关联和计算的问题
  • 仅在特殊业务需求下才考虑手动创建发票,且必须完成完整的双向关联和字段同步,否则会出现数据不一致的情况

内容的提问来源于stack exchange,提问作者Dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:14:52