:date: 2017-10-25 =========================== Wednesday, October 25, 2017 =========================== Separate "coachings" from "clients" =================================== While adapting the test suites after yesterday's changes for :ticket:`2115`, I realized that it is time to split the coachings plugin into "coachings per se" and "clients". And :ref:`avanti` uses only :mod:`clients `, not :mod:`coachings `. This fixes some less visible problems, e.g. the irritating unused menu entries for coachings in :ref:`avanti`. Database migration: The models :class:`ClientContact ` and :class:`ClientContactType `, and the choicelist :class:`ClientStates ` were moved from :mod:`lino_xl.lib.coachings` to :mod:`lino_xl.lib.clients`. After these changes I had -as expected- some work to repair the test suites for :ref:`welfare`. For example at some moment there were only 23 instead of 58 clients in :mod:`lino_welfare.projects.eupen`. This was actually because of the *default default* value of the :attr:`client_state` field (see :doc:`1009`). Login via Google+ ================= I continued on :ticket:`1275`. I reached the point where Google asks me to choose my account. I saw this nice RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to localhost:8000/complete/google-plus/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings. And later, shortly after fixing above error:: AjaxExceptionResponse HTTPError: 403 Client Error: Forbidden for url: https://www.googleapis.com/plus/v1/people/me?access_token=...&alt=json in request POST /complete/google-plus/ (data: `__ was null, maybe that's the problem? But theoretically it is being set by the general `beforerequest` handler defined in :xfile:`linoweb.js` :: Ext.Ajax.on('beforerequest', function (conn, options) { if (!(/^http:.*/.test(options.url) || /^https:.*/.test(options.url))) { if (typeof(options.headers) == "undefined") { options.headers = {'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}; } else { options.headers.extend({'X-CSRFToken': Ext.util.Cookies.get('csrftoken')}); } } }, this); To be continued...