Odoo Help

Welcome!

This community is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.

0

how to display selection field content even though the referenced record's 'active' attribute is set to false

By
Stefan Reichel
on 8/14/14, 11:16 AM 2,770 views

Hi,

The predecessor thread is https://www.odoo.com/forum/help-1/question/how-to-add-a-selection-field-which-pulls-tuples-values-from-another-table-60157

The xml view does not filter for the "Active" attribute yet, but when I set the attribute active to false in the DB table, the entry is not shown in the CRM Lead record anymore even though it is still stored withthe record. When I set active=true the field res_partner_leadsource_id is shown again.

Is there some special general feature linked to any attribute named "active"?

The idea is, that the field "Lead Source" is required to be set upon creation of the crm_lead record and may not be changed thereafter. Only currently active lead sources may be assigned to leads. But inactive lead sources shall still be valid. Example: Lead source 'Trade fair 2013' and 'Trade fair 2014' exist. Once all contacts made at the fair in 2013 are entered and linked to that source, the source shall be set to active=false, so that no new contacts can be linked to that lead source.

...
<field name="partner_name" position="after">
   <field name="res_partner_leadsource_id" widget="selection" placeholder="contact source" class="oe_no_button" required="1" attrs="{'readonly':[('name','=',False)]}"/>
</field>

 

The above approach does not work, removing the "attrs" attribute will make the field changeable upon edit which is not desired.

...
       <record id="view_leadsource_tree" model="ir.ui.view">
            <field name="name">res.partner.leadsource.tree</field>
            <field name="model">res.partner.leadsource</field>
            <field name="arch" type="xml">
                <tree string="Lead Source">
                    <field name="id" />
                    <field name="name"/>
                    <field name="description"/>
                    <field name="active"/>
                </tree>
            </field>
        </record>

        <record id="view_leadsource_form" model="ir.ui.view">
            <field name="name">res.partner.leadsource.form</field>
            <field name="name">res.partner.leadsource.form</field>
            <field name="model">res.partner.leadsource</field>
            <field name="arch" type="xml">
                <form string="Lead Source" version="7.0">
                    <group>
                        <group>
                            <field name="name"/>
                        </group>
                        <group>
                            <field name="description"/>
                            <field name="active"/>
                        </group>
                    </group>
                </form>
            </field>
        </record>

        <record id="action_leadsource" model="ir.actions.act_window">
            <field name="name">Lead Sources</field>
            <field name="type">ir.actions.act_window</field>
            <field name="res_model">res.partner.leadsource</field>
            <field name="view_type">form</field>
            <field name="help">Display and manage the list of all lead sources that can be assigned to your lead and partner records. You can create or activate or deactivate lead sources to make sure the ones you are working on will be maintained.</field>
        </record>

        <menuitem action="action_leadsource" id="menu_leadsource_partner" parent="base.menu_config_address_book" sequence="1" groups="base.group_no_one"/>
...

crm.py

...
class crm_lead(osv.osv):
     _inherit = "crm.lead"

     def _leadsource_selection(self, cr, uid, context=None):
          leadsource_obj = self.pool.get('res.partner.leadsource');
          res = [];
          leadsource_ids = leadsource_obj.search(cr, uid, []);
          for leadsource in leadsource_obj.browse(cr, uid, leadsource_ids, context=context):
                 res.append((leadsource.id, leadsource.name))
          return res;

     _columns = {
      'res_partner_leadsource_id': fields.many2one('res.partner.leadsource', 'Source', selection=_leadsource_selection, required="True", select="True",help="where did we get the contact from or where did the contact hear about us"),
     }

crm_lead()
...

res_partner_leadsource.py

class res_partner_leadsource(osv.Model):
    _name = "res.partner.leadsource"
    _description = "Lead Source"
    _order = 'name'
    _columns = {
        'id': fields.integer('Lead Source ID', size="4"),
        'name': fields.char('Lead Source Name', size=64, required=True),
        'active': fields.boolean('Active'),
        'description': fields.char('Lead Source Description', size=200, required=True),
    }
    _defaults = {
        'active': lambda *a: 1,
    }
res_partner_leadsource()

Can someone please guide me how to make the field readonly once the record is created. I also need some guidance in how to make the record still appear in linked records even though the leadsource record has active=false.

Hi Marvin, that explained why the inactive entries where not displayed. But how can I achieve that inactive entries cannot be assigned to new records but will be displayed in previously assigned leads?

Stefan Reichel
on 8/15/14, 3:43 AM

Hi René, as for the "attrs" attribute: the filter "active" would apply to the crm.lead field active but not to the referenced field res.partner.leadsource's field active, wouldn't it? Anyway, applying this, didn't not make a difference. I wonder if I could test for 'create_date' of crm.lead and make the field readonly if that's empty meaning we're about to create the lead and we are not editing. As per Marvin's hint, I applied domain="['|',('active','=',True),('active','=',False)]" to the view's field definition and now I can see all entries but I cannot select an inactive one. I do get a cryptic (for end users) error message, but at least the functionality is there. At this stage, it's now down to the read-only. (But I will try your code anyways). About your hint: why not have an id explicitly in res.partner.leadsource? Cheers, Stefan

