Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

roger : A customized Lino Voga site

A Lino Voga site with a few local customizations.

Used in Lino Voga specs.

The lino_book.projects.roger demo project illustrates some local customizations.

Lines starting with >>> in this document are code snippets that get tested as part of our development workflow.

>>> from lino import startup
>>> startup('lino_book.projects.roger.settings.doctests')
>>> from lino.api.doctest import *

A customized management of membership fees

The lino_voga.lib.roger.courses plugin demonstrates the following rules for handling memberships:

  • Membership costs 15€ per year.

  • Members get a discount on enrolments to courses.

  • Customers can freely decide whether they want to be members or not.

  • They become member by paying the membership fee.

To handle these rules, we have an additional field member_until on each pupil.

There is a custom data checker lino_voga.lib.roger.courses.MemberChecker

>>> dd.demo_date()
datetime.date(2015, 5, 22)
>>> rt.show(courses.Pupils)
... 
======================================== ================================= ================== ============ ===== ===== ======== ==============
 Name                                     Address                           Participant type   Section      LFV   CKK   Raviva   Mitglied bis
---------------------------------------- --------------------------------- ------------------ ------------ ----- ----- -------- --------------
 Hans Altenberg (MEL)                     Aachener Straße, 4700 Eupen       Member                          Yes   No    No       31/12/2015
 Annette Arens (MEC)                      Alter Malmedyer Weg, 4700 Eupen   Helper                          No    Yes   No       31/12/2015
 Laurent Bastiaensen (ME)                 Am Berg, 4700 Eupen               Non-member                      No    No    No       31/12/2015
 Bernd Brecht (ME)                        Aachen, Germany                   Member                          No    No    No       31/12/2015
 Ulrike Charlier (ME)                     Auenweg, 4700 Eupen               Helper                          No    No    No       31/12/2015
 Dorothée Demeulenaere (ME)               Auf'm Rain, 4700 Eupen            Non-member                      No    No    No       31/12/2016
 ...
 Hedi Radermacher (ME)                    4730 Raeren                       Non-member                      No    No    No       31/12/2015
 Jean Radermacher (ME)                    4730 Raeren                       Member                          No    No    No       31/12/2015
 Marie-Louise Vandenmeulenbos (MEC)       Amsterdam, Netherlands            Helper                          No    Yes   No       31/12/2015
 Didier di Rupo (MS)                      4730 Raeren                       Non-member         Herresbach   No    No    No
 Erna Ärgerlich (ME)                      4730 Raeren                       Member                          No    No    No       31/12/2015
 Otto Östges (MCS)                        4730 Raeren                       Helper             Eynatten     No    Yes   No
======================================== ================================= ================== ============ ===== ===== ======== ==============
>>> print(dd.plugins.accounting.suppress_movements_until)
None
>>> rt.show(checkdata.MessagesByChecker, 'courses.MemberChecker')
============= ============================================ ==========================================
 Responsible   Database object                              Message text
------------- -------------------------------------------- ------------------------------------------
 Robin Rood    `Karl Kaivers (ME) <…>`__                    Member until 2015-12-31, but no payment.
 Robin Rood    `Laura Laschet (ME) <…>`__                   Member until 2015-12-31, but no payment.
 Robin Rood    `Josefine Leffin (MEL) <…>`__                Member until 2015-12-31, but no payment.
 Robin Rood    `Marie-Louise Meier (ME) <…>`__              Member until 2015-12-31, but no payment.
 Robin Rood    `Alfons Radermacher (ME) <…>`__              Member until 2015-12-31, but no payment.
 Robin Rood    `Christian Radermacher (MEL) <…>`__          Member until 2015-12-31, but no payment.
 Robin Rood    `Edgard Radermacher (ME) <…>`__              Member until 2015-12-31, but no payment.
 Robin Rood    `Guido Radermacher (ME) <…>`__               Member until 2015-12-31, but no payment.
 Robin Rood    `Hedi Radermacher (ME) <…>`__                Member until 2015-12-31, but no payment.
 Robin Rood    `Jean Radermacher (ME) <…>`__                Member until 2015-12-31, but no payment.
 Robin Rood    `Erna Ärgerlich (ME) <…>`__                  Member until 2015-12-31, but no payment.
 Robin Rood    `Jean Dupont (ME) <…>`__                     Member until 2015-12-31, but no payment.
 Robin Rood    `Marie-Louise Vandenmeulenbos (MEC) <…>`__   Member until 2015-12-31, but no payment.
 Robin Rood    `Bernd Brecht (ME) <…>`__                    Member until 2015-12-31, but no payment.
 Robin Rood    `Jérôme Jeanémart (ME) <…>`__                Member until 2015-12-31, but no payment.
