Clients in Lino Avanti

This document describes the lino_avanti.lib.avanti plugin.

A tested document

This is a tested document. The following instructions are used for initialization:

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

Overview

A client is a person using our services.

The legacy file number

Dossiernummern:

  • wenn du "ip6" eintippst, macht er daraus "IP 6901" (wenn "IP 6900" die letzte Dossiernummer ist, die mit "IP 6" beginnt.

  • du kannst jederzeit auch im Schnellsuche-Feld "ip 6900" eintippen

  • wenn du "ip 1234" einzippst (also die Dossiernummer selber eine vierstellige Zahl angibst), dann lässt Lino diese Nummer stehen.

  • ob du "ip" oder "IP" eintippst, ist egal, Lino macht daraus immer "IP".

  • Auch das Leerzeichen kannst du beim Eintippen sparen, das setzt Lino automatisch rein.

  • wenn die Dossiernummer nicht mit "ip" beginnt, lässt Lino sie unverändert

>>> other_client = avanti.Client.objects.get(pk=116)
>>> def update_other(ref):
...     other_client.ref = ref
...     other_client.full_clean()
...     other_client.save()
>>> update_other(None) # tidy up from previous test run
>>> def test(ref):
...     obj = avanti.Client(ref=ref, name="x")
...     obj.full_clean()
...     print(obj.ref)
>>> test("ip 1")
IP 1001
>>> update_other("IP 4010")
>>> test("ip 4")
IP 4011
>>> test("ip")
IP 4011
>>> update_other(None) # tidy up for the following tests

Clients

class lino_avanti.lib.avanti.Client(lino.core.model.Model)
translator_type

Which type of translator is needed with this client.

See also TranslatorTypes

professional_state

The professional situation of this client.

See also ProfessionalStates

overview

A panel with general information about this client.

client_state

The state of this client record.

This is a pointer to ClientStates and can have the following values:

>>> rt.show('clients.ClientStates')
======= ========== ============ =============
 value   name       text         Button text
------- ---------- ------------ -------------
 05      incoming   Incoming
 07      informed   Informed
 10      newcomer   Newcomer
 15      equal      Equal
 20      coached    Registered
 25      inactive   Inactive
 30      former     Ended
 40      refused    Abandoned
======= ========== ============ =============
unemployed_since

The date when this client got unemployed and stopped to have a regular work.

seeking_since

The date when this client registered as unemployed and started to look for a new job.

work_permit_suspended_until
city

The place (village or municipality) where this client lives.

This is a pointer to a lino_xl.lib.countries.Place.

municipality

The municipality where this client lives. This is basically equal to city, except when city is a village and has a parent which is a municipality (which causes that place to be returned).

class lino_avanti.lib.avanti.ClientDetail
class lino_avanti.lib.avanti.Clients

Base class for most lists of clients.

client_state

If not empty, show only Clients whose client_state equals the specified value.

class lino_avanti.lib.avanti.AllClients(Clients)

This table is visible for Explorer who can also export it.

For privacy reasons this table shows only a very limited set of fields. For example the names are hidden. OTOH it includes the municipality virtual field.

>>> show_columns(avanti.AllClients, all=True)
... 
+-------------------+------------------------+--------------------------------------------------------------+
| Internal name     | Verbose name           | Help text                                                    |
+===================+========================+==============================================================+
| client_state      | State                  | The state of this client record.                             |
+-------------------+------------------------+--------------------------------------------------------------+
| starting_reason   | Starting reason        |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| ending_reason     | Ending reason          |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| city              | Locality               | The place (village or municipality) where this client lives. |
+-------------------+------------------------+--------------------------------------------------------------+
| municipality      | Municipality           |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| country           | Country                |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| zip_code          | Zip code               |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| nationality       | Nationality            | The nationality. This is a pointer to                        |
|                   |                        | countries.Country which should                               |
|                   |                        | contain also entries for refugee statuses.                   |
+-------------------+------------------------+--------------------------------------------------------------+
| gender            | Gender                 | The sex of this person (male or female).                     |
+-------------------+------------------------+--------------------------------------------------------------+
| birth_country     | Birth country          |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| in_belgium_since  | Lives in Belgium since | Uncomplete dates are allowed, e.g.                           |
|                   |                        | "00.00.1980" means "some day in 1980",                       |
|                   |                        | "00.07.1980" means "in July 1980"                            |
|                   |                        | or "23.07.0000" means "on a 23th of July".                   |
+-------------------+------------------------+--------------------------------------------------------------+
| needs_work_permit | Needs work permit      |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| translator_type   | Translator type        | Which type of translator is needed with this client.         |
+-------------------+------------------------+--------------------------------------------------------------+
| mother_tongues    | Mother tongues         |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| cef_level_de      | None                   |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| cef_level_fr      | None                   |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| cef_level_en      | None                   |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
| user              | Primary coach          | The author of this object.                                   |
|                   |                        | A pointer to lino.modlib.users.models.User.                  |
+-------------------+------------------------+--------------------------------------------------------------+
| event_policy      | Recurrency policy      |                                                              |
+-------------------+------------------------+--------------------------------------------------------------+
class lino_avanti.lib.avanti.MyClients(Clients)

Shows all clients having me as primary coach. Shows all client states.

>>> rt.login('robin').show('avanti.MyClients')
... 
=============================== ============ =============== ===== ================================= ========== ================ ======= ===== ====================
 Name                            State        National ID     GSM   Address                           Age        e-mail address   Phone   ID    Legacy file number
------------------------------- ------------ --------------- ----- --------------------------------- ---------- ---------------- ------- ----- --------------------
 ABDALLAH Aáish (127)            Registered   920417 001-91         Bellmerin, 4700 Eupen             24 years                            127
 ABDO Aásim (138)                Registered   831201 001-50         Gülcherstraße, 4700 Eupen         33 years                            138
 ABDULLAH Afááf (155)            Ended        760102 002-86         4730 Raeren                       41 years                            155
 ABOUD Ahláám (166)              Ended        690627 002-97         4730 Raeren                       47 years                            166
 ARENT Afánásiiá (124)           Ended        891219 002-23         Bergkapellstraße, 4700 Eupen      27 years                            124
 ASTAFUROV Agáfiiá (175)         Registered   820120 002-60         Aachen, Germany                   35 years                            175
 BARTOSZEWICZ Agáfokliiá (146)   Ended        781018 002-02         Herbesthaler Straße, 4700 Eupen   38 years                            146
 BERENDT Antoshá (165)           Ended        700602 001-93         4730 Raeren                       46 years                            165
 CONTEE Chike (131)              Registered   870822 001-58         Edelstraße, 4700 Eupen            29 years                            131
 DIOP Ashánti (142)              Registered   810214 002-32         Habsburgerweg, 4700 Eupen         36 years                            142
 JALLOH Diállo (158)             Registered   740810 001-48         4730 Raeren                       42 years                            158
=============================== ============ =============== ===== ================================= ========== ================ ======= ===== ====================
class lino_avanti.lib.avanti.ClientsByNationality(Clients)
class lino_avanti.lib.avanti.Residence(lino.core.model.Model)
class lino_avanti.lib.avanti.EndingReason(lino.core.model.Model)
>>> rt.show('avanti.EndingReasons')
==== ======================== ========================== ========================
 ID   Designation              Designation (de)           Designation (fr)
---- ------------------------ -------------------------- ------------------------
 1    Successfully ended       Erfolgreich beendet        Successfully ended
 2    Health problems          Gesundheitsprobleme        Health problems
 3    Familiar reasons         Familiäre Gründe           Familiar reasons
 4    Missing motivation       Fehlende Motivation        Missing motivation
 5    Return to home country   Rückkehr ins Geburtsland   Return to home country
 9    Other                    Sonstige                   Autre
==== ======================== ========================== ========================
class lino_avanti.lib.avanti.Category(BabelDesignated)
>>> rt.show('avanti.Categories')
==== =============================== =============================== ===============================
 ID   Designation                     Designation (de)                Designation (fr)
---- ------------------------------- ------------------------------- -------------------------------
 1    Language course                 Sprachkurs                      Language course
 2    Integration course              Integrationskurs                Integration course
 3    Language & integration course   Language & integration course   Language & integration course
 4    External course                 External course                 External course
 5    Justified interruption          Begründete Unterbrechung        Justified interruption
 6    Successfully terminated         Erfolgreich beendet             Successfully terminated
==== =============================== =============================== ===============================
class lino_avanti.lib.avanti.TranslatorTypes

List of choices for the Client.translator_type field of a client.

>>> rt.show(rt.models.avanti.TranslatorTypes, language="de")
====== ====== ==========
 Wert   name   Text
------ ------ ----------
 10            SETIS
 20            Sonstige
 30            Privat
====== ====== ==========
class lino_avanti.lib.avanti.ProfessionalStates

List of choices for the Client.professional_state field of a client.

>>> rt.show(rt.models.avanti.ProfessionalStates, language="de")
... 
====== ====== ================================
 Wert   name   Text
------ ------ --------------------------------
 100           Student
 200           Arbeitslos
 300           Eingeschrieben beim Arbeitsamt
 400           Angestellt
 500           Selbstständig
 600           Pensioniert
 700           Arbeitsunfähig
====== ====== ================================
>>> rt.show(checkdata.Checkers, language="en")
... 
================================= ========================================
 value                             text
--------------------------------- ----------------------------------------
 beid.SSINChecker                  Check for invalid SSINs
 cal.ConflictingEventsChecker      Check for conflicting calendar entries
 cal.EventGuestChecker             Entries without participants
 cal.LongEntryChecker              Too long-lasting calendar entries
 cal.ObsoleteEventTypeChecker      Obsolete generated calendar entries
 countries.PlaceChecker            Check data of geographical places.
 dupable.DupableChecker            Check for missing phonetic words
 dupable.SimilarObjectsChecker     Check for similar objects
 memo.PreviewableChecker           Check for previewables needing update
 printing.CachedPrintableChecker   Check for missing target files
 system.BleachChecker              Find unbleached html content
================================= ========================================

Language knowledges

Avanti adds an entry date to the language knowledge table of a client. There can be multiple entries per language and client. Because we want to report whether knowledge changed after attending a course.

Some example cases:

>>> client = rt.models.avanti.Client.objects.get(pk=120)
>>> rt.show('cv.LanguageKnowledgesByPerson', client, nosummary=True)
... 
========== =============== ============ ============ =========== ============= ============
 Language   Mother tongue   Spoken       Written      CEF level   Certificate   Entry date
---------- --------------- ------------ ------------ ----------- ------------- ------------
 Dutch      No              a bit        moderate     A2+         No            05/02/2017
 Dutch      No              moderate     quite well   A2          No            12/01/2016
 German     No              quite well   very well    A1+         No            12/01/2016
 French     Yes                                                   No            12/01/2016
========== =============== ============ ============ =========== ============= ============
>>> client = rt.models.avanti.Client.objects.get(pk=121)
>>> rt.show('cv.LanguageKnowledgesByPerson', client, nosummary=True)
... 
========== =============== ======== ========= =========== ============= ============
 Language   Mother tongue   Spoken   Written   CEF level   Certificate   Entry date
---------- --------------- -------- --------- ----------- ------------- ------------
 Estonian   Yes                                            No            12/01/2016
========== =============== ======== ========= =========== ============= ============
>>> client = rt.models.avanti.Client.objects.get(pk=122)
>>> rt.show('cv.LanguageKnowledgesByPerson', client, nosummary=True, language="de")
... 
============= =============== ============== ============== =============== ============ =================
 Sprache       Muttersprache   Wort           Schrift        CEF-Kategorie   Zertifikat   Erfassungsdatum
------------- --------------- -------------- -------------- --------------- ------------ -----------------
 Deutsch       Nein            gar nicht      ein bisschen   A1              Nein         05.02.17
 Deutsch       Nein            ein bisschen   mittelmäßig    A0              Nein         12.01.16
 Französisch   Ja                                                            Nein         12.01.16
============= =============== ============== ============== =============== ============ =================

The end user usually sees the summary of language knowledges , which shows the CEF level of the languages defined in lino.core.site.Site.languages, and only the most recent CEF level. For above client the CEF level for German is A1 (not A0):

>>> rt.show('cv.LanguageKnowledgesByPerson', client, language="de")
... 
en: Ohne Angabe
de: A1
fr: Ohne Angabe
Muttersprachen: Französisch

Creating a new client

>>> ses = rt.login("romain")
>>> url = '/api/avanti/MyClients/-99999?an=insert&fmt=json'
>>> test_client.force_login(ses.user)
>>> res = test_client.get(url)
>>> res.status_code
200
>>> d = AttrDict(json.loads(res.content))
>>> rmu(sorted(d.keys()))
... 
['data', 'phantom', 'title']
>>> d.phantom
True
>>> print(d.title)
Nouveau Bénéficiaire

The dialog window has 6 data fields:

>>> sorted(d.data.keys())  
['disabled_fields', 'email', 'first_name', 'gender', 'genderHidden', 'last_name']
>>> fld = avanti.Clients.parameters['observed_event']
>>> rt.show(fld.choicelist, language="en")
No data to display