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

Odoo15选择Job Card自动加载产品行到发票行报错排查

Odoo15 工卡明细同步发票行报错修复方案

问题原因

代码存在6类核心错误,直接触发运行异常:

  • 主从表关联字段定义完全错误:Job Card主模型中,除x_job_card_ids外其余关联明细的One2many字段,第二个参数(子表外键字段)错填为quantity/price等普通数值字段,x_product_ids错定义为Many2many类型且关联参数错误,根本无法读取到工卡下的产品明细数据。
  • 字段名拼写错误:生成发票行值的方法中,单价字段名price_unit前多了前置空格,写成' price_unit',Odoo无法识别字段直接抛出字段不存在的异常。
  • 字段引用不匹配:Job Card Line明细模型中定义的单价字段名为price,代码中错写为price_unit;产品字段关联的是product.template模型,而发票行产品字段要求关联product.product模型,类型不匹配触发约束报错。
  • 方法写法不规范:Onchange方法中调用update方法赋值One2many字段不符合Odoo规范,且未做空值判断,清空工卡字段时会触发空记录集调用方法的报错。
  • 发票行必填字段缺失:创建发票行时仅传入数量、单价两个字段,缺少product_id/name/tax_ids等必填字段,即使字段名正确也会触发必填校验报错。
  • 精度问题:Job Card Line的total字段定义为Integer整数类型,单价为Float浮点数,相乘后会丢失小数精度。

修正后代码

1. 修正Job Card主模型

删除原有错误的明细关联字段,替换为正确的One2many定义,同时修正发票行值生成方法:

class JobCard(models.Model):
    _name = "job.card"
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = "Job Card Master"
    _rec_name = 'job_card_number'

    job_card_number = fields.Char(string='Job Card No.', readonly=True)
    customer_id = fields.Many2one('res.partner', string="Customer Name", tracking=True)
    vehicle_id = fields.Many2one('res.partner.line', string="Vehicle", tracking=True,
                                 domain="[('x_customer_id','=',customer_id)]")
    date_time_of_invoice = fields.Datetime(string='Date & Time of Invoice', tracking=True, default=fields.Datetime.now)
    start_date_time = fields.Datetime(string='Start Date & Time', tracking=True)
    end_date_time = fields.Datetime(string='End Date & Time', tracking=True)
    priority = fields.Selection([
        ('0', 'Normal'),
        ('1', 'Low'),
        ('2', 'High'),
        ('3', 'Very High')], string="Priority")
    state = fields.Selection([
        ('draft', 'Draft'),
        ('in_progress', 'In Progress'),
        ('done', 'Done'),
        ('cancel', 'Cancelled')], string="Status", default='draft', required=True)
    active = fields.Boolean(string="Active", default=True, tracking=True)
    # 正确的明细行One2many关联:第二个参数为子表指向主表的外键字段名job_card_id
    job_card_line_ids = fields.One2many('job.card.line', 'job_card_id', string="Job Card Details")

    job_card_count = fields.Integer(compute='compute_job_card_count', string='Job Card Count')

    def get_invoice_line_vals(self):
        vals_list = []
        for line in self.job_card_line_ids:
            vals_list.append({
                # 关联product.product模型记录,取产品模板下的第一个可销售变体
                'product_id': line.product_id.product_variant_id.id,
                # 修正字段名,去掉前置空格,取明细行的price字段作为单价
                'price_unit': line.price,
                'quantity': line.quantity,
                # 补全发票行必填的名称字段
                'name': line.product_id.display_name,
                # 补全税费字段,自动带产品默认税费
                'tax_ids': [(6, 0, line.product_id.taxes_id.ids)]
            })
        return vals_list

2. 修正Job Card Line明细模型

调整金额字段类型避免精度丢失:

class JobCardLine(models.Model):
    _name = "job.card.line"

    job_card_id = fields.Many2one('job.card', string="Job Card Id", tracking=True)
    product_id = fields.Many2one('product.template', string="Product", tracking=True)
    quantity = fields.Integer(string="Quantity", tracking=True)
    price = fields.Float(string="Price")
    # 改为Float类型避免小数精度丢失
    total = fields.Float(string='Total', compute='_compute_total', tracking=True,
                       help="This field will be calculated from quantity and price !")
    employee_id = fields.Many2one('hr.employee', string="Employee", tracking=True)
    x_job_card_id = fields.Many2one('res.partner', string="Vehicle Details")

    @api.onchange('product_id')
    def _on_change_product_id(self):
        self.price = self.product_id.list_price

    @api.depends('quantity', 'price')
    def _compute_total(self):
        for rec in self:
            rec.total = rec.quantity * rec.price

3. 修正发票模型的Onchange方法

规范赋值逻辑,增加空值判断:

class CustomInvoice(models.Model):
    _inherit = "account.move"

    job_card_id = fields.Many2one('job.card', string="Job Card", domain="[('customer_id','=',partner_id)]",
                                  tracking=True)

    @api.onchange('job_card_id')
    def _onchange_job_card_id(self):
        # 先清空原有发票明细
        self.invoice_line_ids = [(5, 0, 0)]
        # 未选择工卡时直接返回,避免空对象报错
        if not self.job_card_id:
            return
        # 生成发票明细值并赋值
        invoice_lines_vals = self.job_card_id.get_invoice_line_vals()
        self.invoice_line_ids = [(0, 0, vals) for vals in invoice_lines_vals]
        # 可选:自动带工卡关联的客户到发票
        self.partner_id = self.job_card_id.customer_id

升级模块后重启Odoo服务,功能即可正常运行。

内容的提问来源于stack exchange,提问作者mr.robot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:45:32