============= ============================================ ==========================================
>>> acc = rt.models.accounting.CommonAccounts.membership_fees.get_object()
>>> print(acc)
(7310) Membership fees
>>> rt.show(accounting.MovementsByAccount, acc)
============ ==================== =========================================== ======= ============ =============
 Value date   Voucher              Description                                 Debit   Credit       Match
------------ -------------------- ------------------------------------------- ------- ------------ -------------
 22/12/2015   `CSH 5/2015 <…>`__   `Faymonville Luc <…>`__                             15,00        **CSH 5:1**
 22/12/2015   `CSH 5/2015 <…>`__   `Groteclaes Gregory <…>`__                          15,00        **CSH 5:2**
 22/12/2015   `CSH 5/2015 <…>`__   `Hilgers Hildegard <…>`__                           15,00        **CSH 5:3**
 22/12/2015   `CSH 5/2015 <…>`__   `Jacobs Jacqueline <…>`__                           15,00        **CSH 5:4**
 22/12/2015   `CSH 5/2015 <…>`__   `Jonas Josef <…>`__                                 15,00        **CSH 5:5**
 22/11/2015   `CSH 4/2015 <…>`__   `Dobbelstein-Demeulenaere Dorothée <…>`__           15,00        **CSH 4:1**
 22/11/2015   `CSH 4/2015 <…>`__   `Emonts Daniel <…>`__                               15,00        **CSH 4:3**
 22/11/2015   `CSH 4/2015 <…>`__   `Engels Edgar <…>`__                                15,00        **CSH 4:4**
 22/11/2015   `CSH 4/2015 <…>`__   `Evers Eberhart <…>`__                              15,00        **CSH 4:2**
 22/10/2015   `CSH 3/2015 <…>`__   `Demeulenaere Dorothée <…>`__                       15,00        **CSH 3:2**
 22/10/2015   `CSH 3/2015 <…>`__   `Dericum Daniel <…>`__                              15,00        **CSH 3:1**
 22/02/2015   `CSH 2/2015 <…>`__   `Charlier Ulrike <…>`__                             15,00        **CSH 2:1**
 22/01/2015   `CSH 1/2015 <…>`__   `Altenberg Hans <…>`__                              15,00        **CSH 1:2**
 22/01/2015   `CSH 1/2015 <…>`__   `Arens Annette <…>`__                               15,00        **CSH 1:1**
 22/01/2015   `CSH 1/2015 <…>`__   `Bastiaensen Laurent <…>`__                         15,00        **CSH 1:3**
                                   **Balance -225.00 (15 movements)**                  **225,00**
============ ==================== =========================================== ======= ============ =============

Django and the VatVoucher model mixin

This section is no longer needed since 20230829. It helped us to discover that when you call contenttypes.ContentType.objects.get_for_model() with an abstract Model class, Django creates a contenttype database record. We then optimized lino_react.react.Renderer.actor2json() to not fall into that pit anymore.

The code snippets in this section are not actively tested, but you may remove the #doctest: +SKIP and play.

The contenttypes framework seems to sometimes create an entry for the VatVoucher model mixin although this is an abstract model.

>>> from django.apps import apps
>>> cts = set([ct.model_class() for ct in contenttypes.ContentType.objects.all()])
>>> for m in apps.get_models():
...     if m in cts:
...         cts.remove(m)
>>> cts  
{None}
>>> for ct in contenttypes.ContentType.objects.all():  
...   if ct.model_class() is None:
...     print(ct)
vatvoucher

This is caused by the following method:

>>> get_for_model = contenttypes.ContentType.objects.get_for_model

When passing a non-existed Model class (that is abstract) it creates a contenttype database record. For example see how the contenttype count increasing when looking up abstract models:

>>> contenttypes.ContentType.objects.count()  
92
>>> users.UserAuthored._meta.abstract, contenttypes.ContentType.objects.filter(model="userauthored").count()  
(True, 0)

Now see when we look it up using get_for_model method:

>>> get_for_model(users.UserAuthored)  
<ContentType: userauthored>
>>> contenttypes.ContentType.objects.count()  
93

