diff --git a/app/scodoc/sco_portal_apogee.py b/app/scodoc/sco_portal_apogee.py
index 8c77b91cf60080b18bc9eb2de2d54863d0ff580d..435ec4e80aba8acf08b6b45244b6cac7cd61a59c 100644
--- a/app/scodoc/sco_portal_apogee.py
+++ b/app/scodoc/sco_portal_apogee.py
@@ -153,7 +153,7 @@ def get_inscrits_etape(code_etape, anneeapogee=None, ntrials=4, use_cache=True):
     ntrials: try several time the same request, useful for some bad web services
     use_cache: use (redis) cache
     """
-    log("get_inscrits_etape: code=%s anneeapogee=%s" % (code_etape, anneeapogee))
+    log(f"get_inscrits_etape: code={code_etape} anneeapogee={anneeapogee}")
     if anneeapogee is None:
         anneeapogee = str(time.localtime()[0])
     if use_cache:
diff --git a/app/scodoc/sco_synchro_etuds.py b/app/scodoc/sco_synchro_etuds.py
index 9a13a8f5c9d1b3bdd6bb8aa4c5bc4d180f5a9293..9b71bcc59ee327edbf4c437328633fc70b34f87d 100644
--- a/app/scodoc/sco_synchro_etuds.py
+++ b/app/scodoc/sco_synchro_etuds.py
@@ -87,7 +87,7 @@ def formsemestre_synchro_etuds(
     etuds: apres sélection par l'utilisateur, la liste des étudiants selectionnés
     que l'on va importer/inscrire
     """
-    log("formsemestre_synchro_etuds: formsemestre_id=%s" % formsemestre_id)
+    log(f"formsemestre_synchro_etuds: formsemestre_id={formsemestre_id}")
     sem = sco_formsemestre.get_formsemestre(formsemestre_id)
     sem["etape_apo_str"] = sco_formsemestre.formsemestre_etape_apo_str(sem)
     # Write access ?
