Make getting contact mechanisms with usage explicit

I walk into some problems that I get wrong email addresses back from a party where I should have get none.

For example: I want to send an invoice to a customer. To get the email address I use

email = party.contact_mechanism_get('email', usage='invoice')

So when that party doesn’t have any email with the field invoice checked, I should get nothing back. However, I got their general email address.

The same happens for delivery. I just want to have the email address which have delivery checked and not the email address for e.g. invoice.

I digged into the code and found:

Where you can see that even when there is nothing found, the first item in the list will be returnd. IMO when usage is used it should be explicit, so when nothing is found, return None. Which basically means adding an extra return None after the for-loop.

Any thoughts on this?

No this is not how it is designed (as explained in the docstring). The checkbox is a preference.

If someone wants extra check, he can still check the returned value.

But we are not going to change such historic behavior.

To avoid such behavior when sending invoices to customer, we add a function field to get only emails with ‘invoice’ checked and this function field is used to send invoices.


class Invoice(metaclass=PoolMeta):
    __name__ = 'account.invoice'

    invoice_emails = fields.Function(fields.Many2Many(
        'party.contact_mechanism', None, None, "Invoice Emails",
        domain=[
            ('party', '=', Eval('party', -1)),
            ('type', 'in', ['email']),
        ]), 'get_invoice_emails')

    def get_invoice_emails(self, name):
        mechanisms = [m for m in self.party.contact_mechanisms
            if m.type in {'email'} and getattr(m, 'invoice')]
        return mechanisms

I don’t want to do that, it feels to me like a hack because I have to do it for every place where I want an email or other contact. So there are two ways:

  1. add a config option to trytond.conf to enable the explicit search. Changes are in the core
  2. overwrite the mixin in my own module
1 Like