Thursday, July 27, 2017

Today I redefined the meanings of entry_date and voucher_date of lino_xl.lib.ledger.Voucher. Because they were a bit unclear and messy. What counts is the entry_date (i.e. the date of the ledger entry, IOW where this voucher should appear in the ledger). The voucher_date is actually used only for information and only in public administrations where they want that information for some reason I don’t recall right now.

Attention, this will require a data migration for production sites with existing data (e.g. Die Eiche) where both entry_date and voucher_date should be set to voucher_date (and existing values in entry_date are worthless and will be lost).

Lino Tera continued

Here is the new list of tasks for me after my meeting with Lydia yesterday (#1982).


  • Eingabedatum (wann ich es eingegeben habe) interessiert uns nicht. Pro Beleg haben wir jetzt das Buchungsdatum (entry_date), und ein eventuelles Belegdatum (voucher_date) ist höchstens noch zur Info irgendwo im Hintergrund.
  • MWSt-Erklärung hat zwei Felder “Buchungsperiode”. Labels spezifizieren.


  • We managed to reproduce #1975 (Daten im oberen Teil des Dokuments verschwinden wenn man registriert): Neue EKR erstellen. An Rumma. Im Betreff “test” eingeben. Nicht speichern, sondern sofort unten ein Konto 610211 eingeben, Betrag inkl. 123€, und dann Registrieren klicken. NB passiert nur, wenn es eine soeben erstellte EKR ist.
  • Buchungsperiode soll laut BELEGdatum sein. Aber man muss Buchungsperiode manuell ändern können. Falls BP abgeschlossen ist, sollte Lino sie nicht mehr vorschlagen. Data checker mit fix.
  • Kontenbewegungen nach Buchungsperiode filtern können.
  • Alle EKR sind im Q4 verbucht, das ist falsch.
  • Testen, ob MWSt-Erklärung für Q1 jetzt funktioniert,
  • Analytic Accounts Balance 2017 ist leer, obschon EKR existieren.
  • Journal “Zahlungsaufträge” fehlt noch.
  • Man kann Einschreibungen nicht bestätigen.
  • Termin Familiengruppe machen und Anwesenheiten erfassen können.


  • Layout EKR noch zu optimieren. Zahlungsbedingung kann raus.
  • Wenn ich Belegdatum ändere, sollte er Zahlungziel anpassen. (unwichtig, weil es im insert_layout machbar ist)
  • Was passiert wenn jemand umzieht? Momentan ist es so, dass man auch beim Konsultieren einer alten Aktivität die neue Adresse sieht. Die alte Adresse könnte man sich bei Bedarf als Bemerkung reinschreiben.
  • Und dann kommt natürlich die Frage, wie das alles fakturiert werden soll.

TypeError: __init__() takes exactly 4 arguments (2 given)

Intermetzzo. I received an error message from a production site where a bug caused an exception when trying to render as JSON a date with a year below 1900:

>>> import datetime
>>> from lino import startup
>>> startup('lino_book.projects.min1.settings.demo')
>>> from lino.utils.jsgen import py2js
>>> print(py2js(, 7, 27)))
>>> print(py2js(, 7, 27)))  
Traceback (most recent call last):
TypeError: __init__() takes exactly 4 arguments (2 given)

After the fix it works:

>>> print(py2js(, 7, 27)))

They didn’t yet complain, but I had a feeling that I should dive into this. I wrote the following run script on their production server:

from import *

And indeed, the output was:

[Contract #340 ('ISIP#340 (Yamina XXXX)')]

And indeed, it was not possible to show that contract ISIP#340 through the web interface. I ran another script to repair it:

from import *
obj = isip.Contract.objects.filter(applies_from__year__lt=1900)[0]
obj.applies_from = obj.applies_from.replace(year=2017)

Now that the bug is fixed, it is again possible to display dates before 1900.

I didn’t deploy that fix to their production site since this is probably a rather rare case. No need to panic.

I started to write a page Utilities for generating Javascript code in the Developers Guide which tests that bug.

API change about current user type

I continued a bit on the new Utilities for generating Javascript code page because it seems to be a good place for exploring and documenting questions like “What is a table handle and why do we need it?”.

I added a new method lino.modlib.users.UserType.context() which returns a context manager so you can now write:

with UserTypes.admin.context():
    # some code

For this I moved the _for_user_profile global variable and the logic for handling it from lino.utils.jsgen to lino.modlib.users.utils.

Instead of saying:

from lino.utils import jsgen
if jsgen._for_user_profile ...

you must now say:

from lino.modlib.users.utils import get_user_profile
if get_user_profile() ...

I adapted also ExtJS 6 interface for Lino and added a test case there because this failure was not being detected.

With all this I still didn’t find a satisfying answer to the question “What is a table handle and why do we need it?” so far. Maybe this is code left behind by history which can be simplified now. Deserves more work. But for now I abandon it because customers are waiting…

Adapt the test suites

I took some more time for getting the complete test suite pass again. Which made me discover #1985. I investigated more than an hour. Something is wrong there, but I still cannot even say whether it is just a trivial problem or something fundamental. Not urgent since the Welfare accounting project is currently waiting for political decision.

I removed the disturbing #1173 debug messages in kernel and actors.