20140305 (Wednesday, 05 March 2014)

Started to fine-tune the Client Addresses management.


  • an action to create a ClientAddress from the data stored on Client. Used at least once when migrating data, and when loading demo fixtures. Is it also useful in other situations?

A first real-world usage case for hidden_apps

A first real-world usage case for hidden_apps: the Lino Welfare in Châtelet does not need the debts and courses modules.

So I hide them in lino_welfare.settings.fr:

hidden_apps = 'debts courses'

Of course this leads to a number of minor problems, because until now nobody ever has thought about not having these modules.

For example now I got the following traceback at startup:

Exception: Unexpected name 'courses' (UserGroups are: ['office',
'reception', u'coaching', 'accounts', u'integ', 'newcomers',

Yes, Lino is right: when we have another set of usergroups, we must of course also rewrite the list of user profiles, i.e. write an individual setup_choicelists for lino_welfare.settings.fr.

Another problem occured in lino_welfare.fixtures.demo. Had to move the demo fixture for lino_welfare.modlib.courses to their own module. Normal.

Another problem is:

KeyError: u'Problem installing fixture \'/home/luc/hgwork/welfare/lino_welfare/fixtures/demo.py\': u"Unknown element u\'courses.CourseRequestsByPerson\' referred in layout <ClientDetail on pcsw.Clients>."'

The problem comes because the “Languages” tab of the ClientDetail is as follows:

languages = dd.Panel("""
""", label=_("Languages"))

In that case we want the element to simply disappear, similar as if the user had no view permission. That’s a little change in lino.core.layouts.create_layout_element().

Another problem was more subtle. I had to move pcsw.DebtsClients to debts.Clients because it had (of course) a permission requirement on a user_group “debts” which is not known when the “debts” app is hidden. This caused an AttributeError in lino.core.perms.make_view_permission_handler(). Replaced the AttributeError by a more verbose Exception which names the guilty actor, otherwise it is difficult to locate the error.

Yet another problem was the permission requirements for LanguageKnowledges. This table is defined in the cv app, and until now it required the courses usergroup:

class LanguageKnowledges(dd.Table):
    model = LanguageKnowledge
    required = dd.required(
        user_groups='courses', user_level='manager')

Both social agents and integration agents want to see this table. Also in Châtelet. Where a usergroup courses does not exist. Solution: replace courses by coaching. An alternative would be to create a new group cv. But for the moment there is no need for such detailedness. I believe that in this case it is good to be minimalistic (to no try to guess ahead some need which has not yet been asked).

Next problem:

Could not define system.SiteConfigs.DetailFormPanel for <class
'lino.modlib.system.models.SiteConfigs'>: u"Unknown element
u'master_budget' referred in layout <FormLayout on

Yes, this field is being injected by the debts module and thus it doesn’t exist now. But the SiteConfigs.DetailFormPanel has it specified in its layout. As earlier, I’d say that we want the element to simply disappear. But here it is more difficult for lino.core.layouts.create_layout_element() to test this. In fact, my earlier solution was just a hack which won’t work every time: it works only when the element is specified using a dotted name.

Similar problem for the is_courseprovider (injected to contacts.Company by lino_welfare.modlib.courses).

Solved both problems using lino.core.layouts.Panel.replace(). To solve this more elegantly, we would need “field-level permissions”.