==================================
20130321 (Thursday, 21 March 2013)
==================================

Storing Site configuration in a singleton database row
------------------------------------------------------

:class:`lino.ui.Site` has a `site_config` property which
returns the *one and only* 
:class:`SiteConfig <lino.ui.models.SiteConfig>` 
instance. One might call it a "singleton database row".

The concept includes some challenges, has caused me quite some 
work in the past and todays whole workday.

Some fragments on how it is implemented.

The `site_config` property on the :class:`lino.ui.Site` 
class uses a cached object instance::

    @property
    def site_config(self):
        if self._site_config is None:
            SiteConfig = self.modules.ui.SiteConfig
            try:
                self._site_config = SiteConfig.objects.get(pk=1)
            except SiteConfig.DoesNotExist:
                kw = dict(pk=1)
                kw.update(self.site_config_defaults)
                self._site_config = SiteConfig(**kw)
        return self._site_config

One complication is that we must clear this cached instance at 
certain moments::

    def clear_site_config(self):
        self._site_config = None

But when to call this method?
There is unfortunately no single clear signal to which to connect it.
That's why we connect it to all the following signals::

    def my_callback(sender,**kw):
        settings.SITE.clear_site_config()
    from django.db.backends.signals import connection_created
    connection_created.connect(my_callback)
    testcase_setup.connect(my_callback)
    models.signals.post_syncdb.connect(my_callback)
    models.signals.post_save.connect(my_callback,sender=SiteConfig) # NOTE 
    
The testcase_setup signal is my own custom signal, 
emitted only by djangoutils.utils.test.TestCase.

NOTE : I didn't manage to get that last line working. 
When specifying a `sender`, the signal seems to just not get sent.
Worked around this by overriding SiteConfig.save() to call directly clear_site_config()

Another complication is that we must write a
`custom manager <https://docs.djangoproject.com/en/5.2/topics/db/managers/#custom-managers>`_:

Can't we avoid all these complications by not caching 
the object at all?
One of the things I tried yesterday was
something like this::

    @property
    def site_config(self):
        SiteConfig = self.modules.ui.SiteConfig
        try:
            return SiteConfig.objects.get(pk=1)
        except SiteConfig.DoesNotExist:
            kw = dict(pk=1)
            kw.update(self.site_config_defaults)
            sc = SiteConfig(**kw)
            sc.full_clean()
            sc.save()
            return sc

But this caused code as the following 
(in :mod:`lino_welfare.pcsw.modlib.tests.pcsw_tests`) 
to produce unexpected results::

  def test00(self):
      sc = settings.SITE.site_config
      sc.signer1 = Person(first_name="Ernst",last_name="Keutgen") ; sc.signer1.save()
      sc.signer2 = Person(first_name="Johann",last_name="Ossemann") ; sc.signer2.save()
      sc.full_clean() ; sc.save()

Because saving a Person itself causes an update of the SiteConfig record 
(to increment the next_partner_id

BTW I also stumbled over Django ticket 
:djangoticket:`10200` (loaddata command does not raise CommandError on errors).

These problems seem now solved.
Just the pcsw_demo_tests and pcsw_sql_tests are still deactivated,
waiting for adaptation. That doesn't stop me from checking it in.

TODO
----

Yes, there is much to do:

- Write unit tests for the new features in :mod:`lino_welfare.modlib.jobs`

- rename users.UserGroups to auth.PermissionGroups

- implement new user requests for `welfare.debts`.

- start translating the `welfare.userman`, 
  using http://sphinx-doc.org/intl.html
  
- Use python-babel for generating the message files. 
  http://jinja.pocoo.org/docs/integration/#babel-integration  
  
- Explore and use python-babel's 
  interface to the CLDR (Common Locale Data Repository).
  See
  http://babel.edgewall.org/wiki/Documentation/intro.html#locale-data
  
- Find a solution to handle the current situation: version numbers 
  are already incremented to the new ones, release notes are started, 
  but the thing isn't yet officially released.
  I don't want to edit four files and rebuild the whole html docs .
  to change this sentence
  
  
User requests for `welfare.debts`
--------------------------------------

- The Reference field of an Account wasn't visible
- add_site_attribute()