@@ -182,35 +182,35 @@ def formsemestre_synchro_etuds(
         if not dialog_confirmed:
             # Confirmation
             if a_importer:
-                H.append("<h3>Etudiants à importer et inscrire :</h3><ol>")
+                H.append("<h3>Étudiants à importer et inscrire :</h3><ol>")
                 for key in a_importer:
-                    H.append("<li>%(fullname)s</li>" % etudsapo_ident[key])
+                    nom = f"""{etudsapo_ident[key]['nom']} {etudsapo_ident[key].get("prenom", "")}"""
+                    H.append(f"<li>{nom}</li>")
                 H.append("</ol>")
 
             if a_inscrire:
-                H.append("<h3>Etudiants à inscrire :</h3><ol>")
+                H.append("<h3>Étudiants à inscrire :</h3><ol>")
                 for key in a_inscrire:
-                    H.append("<li>%(fullname)s</li>" % etudsapo_ident[key])
+                    nom = f"""{etudsapo_ident[key]['nom']} {etudsapo_ident[key].get("prenom", "")}"""
+                    H.append(f"<li>{nom}</li>")
                 H.append("</ol>")
 
             a_inscrire_en_double = inscrits_ailleurs.intersection(a_inscrire)
             if a_inscrire_en_double:
                 H.append("<h3>dont étudiants déjà inscrits:</h3><ol>")
                 for key in a_inscrire_en_double:
-                    H.append(
-                        '<li class="inscrailleurs">%(fullname)s</li>'
-                        % etudsapo_ident[key]
-                    )
+                    nom = f"""{etudsapo_ident[key]['nom']} {etudsapo_ident[key].get("prenom", "")}"""
+                    H.append(f'<li class="inscrailleurs">{nom}</li>')
                 H.append("</ol>")
 
             if a_desinscrire:
-                H.append("<h3>Etudiants à désinscrire :</h3><ol>")
+                H.append("<h3>Étudiants à désinscrire :</h3><ol>")
                 for key in a_desinscrire:
                     etud = sco_etud.get_etud_info(filled=True, code_nip=key)[0]
                     H.append('<li class="desinscription">%(nomprenom)s</li>' % etud)
                 H.append("</ol>")
             if a_desinscrire_without_key:
-                H.append("<h3>Etudiants à désinscrire (sans code):</h3><ol>")
+                H.append("<h3>Étudiants à désinscrire (sans code):</h3><ol>")
                 for etudid in a_desinscrire_without_key:
                     etud = inscrits_without_key_all[etudid]
                     sco_etud.format_etud_ident(etud)
@@ -669,7 +669,7 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
         # here we try to remove all created students
         cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
         for etudid in created_etudids:
-            log("do_import_etuds_from_portal: deleting etudid=%s" % etudid)
+            log(f"do_import_etuds_from_portal: deleting etudid={etudid}")
             cursor.execute(
                 "delete from notes_moduleimpl_inscription where etudid=%(etudid)s",
                 {"etudid": etudid},
@@ -702,7 +702,7 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
 
     ScolarNews.add(
         typ=ScolarNews.NEWS_INSCR,
-        text="Import Apogée de %d étudiants en " % len(created_etudids),
+        text=f"Import Apogée de {len(created_etudids)} étudiants en ",
         obj=sem["formsemestre_id"],
         max_frequency=10 * 60,  # 10'
     )
@@ -716,6 +716,7 @@ def do_import_etud_admission(
     """
     annee_courante = time.localtime()[0]
     serie_bac, spe_bac = get_bac(etud)
+    # Les champs n'ont pas les mêmes noms dans Apogee et dans ScoDoc:
     args = {
         "etudid": etudid,
         "annee": get_opt_str(etud, "inscription") or annee_courante,
@@ -723,23 +724,26 @@ def do_import_etud_admission(
         "specialite": spe_bac,
         "annee_bac": get_opt_str(etud, "anneebac"),
         "codelycee": get_opt_str(etud, "lycee"),
+        "nomlycee": get_opt_str(etud, "nom_lycee"),
+        "villelycee": get_opt_str(etud, "ville_lycee"),
+        "codepostallycee": get_opt_str(etud, "codepostal_lycee"),
         "boursier": get_opt_str(etud, "bourse"),
     }
     # log("do_import_etud_admission: etud=%s" % pprint.pformat(etud))
-    al = sco_etud.admission_list(cnx, args={"etudid": etudid})
-    if not al:
+    adm_list = sco_etud.admission_list(cnx, args={"etudid": etudid})
+    if not adm_list:
         sco_etud.admission_create(cnx, args)  # -> adm_id
     else:
         # existing data: merge
-        e = al[0]
+        adm_info = adm_list[0]
         if get_opt_str(etud, "inscription"):
-            e["annee"] = args["annee"]
+            adm_info["annee"] = args["annee"]
         keys = list(args.keys())
         for k in keys:
             if not args[k]:
                 del args[k]
-        e.update(args)
-        sco_etud.admission_edit(cnx, e)
+        adm_info.update(args)
+        sco_etud.admission_edit(cnx, adm_info)
     # Traite cas particulier de la date de naissance pour anciens
     # etudiants IUTV
     if import_naissance and "naissance" in etud:
diff --git a/sco_version.py b/sco_version.py
index 43de22c015013a313bba87f49f46d5464844a71a..fd6f02b186b0b77f90a948bc2b2c577af55a406d 100644
--- a/sco_version.py
+++ b/sco_version.py
@@ -1,7 +1,7 @@
 # -*- mode: python -*-
 # -*- coding: utf-8 -*-
 
-SCOVERSION = "9.3.27"
+SCOVERSION = "9.3.28"
 
 SCONAME = "ScoDoc"
 
diff --git a/tools/fakeportal/etud_template.xml b/tools/fakeportal/etud_template.xml
index 6b2f205109f4acb3bd7e46e6ab32d8500beb21dc..c6243be77b63dc5f5e976e2169280eb6f82fbd77 100644
--- a/tools/fakeportal/etud_template.xml
+++ b/tools/fakeportal/etud_template.xml
@@ -18,6 +18,9 @@
 	<bac>S Scientifique</bac>
 	<anneebac>2019</anneebac>
 	<lycee>07981234T</lycee>
+	<nom_lycee>nom du lycée</nom_lycee>
+	<ville_lycee>ville lycée</ville_lycee>
+	<codepostal_lycee>code postal lycée</codepostal_lycee>
 	<mention>AB</mention>
 	<bourse>N</bourse>
 	<paiementinscription>true</paiementinscription>
@@ -34,5 +37,4 @@
 	<cod_dip>{diplome}</cod_dip>
 	<cod_etp>{etape}</cod_etp>
 	<tem_rgl_sit_mil>O</tem_rgl_sit_mil>
-	<fullname>{prenom} {nom}</fullname>
 </etudiant>
diff --git a/tools/fakeportal/fakeportal.py b/tools/fakeportal/fakeportal.py
index 0f306cc868795bd643dc28c2a4bab7dbf1be5b76..7efff4d3d0dda5b10a5aea15b45c24846d1ae682 100755
--- a/tools/fakeportal/fakeportal.py
+++ b/tools/fakeportal/fakeportal.py
@@ -2,6 +2,14 @@
 
 """Simple fake HTTP serveur
     emulating "Apogee" Web service
+
+Usage:
+    /opt/scodoc/tools/fakeportal/fakeportal.py 
+
+et régler "URL du portail" sur la page de *Paramétrage* du département testé,
+typiquement: http://localhost:8678
+et "Version de l'API" à 2
+
 """
 from pathlib import Path
 from urllib.parse import parse_qs
@@ -32,6 +40,8 @@ ETUD_HEAD = """<?xml version="1.0" encoding="UTF-8"?>
 ETUD_TAIL = """</etudiants>
 """
 
+CODES_ETAPES = ("V1RT", "V2RT", "V2RT2", "")
+
 
 def make_random_etud(nip, etape=None, annee=None, template=ETUD_TEMPLATE_FULL):
     """return XML for a student"""
@@ -39,7 +49,7 @@ def make_random_etud(nip, etape=None, annee=None, template=ETUD_TEMPLATE_FULL):
     gender = random.choice(("M", "F"))
     nom, prenom = nomprenom(gender)
     if not etape:
-        etape = random.choice(("V1RT", "V2RT", "V2RT2", ""))
+        etape = random.choice(CODES_ETAPES)
     if not annee:
         annee = time.strftime("%Y")  # current year
     diplome = "VDRT"
@@ -54,7 +64,6 @@ def make_random_etud(nip, etape=None, annee=None, template=ETUD_TEMPLATE_FULL):
         ville_naissance=random.choice(("Paris", "Berlin", "Londres", "")),
         code_dep_naissance=random.choice(("75", "99", "89")),
         libelle_dep_naissance="nom département",
-        # nomlycee=
     )
     return data
 
@@ -155,6 +164,10 @@ def signal_handler(sig, frame):
 signal.signal(signal.SIGINT, signal_handler)
 
 if __name__ == "__main__":
+    # Help message
+    print(f"Les étapes (codes Apogée) sont: {CODES_ETAPES}")
+    print(f"Définir l'URL du portail comme: http://localhost:{PORT}")
+    print("""et "Version de l'API" à 2""")
     # Start the server
     print(f"Server listening on port {PORT}...")
     my_server = socketserver.TCPServer(("", PORT), MyHttpRequestHandler)