Stefan Reichel
on 8/15/14, 5:01 AM

not having the the ID linked but the name as FK would make the error message more readable when selecting inactive leadsources. Currently I get 'The value "1" for the field "crm_lead.res_partner_leadsource_id" is not in the selection' which would then replace "1" with the name value. But from a DB (performance) point of view my old school tech degree suggested to link on fields that are quickly to compare/compute, i.e. numbers. But my degree thesis is already >10 years old and DB technology has advanced. Is FK linking on a char field recommended nowadays?

Stefan Reichel
on 8/15/14, 5:13 AM

You are absolutely right about the attrs attribute. I've edited my answer. Please post the error message when trying to select an inactive leadsource.

René Schuster
on 8/15/14, 5:23 AM

A bit of thinking, digging, trying got me to The domain displays active and inactive lead sources. The attrs makes sure that once the lead has a name (the only mandatory field in crm.lead), the source is unchangeable. The crux is, that the readonly attribute and the linked condition is evaluated on the client, i.e. in the browser. Entering a lead name, makes the leadsource field readonly if focus changes from the name field. Can this logic be applied on the server prior to sending the data to the client?

Stefan Reichel
on 8/15/14, 5:36 AM

Hi René, the error message when saving with an inactive entry selected is 'The value "1" for the field "crm_lead.res_partner_leadsource_id" is not in the selection'

Stefan Reichel
on 8/15/14, 5:37 AM

I think I've nailed the "readonly" case with attrs="{'readonly': [('id','!=',False)]}" and The ID gets created when saved and is NULL/empty before. Adding the ID field to the view and base our readonly on that field, seems to have done what I wanted. Now I either have to filter the selection list (in edit/create view only) or I have to amend the error message (Tupel/field definition from integer to char [using the name field]).

Stefan Reichel
on 8/15/14, 5:53 AM

My next approach was to utilize the "disabled" attribute to a select-option in HTML and amend _leadsource_selection: leadsource_key = `leadsource.id` if not leadsource.active: leadsource_key += '" disabled="disabled' res.append((leadsource.id, leadsource.name))

Stefan Reichel
on 8/15/14, 6:30 AM
2
Marvin Taboada
On 8/14/14, 12:13 PM

Hello Stefan,

The ORM layer automatically applies the ('active', '=', 1) filter for searches, name searches, group-by and tabular lists, provided the following 2 conditions are met:

  1. The related entity explicitly defines an 'active' column (a boolean column is expected), and
  2. 'active' has not explicitly been defined in the filter (either 0 or 1)

You can review the ORM related code (for branch 7.0) here: https://github.com/odoo/odoo/blob/7.0/openerp/osv/orm.py#L4766

If you require to list active and inactive records, you require to define an appropriate domain where required.

As you can see in the underlying "private" method of the link, there are other two low level options to skip filtering inactive records, an 'active_test' parameter for this methods (which defaults to True) and a 'active_test' context parameter.

1

René Schuster

--René Schuster--
1560
| 5 5 8
Weinheim, Germany
--René Schuster--

Challenge Everything!

René Schuster
On 8/15/14, 4:21 AM

Some things I can think of:

(EDIT)
1. To make the lead source field readonly when the lead source is inactive:

def _get_leadsource_state(self, cr, uid, ids, field_name, args, context=None):
    res = {};
    for obj in self.browse(cr, uid, ids, context=context):
        res[obj.id] = obj.res_partner_leadsource_id.active or True;
    return res;

_columns = {
    'leadsource_state': fields.function(_get_leadsource_state, type='boolean', method=True, string="Lead Source State"),
}

<field name="leadsource_state" invisible="1"/>
<field name="res_partner_leadsource_id" [ . . . ] attrs="{'readonly': [('lead_source_active','=',False)]}"/>

2. To avoid assigning inactive lead sources to a lead:

def _leadsource_selection(self, cr, uid, context=None):
          leadsource_obj = self.pool.get('res.partner.leadsource');
          res = [];
          leadsource_ids = leadsource_obj.search(cr, uid, [('active','=',True)]);
          for leadsource in leadsource_obj.browse(cr, uid, leadsource_ids, context=context):
                 res.append((leadsource.id, leadsource.name))
          return res;

Hint: I don't think it's good to define the 'id' field explicitly on res_partner_leadsource model. Just a feeling. Maybe it's screwing up id constraints and requirements.

Regards.

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

About This Community

This community is for professionals and enthusiasts of our products and services. Read Guidelines

Question tools

2 follower(s)

Stats

Asked: 8/14/14, 11:16 AM
Seen: 2770 times
Last updated: 8/12/15, 10:51 AM