And there’s one more contenttype object.

Database structure

>>> from lino.utils.diag import analyzer
>>> analyzer.show_db_overview()
... 
48 plugins: lino, about, jinja, react, printing, system, help, users, office, xl, countries, contacts, phones, lists, beid, contenttypes, gfks, linod, checkdata, cal, courses, products, rooms, memo, excerpts, weasyprint, uploads, accounting, bevats, vat, trading, summaries, storage, invoicing, finan, sepa, notes, outbox, voga, export_excel, calview, wkhtmltopdf, appypod, changes, bootstrap3, publisher, staticfiles, sessions.
95 models:
============================= ============================== ========= =======
 Name                          Default table                  #fields   #rows
----------------------------- ------------------------------ --------- -------
 accounting.Account            accounting.Accounts            18        21
 accounting.AccountingPeriod   accounting.AccountingPeriods   7         17
 accounting.FiscalYear         accounting.FiscalYears         5         7
 accounting.Journal            accounting.Journals            27        10
 accounting.LedgerInfo         accounting.LedgerInfoTable     2         0
 accounting.MatchRule          accounting.MatchRules          3         33
 accounting.Movement           accounting.Movements           11        1453
 accounting.PaymentTerm        accounting.PaymentTerms        11        8
 accounting.Voucher            accounting.AllVouchers         8         423
 bevats.Declaration            bevats.Declarations            28        15
 cal.Calendar                  cal.Calendars                  6         8
 cal.EntryRepeater             cal.EntryRepeaterTable         17        0
 cal.Event                     cal.Events                     25        1171
 cal.EventPolicy               cal.EventPolicies              20        6
 cal.EventType                 cal.EventTypes                 24        10
 cal.Guest                     cal.Guests                     6         0
 cal.GuestRole                 cal.GuestRoles                 5         3
 cal.RecurrentEvent            cal.RecurrentEvents            22        16
 cal.RemoteCalendar            cal.RemoteCalendars            7         0
 cal.Room                      cal.Rooms                      11        7
 cal.Subscription              cal.Subscriptions              4         35
 cal.Task                      cal.Tasks                      16        0
 calview.DailyPlannerRow       calview.DailyPlannerRows       7         2
 changes.Change                changes.Changes                10        0
 checkdata.Message             checkdata.Messages             6         23
 contacts.Company              contacts.Companies             26        31
 contacts.CompanyType          contacts.CompanyTypes          7         16
 contacts.Partner              contacts.Partners              24        103
 contacts.Person               contacts.Persons               42        72
 contacts.Role                 contacts.Roles                 4         3
 contacts.RoleType             contacts.RoleTypes             5         5
 contenttypes.ContentType      gfks.ContentTypes              3         95
 countries.Country             countries.Countries            6         10
 countries.Place               countries.Places               9         80
 courses.Course                courses.Activities             34        26
 courses.CourseType            courses.CourseTypes            5         0
 courses.Enrolment             courses.Enrolments             17        95
 courses.Line                  courses.Lines                  25        10
 courses.Pupil                 courses.Pupils                 51        35
 courses.PupilType             courses.PupilTypes             5         3
 courses.Slot                  courses.Slots                  5         0
 courses.Teacher               courses.Teachers               44        9
 courses.TeacherType           courses.TeacherTypes           5         4
 courses.Topic                 courses.Topics                 4         5
 excerpts.Excerpt              excerpts.Excerpts              11        ...
 excerpts.ExcerptType          excerpts.ExcerptTypes          17        15
 finan.BankStatement           finan.BankStatements           16        21
 finan.BankStatementItem       finan.BankStatementItemTable   9         368
 finan.JournalEntry            finan.FinancialVouchers        14        0
 finan.JournalEntryItem        finan.JournalEntryItemTable    9         0
 finan.PaymentOrder            finan.PaymentOrders            15        16
 finan.PaymentOrderItem        finan.PaymentOrderItemTable    9         127
 invoicing.FollowUpRule        invoicing.FollowUpRules        5         4
 invoicing.Item                invoicing.Items                10        16
 invoicing.Plan                invoicing.Plans                8         1
 invoicing.SalesRule           invoicing.SalesRules           3         4
 invoicing.Tariff              invoicing.Tariffs              8         0
 invoicing.Task                invoicing.Tasks                28        1
 linod.SystemTask              linod.SystemTasks              24        5
 lists.List                    lists.Lists                    7         8
 lists.ListType                lists.ListTypes                4         3
 lists.Member                  lists.Members                  5         103
 memo.Mention                  memo.Mentions                  5         15
 notes.EventType               notes.EventTypes               8         1
 notes.Note                    notes.Notes                    16        100
 notes.NoteType                notes.NoteTypes                11        3
 outbox.Attachment             outbox.Attachments             4         0
 outbox.Mail                   outbox.Mails                   8         63
 outbox.Recipient              outbox.Recipients              6         63
 phones.ContactDetail          phones.ContactDetails          8         79
 products.Category             products.Categories            15        5
 products.PriceRule            products.PriceRules            4         0
 products.Product              products.Products              21        12
 publisher.Page                publisher.Pages                15        72
 rooms.Booking                 rooms.Bookings                 24        3
 sepa.Account                  sepa.Accounts                  6         25
 sessions.Session              users.Sessions                 3         ...
 storage.Component             storage.Components             4         3
 storage.DeliveryItem          storage.DeliveryItems          8         0
 storage.DeliveryNote          storage.DeliveryNotes          14        0
 storage.Filler                storage.Fillers                6         19
 storage.Movement              storage.Movements              10        264
 storage.Provision             storage.Provisions             5         0
 storage.TransferRule          storage.TransferRules          5         0
 system.SiteConfig             system.SiteConfigs             12        1
 trading.InvoiceItem           trading.InvoiceItems           15        582
 trading.PaperType             trading.PaperTypes             5         2
 trading.VatProductInvoice     trading.Invoices               27        252
 uploads.Upload                uploads.Uploads                12        7
 uploads.UploadType            uploads.UploadTypes            8         1
 uploads.Volume                uploads.Volumes                5         0
 users.Authority               users.Authorities              3         0
 users.User                    users.AllUsers                 22        6
 vat.InvoiceItem               vat.InvoiceItemTable           9         187
 vat.VatAccountInvoice         vat.Invoices                   20        119
