跳至內容
選單
此問題已被標幟
1 回覆
168 瀏覽次數

In Odoo 17 purchase.order has invoices:

invoice_ids = fields.Many2many('account.move', compute="_compute_invoice", string='Bills', copy=False, store=True)

and each account.move has a purchase:

purchase_id = fields.Many2one('purchase.order', store=False, readonly=False,
string='Purchase Order',
help="Auto-complete from a past purchase order.")

I added a simple field in Purchase:

class PurchaseOrder(models.Model):
_inherit = "purchase.order"
accounting_note = fields.Char()

and want to show this field's value in each related Invoice, too:

class AccountMove(models.Model):
_inherit = "account.move"
accounting_note = fields.Char(readonly=True)

So far I tried to compute it in AccountMove, but failed:

accounting_note = fields.Char(compute="_compute_accounting_note")

@api.depends("purchase_id")
def _compute_accounting_note(self):
for record in self:
record.accounting_note = record.purchase_id.accounting_note

and to set it onchange in PurchaseOrder (write is not allowed here, according to docs), but failed too:

@api.onchange("accounting_note")
def _update_accounting_notes(self):
for record in self:
for invoice in record.invoice_ids:
invoice.accounting_note = record.accounting_note

In Purchase Order the value is fine, but it never appeared in the Invoices.
I suppose this due to certain limitations of the store/computed M2M/O2M fields.
How do I get this right?

頭像
捨棄

Hello,
Have you tried in below method?
def _prepare_invoice(self):
res = super()._prepare_invoice()
res["accounting_note"] = self.accounting_note
return res
Keep acounting_note field as it is in account.move

作者

This would only set the field for new (created) invoices.
I would prefer to fill/get this field's value for all invoices on change, not only new ones.

You can configure schedule action for old records. Is it feasible for your customization?

最佳答案

Hi,


The issue occurs because the link between Purchase Orders and Bills in Odoo 17 is based on computed and non-stored fields, which don’t automatically update or propagate values.


To display the accounting_note from the purchase order on its related bills, there are two reliable methods:


    Use a related field — define accounting_note = fields.Char(related="purchase_id.accounting_note", store=True, readonly=True).

    This automatically displays the purchase note on the bill and updates if the purchase note changes.   


     class AccountMove(models.Model):

        _inherit = "account.move"


        accounting_note = fields.Char(related="purchase_id.accounting_note", store=True, readonly=True)


    Copy the value when the bill is created — override the bill’s create method to set accounting_note from the purchase order once during creation.

    This keeps the bill’s note fixed, even if the purchase order changes later.


    class AccountMove(models.Model):

        _inherit = "account.move"


        accounting_note = fields.Char(readonly=True)


        @api.model_create_multi

        def create(self, vals_list):

            records = super().create(vals_list)

            for move in records:

                if move.purchase_id and move.purchase_id.accounting_note:

                    move.accounting_note = move.purchase_id.accounting_note

            return records


In short, the related field is best for dynamic syncing, while copying on creation is ideal for keeping a static record.


Hope it helps

頭像
捨棄
相關帖文 回覆 瀏覽次數 活動
2
7月 24
3414
1
5月 25
3972
2
7月 19
3277
0
5月 16
3960
2
4月 16
5987