AttributeError upon Access to Present Attribute

Hello,

using trytond V 6.8.1 I tried to add a Function field to access the supplier’s product code.

I cannot make the following method working as it raises an:

AttributeError: 'purchase.product_supplier' Model has no attribute 'code': <trytond.model.model.purchase.product_supplier._record object at ...>

The access to the purchase_product_supplier.code attribute is validated by the preceding if statement. Hence I would not expect an error.

Here is the code:

purchase_product_supplier_code = fields.Function(
    fields.Char('Supplier_Code'),
    'get_purchase_product_supplier_code')

# lines omitted (....)

def get_purchase_product_supplier_code(self, name):
    """Return the supplier code of the product for the supplier of the
    quotation."""

    pool = Pool()
    ProductSupplier = pool.get('purchase.product_supplier')
    # get code from purchase.product.supplier where party = quotation.supplier and product = self.product
    if self.quotation and self.quotation.supplier and self.product:
        purchase_product_supplier = ProductSupplier(
                party=self.quotation.supplier.id,
                product=self.product.id,
                company=self.quotation.company)
        if purchase_product_supplier and 'code' in dir(purchase_product_supplier):
            return purchase_product_supplier.code

I believe in your code:

    # get code from purchase.product.supplier where party = quotation.supplier and product = self.product
    if self.quotation and self.quotation.supplier and self.product:
        purchase_product_supplier = ProductSupplier(
                party=self.quotation.supplier.id,
                product=self.product.id,
                company=self.quotation.company)

You are not loading the specific purchase product supplier, but instead you are creating a new instance, hence member attribute code has not been initialized with any value and therefore the error.
If you want to load the purchase product supplier from the DB with the specific supplier id, product id and company, you should use the search function. I.e.:

# get code from purchase.product.supplier where party = quotation.supplier and product = self.product
    if self.quotation and self.quotation.supplier and self.product:
      purchase_product_suppliers = ProductSupplier.search([
        ('party', '=', self.quotation.supplier.id),
        ('product', '=', self.product.id),
        ('company', '=', self.quotation.company)
      ], limit = 1)
      if purchase_product_suppliers:
        purchase_product_supplier = purchase_product_suppliers[0] 
     ....

I hope this helps.

It helped! Thank you very much.

The proper way to retrieve product suppliers from a product is by calling product.product_suppliers_used() with the proper pattern.

If the ProductSupplier.search(...) method call is replaced by:

purchase_product_suppliers = self.product.product_suppliers_used({'party': self.quotation.supplier.id})

I get:

    purchase_product_suppliers = self.product.product_suppliers_used(
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Product.product_suppliers_used() takes 1 positional argument but 2 were given

It must be:

self.product.product_suppliers_used(party=self.quotation.supplier.id, company=self.quotation.company.id)

Thank you, I switched over to your suggestion.

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