============================= ============================== ========= =======

Foreign Keys and their on_delete setting

Here is a list of foreign keys in Lino Voga and their on_delete behaviour. See also Customize delete behaviour.

>>> from lino.utils.diag import analyzer
>>> print(analyzer.show_foreign_keys())
... 
- accounting.Account :
  - PROTECT : accounting.Journal.account, accounting.MatchRule.account, accounting.Movement.account, finan.BankStatement.item_account, finan.BankStatementItem.account, finan.JournalEntry.item_account, finan.JournalEntryItem.account, finan.PaymentOrder.item_account, finan.PaymentOrderItem.account, vat.InvoiceItem.account
- accounting.AccountingPeriod :
  - PROTECT : accounting.Voucher.accounting_period, bevats.Declaration.end_period, bevats.Declaration.start_period
- accounting.FiscalYear :
  - PROTECT : accounting.AccountingPeriod.year
- accounting.Journal :
  - CASCADE : accounting.MatchRule.journal, invoicing.FollowUpRule.source_journal
  - PROTECT : accounting.Voucher.journal, invoicing.Task.target_journal, storage.TransferRule.journal
- accounting.PaymentTerm :
  - PROTECT : bevats.Declaration.payment_term, contacts.Partner.payment_term, courses.Course.payment_term, trading.VatProductInvoice.payment_term, vat.VatAccountInvoice.payment_term
- accounting.Voucher :
  - CASCADE : accounting.Movement.voucher, storage.Movement.voucher
  - PROTECT : bevats.Declaration.voucher_ptr, finan.BankStatement.voucher_ptr, finan.JournalEntry.voucher_ptr, finan.PaymentOrder.voucher_ptr, storage.DeliveryNote.voucher_ptr, trading.VatProductInvoice.voucher_ptr, vat.VatAccountInvoice.voucher_ptr
  - SET_NULL : invoicing.Item.invoice
- cal.Calendar :
  - CASCADE : cal.Subscription.calendar
  - PROTECT : cal.Room.calendar, system.SiteConfig.site_calendar
- cal.Event :
  - CASCADE : cal.Guest.event
  - PROTECT : cal.EntryRepeater.cal_entry
- cal.EventType :
  - PROTECT : cal.Event.event_type, cal.EventPolicy.event_type, cal.RecurrentEvent.event_type, courses.Line.event_type, products.PriceRule.selector, rooms.Booking.event_type, system.SiteConfig.default_event_type, users.User.event_type
