Bug with missing depend (and solution :-) )

Hi, I recently had a strange bug since migration to 7.2 with some custos. I just want to share with you the problem I met and the solution.

When creating a new purchase and clicking on “Ok” after selecting a product to add on a purchase line, I had this error:

AssertionError: (Pool().get('purchase.line')({}), 'moves')

Here’s the traceback:


16776 140325407409856 [2024-10-04 09:01:35,513] ERROR trytond.protocols.dispatcher purchase.line.on_change_with({'product': 4425, 'id': -2, 'company': 1, 'tariff_code': None, 'product_supplier': None, 'product_secondary_uom_category': None, 'product_uom_category': None, '[_parent_purchase.party](http://_parent_purchase.party)': 1441, 'purchase': {'company': 1, 'currency': 44, 'description': '', 'id': -1, 'invoice_state': 'none', 'number': '', 'party': 1441, 'purchase_date': [datetime.date](http://datetime.date)(2024, 10, 4), 'reference': '', 'revision': 0, 'shipment_state': 'none', 'state': 'draft', 'untaxed_amount': Decimal('0.00'), 'warehouse': 5, 'alfresco_links': [], 'amendments': [], 'available_incoterms': [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22], 'comment': '', 'confirmed_by': None, 'contact': None, 'delivery_date': None, 'incoterm': None, 'incoterm_location': None, 'incoterm_location_required': False, 'invoice_address': 1536, 'invoice_method': 'shipment', 'invoice_party': None, 'invoices': [], 'invoices_ignored': [], 'origin': None, 'party_lang': 'en', 'payment_term': None, 'quoted_by': None, 'shipping_mode': None, 'tax_amount': Decimal('0.00'), 'total_amount': Decimal('0.00')}, '[_parent_purchase.company](http://_parent_purchase.company)': 1, 'purchase_description': ''}, ['purchase_description', 'product_uom_category', 'product_secondary_uom_category', 'tariff_code'], {'client': '2be797f5-e69b-42bc-bb5b-f29db6271880', 'warehouse': 5, 'company_filter': 'one', 'employee': 16, 'company': 1, 'language': 'en', 'language_direction': 'ltr', 'groups': [7, 8, 34, 33, 1, 41, 42, 4, 10, 5, 2, 11, 6, 3, 29, 9, 12, 17, 16, 22, 35, 20, 24, 23, 40, 25, 36, 21, 26, 18, 19, 37, 14, 13, 15, 39, 38, 30], 'roles': [], 'label_printer': 4}) from admin@127.0.0.1/tryton_preciball_prod_72_test2/ in 37 ms
Traceback (most recent call last):
File "/home/mrichez/Workspace/tryton/issues/tryton_72_dev/trytond/trytond/protocols/dispatcher.py", line 221, in _dispatch
result = rpc.result(meth(inst, *c_args, <strong>c_kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mrichez/Workspace/tryton/issues/tryton_72_dev/trytond/trytond/model/fields/field.py", line 195, in on_change_result
return record._changed_values
^^^^^^^^^^^^^^^^^^^^^^
File "/home/mrichez/Workspace/tryton/issues/tryton_72_dev/trytond/trytond/model/modelview.py", line 891, in _changed_values
assert hasattr(init_record, fname), (init_record, fname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: (Pool().get('purchase.line')(</strong>{}), 'moves')
16776 140325407409856 [2024-10-04 09:01:35,515] ERROR trytond.protocols.wrappers <JSONRequest 1@127.0.0.1 'http://localhost:8000/tryton_preciball_prod_72_test2/' [POST] model.purchase.line.on_change_with> in 39 ms

It took me a long time to identify the problem (because my custo is quite big). I had to include step by step code to locate the problem.
Here’s my custom code (which is the origin of the error message):

from trytond.model import fields
from trytond.pyson import Eval
from trytond.pool import PoolMeta


class PurchaseLine(metaclass=PoolMeta):
    __name__ = 'purchase.line'

    tariff_code = fields.Function(
            fields.Many2One('customs.tariff.code', "Tariff Code",
        states={
            'invisible': Eval('type') != 'line',
            }), 'on_change_with_tariff_code')

    @fields.depends('product', methods=['_tarif_code_pattern'])
    def on_change_with_tariff_code(self, name=None):
        if self.product:
            tariff_code = self.product.get_tariff_code(
                self._tariff_code_pattern())
            if tariff_code:
                return tariff_code.id

    @fields.depends('purchase', '_parent_purchase.party')
    def _tariff_code_pattern(self):
        address = self.purchase.party.address_get(type='delivery')
        country = address.country if address else None
        party = self.purchase.party
        return {
            'date': self.delivery_date,
            'country': (country.id if country else None),
            'party': (party.id if party else None),
            }

Everything is ok when doing tests. The error in my code is just a missing depend in the method “def _tariff_code_pattern(self)”.
I forget to add depend on delivery_date :slight_smile:

    @fields.depends('purchase', '_parent_purchase.party', 'delivery_date')
    def _tariff_code_pattern(self):
   ....

Still don’t know why such error message about “moves” that makes really hard to find the real problem.

1 Like

Hi Max,

Thanks for taking the effort of sharing your solutions.
Could you share the full traceback of the original error? That may help others to identify that they have the same issue.

Hi Sergi,

I updated the original post with the traceback. :slight_smile:

1 Like

Hi maxx,

It looks like the reason you got this error is that while the on_change executed, it modified the moves field (possibly because without the depends you added the code went in another branch).

Since the client did not sent the moves, the server raised the error because it detected it is sending back modifications on a field for which it does not know the value (client side).

1 Like

This is because delivery_date is a Function field so as it was not sent for the on_change, it has been computed by calling the getter.
The getter is accessing the moves so it has a depends on it (but it is not part of the definition of the view) so the depends decorator assign a default value to it as it is not know.
Then you have the moves field which is modified for the instance and the assert detect it.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.