Thursday, December 26, 2019

Cannot easily see whether invoices are registered

I worked on #3430. This was less easy than I had imagined.

The basic plan is to change Voucher.__str__() so that a voucher is displayed as journal, number and year (e.g. “SLS 1/2019”) only when it is registered, and that otherwise the internal primary key is displayed (“#12345”).

This change wasn’t that easy because the match becomes valid only when the voucher state is set. Which means that we cannot call get_default_match() during the process of registering when collecting the movements to generate. That’s why I removed get_default_match and say now that str(voucher) or str(voucheritem) returns the match, and when collecting the movements, I set their match to the object itself, not a string. Django will call str() on that object when it actually stores the movement. Is that hackerish? But it even fixed a problem with matches that was visible in search : Add search functionality but that nobody had noticed so far.

Miscellaneous changes en passant:

  • New plugin attribute lino_xl.lib.ledger.Plugin.registered_states.

  • The lino_xl.lib.vat.MovementsByDeclaration table now also shows the VAT class of every ledger account, making diagnostics more intuitive.

Hobbit says “RuntimeError: populate() isn’t reentrant”

I also worked on #3178.

Oops, I saw that my quick fix yesterday (Actor._get_handle) broke everything. I can’t store the handle instance only after setup because once a handle has been instantiated, subsequent calls to _get_handle() should return that instance. They occur already during setup_handle(). Which also means that this change is less probable to fix the problem.

TIL : Having more than 20 years of experience as a developer doesn’t exempt you from having to run the test suite before publishing a change, even if the change seems trivial.

In the afternoon the original problem was again occurring on hobbit. I looked at the error logs and saw:

[Thu Dec 26 10:38:03.007191 2019] [wsgi:error] [pid 31665] [remote
197.2.66.96:53356] mod_wsgi (pid=31665): Target WSGI script
'/usr/local/python/.../apache/wsgi.py' does not contain WSGI
application 'application'.

The wsgi.py scripts for hobbit and jane were still using the old approach using lino_local.py. They said:

import sys ; sys.path.append('/usr/local/python')
from lino_local import setup_wsgi ; setup_wsgi(globals())

And lino_local.py contained:

def setup_wsgi(globals_dict,*args,**kw):
    filename = globals_dict['__file__']
    home_dir,tail = split(dirname(abspath(filename)))
    assert tail == 'apache', "%r is not apache" % tail
    setup(home_dir, *args, **kw)
    #import django.core.handlers.wsgi
    #globals_dict.update(application=django.core.handlers.wsgi.WSGIHandler())
    from django.core.wsgi import get_wsgi_application
    try:
        application = get_wsgi_application()
        globals_dict.update(application = application)
    except RuntimeError as e:
        print(e)
        print("Wsgi application is not yet ready")

I changed them to what getlino does:

import os, sys
sys.path.insert(0, '/usr/local/python')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lino_sites.hobbit.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

I also noted that the apache subdir of hobbit was not writable for www-data.

Missing monit package in Debian Buster

In getlino I changed the debian dockerfile : FROM bullseye instead of from buster. Because I started to believe that indeed monit will never be in buster. Which raises the question of whether and how to upgrade a production site from buster to bullseye. Or should we rather use a backport?

Not sure, but the following two commands in the test suite were hanging and got reactivated after pressing ENTER twice:

. ~/lino/env/bin/activate && getlino startsite noi mynoi1 --batch --dev-repos "lino xl noi" =====
. ~/lino/env/bin/activate && getlino startsite cosi mycosi1 --batch --dev-repos "lino xl cosi" =====

Another bug in lino_xl.lib.vat

I found and fixed a bug in lino_xl.lib.vat : Lino didn’t compute correctly when you defined a DeclarationField with a condition on DeclarationField.vat_classes which mentioned only vat classes to be excluded (i.e. no VAT class without an “!”). Same for DeclarationField.vat_columns and DeclarationField.vat_regimes