- cal.GuestRole :
  - PROTECT : cal.Guest.role, courses.Line.guest_role, system.SiteConfig.pupil_guestrole
- cal.Room :
  - PROTECT : cal.Event.room, courses.Course.room, rooms.Booking.room
- contacts.Company :
  - PROTECT : accounting.Journal.partner, cal.Room.company, contacts.Role.company, courses.Line.company, excerpts.Excerpt.company, notes.Note.company, rooms.Booking.company, system.SiteConfig.site_company
- contacts.CompanyType :
  - PROTECT : contacts.Company.type
- contacts.Partner :
  - CASCADE : contacts.Company.partner_ptr, contacts.Person.partner_ptr, invoicing.Item.partner, invoicing.SalesRule.partner, lists.Member.partner, phones.ContactDetail.partner, sepa.Account.partner
  - PROTECT : accounting.Movement.partner, bevats.Declaration.partner, finan.BankStatementItem.partner, finan.JournalEntryItem.partner, finan.PaymentOrderItem.partner, invoicing.Plan.partner, invoicing.SalesRule.invoice_recipient, outbox.Recipient.partner, storage.DeliveryNote.partner, storage.Filler.partner, storage.Movement.partner, storage.Provision.partner, trading.VatProductInvoice.partner, users.User.partner, vat.VatAccountInvoice.partner
- contacts.Person :
  - CASCADE : courses.Pupil.person_ptr, courses.Teacher.person_ptr
  - PROTECT : cal.Guest.partner, cal.Room.contact_person, contacts.Role.person, courses.Line.contact_person, excerpts.Excerpt.contact_person, notes.Note.contact_person, rooms.Booking.contact_person
- contacts.RoleType :
  - PROTECT : cal.Room.contact_role, contacts.Role.type, courses.Line.contact_role, excerpts.Excerpt.contact_role, notes.Note.contact_role, rooms.Booking.contact_role
- contenttypes.ContentType :
  - PROTECT : cal.Event.owner_type, cal.Task.owner_type, changes.Change.master_type, changes.Change.object_type, checkdata.Message.owner_type, excerpts.Excerpt.owner_type, excerpts.ExcerptType.content_type, invoicing.FollowUpRule.invoice_generator, invoicing.Item.generator_type, memo.Mention.owner_type, memo.Mention.source_type, notes.Note.owner_type, outbox.Attachment.owner_type, outbox.Mail.owner_type, storage.DeliveryItem.invoiceable_type, trading.InvoiceItem.invoiceable_type, uploads.Upload.owner_type
- countries.Country :
  - PROTECT : contacts.Partner.country, contacts.Person.birth_country, contacts.Person.nationality, countries.Place.country
- countries.Place :
  - PROTECT : contacts.Partner.city, contacts.Partner.region, countries.Place.parent
- courses.Course :
  - PROTECT : courses.Enrolment.course, invoicing.Plan.order
- courses.CourseType :
  - PROTECT : courses.Line.course_type
- courses.Line :
  - PROTECT : courses.Course.line
- courses.Pupil :
  - PROTECT : courses.Enrolment.pupil
- courses.PupilType :
  - PROTECT : courses.Pupil.pupil_type
- courses.Slot :
  - PROTECT : courses.Course.slot
- courses.Teacher :
  - PROTECT : courses.Course.teacher
- courses.TeacherType :
  - PROTECT : courses.Teacher.teacher_type
- courses.Topic :
  - PROTECT : courses.Line.topic
- excerpts.Excerpt :
  - SET_NULL : bevats.Declaration.printed_by, courses.Enrolment.printed_by, finan.BankStatement.printed_by, finan.JournalEntry.printed_by, finan.PaymentOrder.printed_by, storage.DeliveryNote.printed_by, trading.VatProductInvoice.printed_by
- excerpts.ExcerptType :
  - PROTECT : excerpts.Excerpt.excerpt_type
- finan.BankStatement :
  - CASCADE : finan.BankStatementItem.voucher
- finan.JournalEntry :
  - CASCADE : finan.JournalEntryItem.voucher
- finan.PaymentOrder :
  - CASCADE : finan.PaymentOrderItem.voucher
- invoicing.Plan :
  - CASCADE : invoicing.Item.plan
- invoicing.Task :
  - CASCADE : invoicing.FollowUpRule.invoicing_task
  - PROTECT : invoicing.Plan.invoicing_task
