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

Odoo 17中如何关联stock.picking与account.move(发票)并显示智能按钮

Odoo发票过账自动创建出库单并关联智能按钮问题解决

问题概述

定制需求:account.move(发票)过账时自动创建stock.picking(出库单),并完成关联以让发票上的发货智能按钮正常显示。已知这是Odoo默认逻辑,但当前手动创建出库单后无法关联,找不到对应关联字段;手动新增字段后问题仍存在,智能按钮依旧不显示。

当前代码如下:

from odoo import fields, models, api, _

class AccountMove(models.Model):
    _inherit = 'account.move'

    def action_post(self):
        res = super(AccountMove, self).action_post()

        if not self.invoice_line_ids.sale_line_ids and self.move_type == 'out_invoice':
            picking_type = self.env.ref('stock.picking_type_out')
            stock_picking = self.env['stock.picking'].create({
                'picking_type_id': picking_type.id,
                'location_id': picking_type.default_location_src_id.id,
                'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                'partner_id': self.partner_id.id,
                'origin': self.name,
                'move_type': 'direct',
                'move_ids': [(0, 0, {
                    'name': line.name,
                    'product_id': line.product_id.id,
                    'product_uom_qty': line.quantity,
                    'product_uom': line.product_uom_id.id,
                    'location_id': picking_type.default_location_src_id.id,
                    'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                }) for line in self.invoice_line_ids if line.product_id.type == 'product']
            })

            stock_picking.action_confirm()
            for move in stock_picking.move_ids:
                self.env['stock.move.line'].create({
                    'move_id': move.id,
                    'product_id': move.product_id.id,
                    'product_uom_id': move.product_uom.id,
                    'location_id': move.location_id.id,
                    'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                    'state': 'done',
                    'picking_id': move.picking_id.id,
                })
                # Link the invoice to the picking
                #self.write({
                #    'move_ids': [(4, stock_picking.id)]
                #})
                stock_picking.button_validate()

        return res

问题分析与修复方案

核心问题点

  1. 关联字段错误:注释中尝试用move_ids关联发票和出库单,但move_ids是account.move关联自身会计分录行的字段,与stock.picking无关。
  2. 库存移动未关联发票行:创建stock.move时未绑定对应的account.move.line,导致发票无法识别关联的出库记录,智能按钮无数据可显示。
  3. 出库单验证逻辑错误:将stock_picking.button_validate()放在循环内部,会在每创建一条库存明细行后就触发验证,逻辑混乱。
  4. 库存明细行缺失必填项:创建stock.move.line时未设置qty_done,直接设state='done'会导致验证失败。

修改后的代码

from odoo import fields, models, api, _

class AccountMove(models.Model):
    _inherit = 'account.move'

    def action_post(self):
        res = super(AccountMove, self).action_post()

        if not self.invoice_line_ids.sale_line_ids and self.move_type == 'out_invoice':
            picking_type = self.env.ref('stock.picking_type_out')
            # 构建库存移动数据,关联对应的发票行
            move_vals_list = []
            for line in self.invoice_line_ids:
                if line.product_id.type == 'product':
                    move_vals_list.append((0, 0, {
                        'name': line.name,
                        'product_id': line.product_id.id,
                        'product_uom_qty': line.quantity,
                        'product_uom': line.product_uom_id.id,
                        'location_id': picking_type.default_location_src_id.id,
                        'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                        'invoice_line_id': line.id,  # 关键:绑定到发票行
                    }))
            
            stock_picking = self.env['stock.picking'].create({
                'picking_type_id': picking_type.id,
                'location_id': picking_type.default_location_src_id.id,
                'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                'partner_id': self.partner_id.id,
                'origin': self.name,
                'move_type': 'direct',
                'move_ids': move_vals_list,
            })

            stock_picking.action_confirm()
            for move in stock_picking.move_ids:
                self.env['stock.move.line'].create({
                    'move_id': move.id,
                    'product_id': move.product_id.id,
                    'product_uom_id': move.product_uom.id,
                    'location_id': move.location_id.id,
                    'location_dest_id': self.env.ref('stock.stock_location_customers').id,
                    'qty_done': move.product_uom_qty,  # 新增:设置已完成数量
                    'picking_id': move.picking_id.id,
                })
            # 所有明细行创建完成后再验证出库单
            stock_picking.button_validate()

        return res

关键修改说明

  1. 绑定库存移动到发票行:在创建stock.move时添加invoice_line_id: line.id,让库存移动与发票分录行建立关联,这样发票的stock_move_ids会自动包含这些移动记录,触发智能按钮显示。
  2. 调整验证时机:将stock_picking.button_validate()移到循环外部,确保所有库存明细行都创建完成后再执行验证,避免逻辑错误。
  3. 补充必填字段:在stock.move.line中添加qty_done并设置为对应数量,保证出库单能正常验证通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:37:34