Tuesday, March 29, 2016¶
Partner and bank account of a payment order¶
Working on #143. Though this is also useful for Lino Così and Lino Voga.
Eingabe ZAU oder AAW : im Bankkonto muss die primäre Kontonummer des Partners stehen. Und man darf nur die Nummern des Partners auswählen können.
Yes, the partner_changed method is defined by
FinancialVoucherItem
and by
BankAccount
.
In Lino Welfare, we want to allow PaymentOrderItems whose partner is empty. And in that case, Lino should use the project as partner. That’s why we have a method:
def get_partner(self):
return self.partner or self.project
But we cannot use this logic in bank_account_choices, so we have to reimplement it there:
@dd.chooser()
def bank_account_choices(cls, partner, project):
partner = partner or project
return rt.models.sepa.Account.objects.filter(
partner=partner).order_by('iban')
This might indicate a design flaw in the chooser API. In above case it would be more natural to define a chooser which works on an existing database object. It is disturbing that the application developer can define a choicelist only by manually specifying the required context fields. But be careful: that object-based chooser API would work only in grid editing mode, not on a detail window. And maybe after #37 we would implent a row-based grid widget (which does not send a PUT after every cell edit), and there our natural chooser would equally fail.
The Moya framework¶
On PlanetPython I stumbled over A side-by-side Comparison of Django and Moya written by the author of Moya.
Moya uses SQLAlchemy while Django uses its own ORM. (But why are the examples in XML? And I don’t agree that “no imports” is an advantage.)
Moya has a package manager. (Lino doesn’t need one because we use pip instead of reinventing the wheel)
My conclusion: Yes, Lino is different from Moya in that we believe that database structure, screen layouts and business logic should be written in Python, not in XML. Python is a powerful and well-known parser, why should we throw away a subset of its features by introducing yet another textual description language? The main reason why frameworks like Moya do this is that it enables them to have non-programmers do the database design and screen layouts. Lino is here because we believe that both database design and screen layout should rather not be delegated to people who are unable to think in Python. One missing piece in all this theory are features like user-defined views (#848).
I started to integrate these thought into the docs at Think Python.
Miscellaneous changesin Voga¶
In Lino Voga when printing an invoice, Alexa got an error message
get_build_options() takes exactly 1 argument (2
given)
. Fixed.
EnrolmentsByCourse.pupil_info now shows a very customized
information defined in lino_voga.projects.voga2.lib
.
Filtering pupils¶
I was surprised to discover that Lino Voga had no filter parameters at
all on Pupils. That was because contacts.Partner, humans.Human and
humans.Born & Co did not yet use the “new” API for defining filter
parameters. Actually that API wasn’t yet finished: we also want two
methods get_request_queryset
and
get_title_tags
on the
Model
.
Puah! And then it took me about 3 hours to get the actual test case pass:
>>> from lino import startup
>>> startup('lino_voga.projects.docs.settings.doctests')
>>> from lino.api.doctest import *
>>> print(rt.models.courses.Pupils.params_layout.main)
aged_from aged_to gender
There are 36 pupils (21 men and 15 women) in our database:
>>> json_fields = 'count rows title success no_data_text param_values'
>>> kwargs = dict(fmt='json', limit=10, start=0)
>>> demo_get('robin', 'api/courses/Pupils', json_fields, 36, **kwargs)
>>> kwargs.update(pv=['', '', 'M'])
>>> demo_get('robin', 'api/courses/Pupils', json_fields, 21, **kwargs)
>>> kwargs.update(pv=['', '', 'F'])
>>> demo_get('robin', 'api/courses/Pupils', json_fields, 15, **kwargs)
It took so long because of a stupid bug in the Actor.get_queryset method which is rather a mousetrap, one day I should check whether it still makes sense and whether we can change this part of the API…