- lists.List :
  - CASCADE : lists.Member.list
- lists.ListType :
  - PROTECT : lists.List.list_type
- notes.EventType :
  - PROTECT : notes.Note.event_type, system.SiteConfig.system_note_type
- notes.NoteType :
  - PROTECT : notes.Note.type
- outbox.Mail :
  - CASCADE : outbox.Attachment.mail, outbox.Recipient.mail
- products.Category :
  - PROTECT : courses.Line.fees_cat, courses.Line.options_cat, products.Category.parent, products.Product.category
- products.Product :
  - PROTECT : cal.Room.fee, courses.Course.fee, courses.Enrolment.fee, courses.Enrolment.option, courses.Line.fee, invoicing.Tariff.product, products.PriceRule.product, storage.Component.child, storage.Component.parent, storage.DeliveryItem.product, storage.Filler.provision_product, storage.Movement.product, storage.Provision.product, trading.InvoiceItem.product
- publisher.Page :
  - PROTECT : publisher.Page.parent, publisher.Page.previous_page, publisher.Page.translated_from
- sepa.Account :
  - PROTECT : accounting.Journal.sepa_account, finan.PaymentOrderItem.bank_account
- storage.DeliveryNote :
  - CASCADE : storage.DeliveryItem.voucher
- trading.PaperType :
  - PROTECT : courses.Course.paper_type, invoicing.SalesRule.paper_type, trading.VatProductInvoice.paper_type
- trading.VatProductInvoice :
  - CASCADE : trading.InvoiceItem.voucher
- uploads.UploadType :
  - PROTECT : uploads.Upload.type
- uploads.Volume :
  - PROTECT : accounting.Journal.uploads_volume, uploads.Upload.volume
- users.User :
  - CASCADE : accounting.LedgerInfo.user, cal.Subscription.user
  - PROTECT : accounting.Voucher.user, cal.Event.assigned_to, cal.Event.user, cal.RecurrentEvent.user, cal.Task.user, changes.Change.user, checkdata.Message.user, courses.Course.user, courses.Enrolment.user, excerpts.Excerpt.user, invoicing.Plan.user, invoicing.Task.user, notes.Note.user, outbox.Mail.user, rooms.Booking.user, uploads.Upload.user, users.Authority.authorized, users.Authority.user
- vat.VatAccountInvoice :
  - CASCADE : vat.InvoiceItem.voucher

Don’t read me

The snippets in this section are just for testing.

>>> pprint(settings.SITE.installed_plugins)
... 
(<lino.core.plugin.Plugin lino>,
 <lino.modlib.about.Plugin lino.modlib.about>,
 <lino.modlib.jinja.Plugin lino.modlib.jinja(needed by lino_react.react)>,
 <lino_react.react.Plugin lino_react.react(needs ['lino.modlib.jinja'])>,
 <lino.modlib.printing.Plugin lino.modlib.printing(needed by lino.modlib.system)>,
 <lino.modlib.system.Plugin lino.modlib.system(needed by lino.modlib.help, needs ['lino.modlib.printing'])>,
 <lino.modlib.help.Plugin lino.modlib.help(needs ['lino.modlib.system'])>,
 <lino.modlib.users.Plugin lino.modlib.users(needs ['lino.modlib.system'])>,
 <lino.modlib.office.Plugin lino.modlib.office(needed by lino_xl.lib.countries)>,
 <lino.core.plugin.Plugin lino_xl.lib.xl(needed by lino_xl.lib.countries)>,
 <lino_xl.lib.countries.Plugin lino_xl.lib.countries(needs ['lino.modlib.office', 'lino_xl.lib.xl'])>,
 <lino_voga.lib.contacts.Plugin lino_voga.lib.contacts(needs ['lino_xl.lib.countries', 'lino.modlib.system'])>,
 <lino_xl.lib.phones.Plugin lino_xl.lib.phones>,
 <lino_xl.lib.lists.Plugin lino_xl.lib.lists>,
 <lino_xl.lib.beid.Plugin lino_xl.lib.beid>,
 <lino.core.plugin.Plugin django.contrib.contenttypes(needed by lino.modlib.gfks)>,
 <lino.modlib.gfks.Plugin lino.modlib.gfks(needed by lino.modlib.checkdata, needs ['lino.modlib.system', 'django.contrib.contenttypes'])>,
 <lino.modlib.linod.Plugin lino.modlib.linod(needed by lino.modlib.checkdata)>,
 <lino.modlib.checkdata.Plugin lino.modlib.checkdata(needs ['lino.modlib.users', 'lino.modlib.gfks', 'lino.modlib.linod'])>,
 <lino_voga.lib.cal.Plugin lino_voga.lib.cal(needs ['lino.modlib.gfks', 'lino.modlib.printing', 'lino_xl.lib.xl', 'lino.modlib.checkdata', 'lino.modlib.linod'])>,
 <lino_voga.lib.roger.courses.Plugin lino_voga.lib.roger.courses(needs ['lino_xl.lib.cal'])>,
 <lino_voga.lib.products.Plugin lino_voga.lib.products(needs ['lino_xl.lib.xl'])>,
 <lino_voga.lib.rooms.Plugin lino_voga.lib.rooms>,
 <lino.modlib.memo.Plugin lino.modlib.memo(needed by lino_voga.lib.trading, needs ['lino.modlib.office', 'lino.modlib.gfks'])>,
 <lino_xl.lib.excerpts.Plugin lino_xl.lib.excerpts(needed by lino_xl.lib.vat, needs ['lino.modlib.gfks', 'lino.modlib.printing', 'lino.modlib.office', 'lino_xl.lib.xl'])>,
 <lino.modlib.weasyprint.Plugin lino.modlib.weasyprint(needed by lino_xl.lib.accounting)>,
 <lino.modlib.uploads.Plugin lino.modlib.uploads(needed by lino_xl.lib.accounting)>,
 <lino_xl.lib.accounting.Plugin lino_xl.lib.accounting(needed by lino_xl.lib.vat, needs ['lino.modlib.weasyprint', 'lino_xl.lib.xl', 'lino.modlib.uploads'])>,
 <lino_xl.lib.bevats.Plugin lino_xl.lib.bevats(needed by lino_xl.lib.vat, needs ['lino_xl.lib.vat'])>,
 <lino_xl.lib.vat.Plugin lino_xl.lib.vat(needed by lino_voga.lib.trading, needs ['lino.modlib.checkdata', 'lino_xl.lib.excerpts'])>,
 <lino_xl.lib.trading.Plugin lino_voga.lib.trading(needs ['lino.modlib.memo', 'lino_xl.lib.products', 'lino_xl.lib.vat'])>,
 <lino.modlib.summaries.Plugin lino.modlib.summaries(needed by lino_xl.lib.storage)>,
 <lino_xl.lib.storage.Plugin lino_xl.lib.storage(needs ['lino_xl.lib.products', 'lino.modlib.summaries'])>,
 <lino_xl.lib.invoicing.Plugin lino_xl.lib.invoicing(needs ['lino_xl.lib.trading'])>,
 <lino_xl.lib.finan.Plugin lino_xl.lib.finan(needs ['lino_xl.lib.accounting'])>,
 <lino_xl.lib.sepa.Plugin lino_xl.lib.sepa(needs ['lino_xl.lib.accounting'])>,
 <lino_xl.lib.notes.Plugin lino_xl.lib.notes(needs ['lino.modlib.memo'])>,
 <lino_xl.lib.outbox.Plugin lino_xl.lib.outbox(needs ['lino.modlib.uploads'])>,
 <lino_voga.lib.voga.Plugin lino_voga.lib.voga>,
 <lino.modlib.export_excel.Plugin lino.modlib.export_excel>,
 <lino_xl.lib.calview.Plugin lino_xl.lib.calview(needs ['lino_xl.lib.cal'])>,
 <lino.modlib.wkhtmltopdf.Plugin lino.modlib.wkhtmltopdf>,
 <lino_xl.lib.appypod.Plugin lino_xl.lib.appypod>,
 <lino.modlib.changes.Plugin lino.modlib.changes(needs ['lino.modlib.users', 'lino.modlib.gfks'])>,
 <lino.modlib.bootstrap3.Plugin lino.modlib.bootstrap3(needed by lino.modlib.publisher, needs ['lino.modlib.jinja'])>,
 <lino.modlib.publisher.Plugin lino.modlib.publisher(needs ['lino.modlib.linod', 'lino.modlib.jinja', 'lino.modlib.bootstrap3'])>,
 <lino.core.plugin.Plugin django.contrib.staticfiles>,
 <lino.core.plugin.Plugin django.contrib.sessions>)