def genCodeTableaux(config, dictAllGrandeur, textSection, listAnnees,
                    isComplet, isWikicode, verbose):
    """
        Génère le code pour les tableaux historiques sur N années
        pour une commune ou un groupement de communes donné,
        dictAllGrandeur contient toutes les donnes pour ce groupement
        pour les mot clé de de comparaison des données
        sur différentes années du modèle.
        Le texte du modèle en entrée est fourni dans la chaine textSection.
        Le type de sortie peut être du Wikicode ou du HTML.
        Le texte résultat est retourné à l'appelant.
    """
    if verbose:
        print("Entrée dans genCodeTableaux")

    nbAnneesTableau = min(
        int(config.get('GenWIkiCode', 'gen.nbLignesTableauxEuros')),
        len(listAnnees))
    textSection = textSection.replace("<ANNEE-N>",
                                      str(listAnnees[nbAnneesTableau - 1]))

    # https://fr.wikipedia.org/wiki/Aide:Couleurs
    couleurTaxeHabitation = config.get('Tableaux',
                                       'tableaux.couleurTaxeHabitation')
    couleurTaxeFonciereBati = config.get('Tableaux',
                                         'tableaux.couleurTaxeFonciereBati')
    couleurTaxeFonciereNonBati = config.get(
        'Tableaux', 'tableaux.couleurTaxeFonciereNonBati')
    couleurStrate = config.get('Tableaux', 'tableaux.couleurStrate')
    couleurTitres = config.get('Tableaux', 'tableaux.couleurTitres')
    couleurSolde = config.get('Tableaux', 'tableaux.couleurSolde')
    couleurRecettes = config.get('Tableaux', 'tableaux.couleurRecettes')
    couleurCharges = config.get('Tableaux', 'tableaux.couleurCharges')
    couleurDettesCAF = config.get('Tableaux', 'tableaux.couleurDettesCAF')
    couleurEmploisInvest = config.get('Tableaux',
                                      'tableaux.couleurEmploisInvest')
    couleurRessourcesInvest = config.get('Tableaux',
                                         'tableaux.couleurRessourcesInvest')

    listeTableaux = []
    # V1.0.5 : Précision investissement : ajout 2 lignes
    tableauPrincipal = \
        {
            'nomTableau' : "PRINCIPAL",
            'listLigne' :
                [
                    ["total des produits de fonctionnement",
                     genCodeCommon.genLien(config, ["Recettes publiques",
                                                    "Produits de fonctionnement"],
                                           isWikicode, verbose),
                     couleurRecettes],

                    ["total des charges de fonctionnement",
                     genCodeCommon.genLien(config, ["Dépenses publiques",
                                                    "Charges de fonctionnement"],
                                           isWikicode, verbose),
                     couleurCharges],
                    ["resultat comptable",
                     genCodeCommon.genLien(config, ["Résultat fiscal en France",
                                                    "Solde de la section de fonctionnement"],
                                           isWikicode, verbose),
                     couleurSolde],
                    ["total des emplois investissement",
                     genCodeCommon.genLien(config, ["Investissement",
                                                    "Emplois d'investissement"],
                                           isWikicode, verbose),
                     couleurEmploisInvest],
                    ["total des ressources d'investissement",
                     genCodeCommon.genLien(config, ["Investissement",
                                                    "Ressources d'investissement"],
                                           isWikicode, verbose),
                     couleurRessourcesInvest],
                    ["besoin ou capacité de financement de la section investissement",
                     genCodeCommon.genLien(config,
                                           ["Résultat fiscal en France",
                                            "Solde de la section d'investissement"],
                                           isWikicode, verbose),
                     couleurSolde],
                ]
        }
    listeTableaux.append(tableauPrincipal)

    tableauDetteCAF = \
        {
            'nomTableau' : "DETTE_CAF",
            'listLigne' :
                [
                    ["encours de la dette au 31 12 n",
                     genCodeCommon.genLien(config, ["Encours"], isWikicode, verbose) + \
                     " de la " + genCodeCommon.genLien(config, ["Emprunt (finance)",
                                                                "dette"],
                                                       isWikicode, verbose) + \
                     " au 31 décembre de l'année",
                     couleurDettesCAF],
                    ["capacité autofinancement caf",
                     genCodeCommon.genLien(config,
                                           ["Capacité d'autofinancement"],
                                           isWikicode,
                                           verbose) + " (CAF)",
                     couleurDettesCAF]
                ]
        }
    listeTableaux.append(tableauDetteCAF)

    tableauProduitsCharges = \
        {
            'nomTableau' : "PRODUITS_CHARGES",
            'listLigne' :
                [
                    ["dont impôts locaux",
                     "Impôts Locaux",
                     couleurRecettes],
                    ["autres impôts et taxes",
                     "autres impôts et taxes",
                     couleurRecettes],
                    ["dotation globale de fonctionnement",
                     "DGF",
                     couleurRecettes],
                    ["dont charges de personnel",
                     "Charges de personnel",
                     couleurCharges],
                    ["achats et charges externes",
                     "achats et charges externes",
                     couleurCharges],
                    ["charges financières",
                     "charges financières",
                     couleurCharges],
                    ["subventions versées",
                     "subventions versées",
                     couleurCharges]
                ]
        }
    listeTableaux.append(tableauProduitsCharges)

    tableauInvest = \
        {
            'nomTableau' : "INVEST",
            'listLigne' :
                [
                    ["dont dépenses équipement",
                     genCodeCommon.genLien(config, ["Dépenses publiques",
                                                    "Dépenses"],
                                           isWikicode, verbose) + " d'équipement",
                     couleurRecettes],
                    ["remboursement emprunts et dettes assimilées",
                     genCodeCommon.genLien(config, ["Plan de remboursement",
                                                    "Remboursements"],
                                           isWikicode, verbose) + \
                     " " + genCodeCommon.genLien(config, ["Emprunt (finance)",
                                                          "emprunts"],
                                                 isWikicode, verbose),
                     couleurRecettes],
                    ["dont emprunts bancaires et dettes assimilées",
                     "Nouvelles " + genCodeCommon.genLien(config, ["Emprunt (finance)",
                                                                   "dettes"],
                                                          isWikicode, verbose),
                     couleurCharges],
                ]
        }
    listeTableaux.append(tableauInvest)

    # Generation des tableaux et remplacement des mot-clés TABLEAU_
    for tableau in listeTableaux:
        if verbose:
            print("\n************************************")
            print("tableau :", tableau['nomTableau'])
            print("************************************")

        if isWikicode:
            tableauWiki = \
                genWikiCodeTableaux.genereTableau(tableau['nomTableau'],
                                                  listAnnees, nbAnneesTableau,
                                                  tableau['listLigne'],
                                                  dictAllGrandeur,
                                                  couleurTitres, couleurStrate,
                                                  isComplet, verbose)
        else:
            tableauWiki = \
                genHTMLCodeTableaux.genereTableau(tableau['nomTableau'],
                                                  listAnnees, nbAnneesTableau,
                                                  tableau['listLigne'],
                                                  dictAllGrandeur,
                                                  couleurTitres, couleurStrate,
                                                  isComplet, verbose)
        textSection = textSection.replace(
            "<TABLEAU_" + tableau['nomTableau'] + ">", tableauWiki)

    # Generation du tableau des taux des taxes
    nbAnneesTableau = min(
        int(config.get('GenWIkiCode', 'gen.nbLignesTableauxTaux')),
        len(listAnnees))
    textSection = textSection.replace("<ANNEE-N_TAUX>",
                                      str(listAnnees[nbAnneesTableau - 1]))
    tableauTaxes = \
        {
            'nomTableau' : "TAXES",
            'listLigne' :
                [
                    ["taux taxe habitation",
                     "taux taxe d'habitation",
                     couleurTaxeHabitation],
                    ["taux taxe foncière bâti",
                     "taux foncier bâti",
                     couleurTaxeFonciereBati],
                    ["taux taxe foncière non bâti",
                     "taux foncier non bâti",
                     couleurTaxeFonciereNonBati],
                ]
        }
    if verbose:
        print("\n************************************")
        print("tableau :", tableauTaxes['nomTableau'])
        print("************************************")

    if isWikicode:
        tableauWiki = \
                genWikiCodeTableaux.genereTableauTaux(tableauTaxes['nomTableau'],
                                                      listAnnees, nbAnneesTableau,
                                                      tableauTaxes['listLigne'],
                                                      dictAllGrandeur,
                                                      couleurTitres, couleurStrate,
                                                      isComplet, verbose)
    else:
        tableauWiki = \
                genHTMLCodeTableaux.genereTableauTaux(tableauTaxes['nomTableau'],
                                                      listAnnees, nbAnneesTableau,
                                                      tableauTaxes['listLigne'],
                                                      dictAllGrandeur,
                                                      couleurTitres, couleurStrate,
                                                      isComplet, verbose)
    textSection = textSection.replace(
        "<TABLEAU_" + tableauTaxes['nomTableau'] + ">", tableauWiki)

    if verbose:
        print("Sortie de genCodeTableaux")
    return textSection
def test_genereTableau(isWikicode, isComplet):
    """
        teste la génération des données tableau pour 1 ville : Wittenheim 68)
        Wittenheim et les années 2013 à 2015 pour comparaison avec
        http://marielaure.monde.free.fr/Finances_Locales_Web/Departement_68/Wittenheim/Wittenheim.html
    """

    config = configparser.RawConfigParser()
    config.read('FinancesLocales.properties')

    # récup données de test
    pathDatabaseMini = config.get('Test', 'genCode.pathDatabaseMini')
    pathCSVMini = config.get('Test', 'genCode.pathCSVMini')
    if os.path.isfile(pathDatabaseMini):
        print("destruction de la base :", pathDatabaseMini)
        os.remove(pathDatabaseMini)

    # Insertion dans la table ville des villes à traiter
    # Création base
    connDB = database.createDatabase(config, pathDatabaseMini, False)
    connDB.executemany(
        """
        INSERT INTO villes(codeCommune, nomMinFi, nom, nomWkpFr)
        VALUES (?, ?, ?, ?)
        """, (('068376', 'WITTENHEIM', 'Wittenheim', 'Wittenheim'), ))
    connDB.commit()

    # Création de la création de la base de test
    param = ['updateDataMinFi.py', pathDatabaseMini, pathCSVMini]
    updateDataMinFi.main(param)
    assert os.path.isfile(pathDatabaseMini)

    nomTableau = "PRINCIPAL"
    listeVilleWalheim = [
        ville
        for ville in database.getListeVilles4Departement(connDB, '068', False)
        if ville[0] == '068376'
    ]
    ville = listeVilleWalheim[0]
    # Recup des annees de données fiscales por WALHEIN
    listAnnees = database.getListeAnneesDataMinFi4Entite(
        connDB, 'V', ville[0], False)
    assert len(listAnnees) == 3
    nbAnneesTableau = min(
        int(config.get('GenWIkiCode', 'gen.nbLignesTableauxEuros')),
        len(listAnnees))

    couleurStrate = config.get('Tableaux', 'tableaux.couleurStrate')
    couleurTitres = config.get('Tableaux', 'tableaux.couleurTitres')
    couleurSolde = config.get('Tableaux', 'tableaux.couleurSolde')
    couleurRecettes = config.get('Tableaux', 'tableaux.couleurRecettes')
    couleurCharges = config.get('Tableaux', 'tableaux.couleurCharges')
    couleurDettesCAF = config.get('Tableaux', 'tableaux.couleurDettesCAF')
    couleurEmploisInvest = config.get('Tableaux',
                                      'tableaux.couleurEmploisInvest')
    couleurRessourcesInvest = config.get('Tableaux',
                                         'tableaux.couleurRessourcesInvest')

    verbose = True
    listeValeurs = [
        [
            "total des produits de fonctionnement",
            genCodeCommon.genLien(
                config, ["Recettes publiques", "Produits de fonctionnement"],
                isWikicode, verbose), couleurRecettes
        ],
        [
            "total des charges de fonctionnement",
            genCodeCommon.genLien(
                config, ["Dépenses publiques", "Charges de fonctionnement"],
                isWikicode, verbose), couleurCharges
        ],
        [
            "resultat comptable",
            genCodeCommon.genLien(config, [
                "Résultat fiscal en France",
                "Solde de la section de fonctionnement"
            ], isWikicode, verbose), couleurSolde
        ],
        [
            "total des emplois investissement",
            genCodeCommon.genLien(config,
                                  ["Investissement", "Emplois investissement"],
                                  isWikicode, verbose), couleurEmploisInvest
        ],
        [
            "total des ressources d'investissement",
            genCodeCommon.genLien(
                config, ["Investissement", "Ressources d'investissement"],
                isWikicode, verbose), couleurRessourcesInvest
        ],
        [
            "besoin ou capacité de financement de la section investissement",
            genCodeCommon.genLien(config, [
                "Résultat fiscal en France",
                "Solde de la section d'investissement"
            ], isWikicode, verbose), couleurSolde
        ],
    ]

    # Récupère toutes les valeurs pour cette ville pour les grandeurs demandées
    dictAllGrandeur = database.getAllValeursDataMinFi4Entite(
        connDB, 'V', ville[0], verbose)
    # Test de la generation tableau
    if isWikicode:
        ligne = genWikiCodeTableaux.genereTableau(
            nomTableau, listAnnees, nbAnneesTableau, listeValeurs,
            dictAllGrandeur, couleurTitres, couleurStrate, isComplet, verbose)
    else:
        ligne = genHTMLCodeTableaux.genereTableau(
            nomTableau, listAnnees, nbAnneesTableau, listeValeurs,
            dictAllGrandeur, couleurTitres, couleurStrate, isComplet, verbose)

    # Test valeur des charges en 2015
    # (cle charge) : 12659.65
    assert "12660" in ligne

    # Test valeur des charges par habitant en 2015
    # (cle fcharge) : 858.63
    assert "859" in ligne

    if isComplet:
        # Test valeur des charges de la strate en 2015
        # (cle mcharge) : 1223.21
        assert "1223" in ligne
def defTableauxPicto(config, dictAllGrandeur, listAnnees, isWikicode, verbose):
    """
    Définition du contenu des tableaux picto spécifiques aux communes
    Retourne la structure grandeursAnalyse qui contient toutes les infos
    """
    if verbose:
        print("Entrée dans defTableauxPicto")

    couleurSolde = config.get('Tableaux', 'tableaux.couleurSolde')
    couleurRecettes = config.get('Tableaux', 'tableaux.couleurRecettes')
    couleurCharges = config.get('Tableaux', 'tableaux.couleurCharges')
    couleurDettesCAF = config.get('Tableaux', 'tableaux.couleurDettesCAF')
    couleurCAF = config.get('Tableaux', 'tableaux.couleurCAF')
    couleurEmploisInvest = config.get('Tableaux',
                                      'tableaux.couleurEmploisInvest')
    couleurRessourcesInvest = config.get('Tableaux',
                                         'tableaux.couleurRessourcesInvest')

    codeCle = "total des charges de fonctionnement"
    chargesF = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    codeCle = "total des emplois investissement"
    emploisI = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    codeCle = "total des produits de fonctionnement"
    produitsF = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    codeCle = "total des ressources d'investissement"
    ressourcesI = dictAllGrandeur["Valeur totale"][codeCle][
        listAnnees[0]] * 1e3

    # Pour comparaison valeur par habitant / Strate des données de l'année la plus récente
    grandeursAnalyse = []
    dictCharges = \
    {
        'des ' + genCodeCommon.genLien(config, ["Charge (comptabilité)",
                                                "charges"],
                                       isWikicode, verbose) + ' de personnels' :
        {
            'libellePicto' : 'Charges de personnels',
            'cle' : "dont charges de personnel",
            'note' : "Les « charges de personnel » regroupent les frais " + \
                     "de [[rémunération]] des employés.",
            'noteHtml' : "7",
            'nul' : 'aucune ' + genCodeCommon.genLien(config, ["Charge (comptabilité)",
                                                               "charges"],
                                                      isWikicode, verbose) + ' de personnel'
        },
        'des ' + genCodeCommon.genLien(config, ["achats"],
                                       isWikicode, verbose) + \
        ' et charges externes' :
        {
            'libellePicto' : 'Achats et charges ext.',
            'cle' : "achats et charges externes",
            'note' : "Le poste « achats et charges externes » regroupe " + \
                     "les achats non stockés de matières et fournitures " + \
                     "([[Eau potable|eau]], [[énergie]]...), le petit matériel, " +\
                     "les achats de [[Crédit-bail|crédits-bails]], " + \
                     "les [[location]]s, [[Prime d'assurance|primes d'assurances]]...",
            'noteHtml' : "8",
            'nul' : 'aucun ' + genCodeCommon.genLien(config, ["achats",
                                                              "achat"],
                                                     isWikicode, verbose) + \
            ' ou charge externe'
        },
        'des charges financières' :
        {
            'libellePicto' : 'charges financières',
            'cle' : "charges financières",
            'note' : "Les « charges financières » correspondent à la rémunération " + \
                         "des ressources d'[[Emprunt (finance)|emprunt]].",
            'noteHtml' : "9",
            'nul' : 'aucune charge financière'
        },
        'des ' + genCodeCommon.genLien(config, ["subventions"],
                                       isWikicode, verbose) + \
        ' versées' :
        {
            'libellePicto' : 'subventions versées',
            'cle' : "subventions versées",
            'note' : "Les « subventions versées » rassemblent l'ensemble " + \
                     "des [[subvention]]s à des associations votées par le " + \
                     "[[Conseil municipal (France)|conseil municipal]].",
            'noteHtml' : "10",
            'nul' : 'aucune ' + genCodeCommon.genLien(config, ["subvention"],
                                                      isWikicode, verbose) + \
            ' versée'
        },
        'des contingents' :
        {
            'libellePicto' : 'contingents',
            'cle' : "contingents",
            'note' : "Les « contingents » représentent des participations " + \
                     "obligatoires au financement de services " + \
                     "départementaux, notamment aux [[Pompier|sapeurs-pompiers]] " + \
                     "du département.",
            'noteHtml' : "11",
            'nul' : 'aucun contingent versé'
        }
    }
    grandeursAnalyse.append([dictCharges, chargesF, "CHARGE", couleurCharges])

    dictEncoursDette = \
    {
        "l'encours de la dette" :
        {
            'libellePicto' : 'Encours de la dette',
            'cle' : 'encours de la dette au 31 12 n',
            'note' : "",
            'noteHtml' : '',
            'nul' : "pas d'encours pour la dette"
        }
    }
    grandeursAnalyse.append(
        [dictEncoursDette, 0, "ENCOURS_DETTE", couleurDettesCAF])

    dictAnnuiteDette = \
    {
        "l'annuité de la dette" :
        {
            'libellePicto' : 'annuité de la dette',
            'cle' : "annuité de la dette",
            'note' : "",
            'noteHtml' : '',
            'nul' : 'aucune annuité pour la dette'
        }
    }
    grandeursAnalyse.append(
        [dictAnnuiteDette, 0, "ANNUITE_DETTE", couleurDettesCAF])

    # Recettes
    dictRecettes = \
    {
        'des ' + genCodeCommon.genLien(config,
                                       ["Impôts locaux en France",
                                        "impôts locaux"],
                                       isWikicode, verbose) :
        {
            'libellePicto' : 'Impôts locaux',
            'cle' : "dont impôts locaux",
            'note' : "Les « [[Impôts locaux en France|impôts locaux]] » " +\
                    "désignent les [[impôt]]s prélevés par les " + \
                    "[[Collectivité territoriale|collectivités territoriales]] " + \
                    "pour alimenter leur budget. Ils regroupent " + \
                    "les [[Taxe foncière|impôts fonciers]], la [[taxe d'habitation]] " + \
                    "ou encore, pour les [[entreprise]]s, les " + \
                    "[[Cotisation foncière des entreprises|cotisations foncières]] ou " + \
                    "sur la [[valeur ajoutée]].",
            'noteHtml' : "12",
            'nul' : 'aucun ' + genCodeCommon.genLien(config,
                                                     ["Impôts locaux en France",
                                                      "impôt local"],
                                                     isWikicode, verbose)
        },
        "de la " + genCodeCommon.genLien(config,
                                         ["dotation globale de fonctionnement"],
                                         isWikicode, verbose) + " (DGF)" :
        {
            'libellePicto' : 'dotation globale de fonctionnement',
            'cle' : 'dotation globale de fonctionnement',
            'note' : "Les « [[Finances locales en France#Dotations et subventions de " + \
                     "l'État|dotations globales de fonctionnement]] » désignent, en " + \
                     "[[France]], des concours financiers de l'[[État]] au [[budget]] " + \
                     "des [[Collectivité territoriale|collectivités territoriales]].",
            'noteHtml' : "13",
            'nul' : 'aucune somme au titre de la [[dotation globale de fonctionnement]]'
        },
        'des ' + genCodeCommon.genLien(config,
                                       ["Impôts locaux en France",
                                        "autres impôts"],
                                       isWikicode, verbose) :
        {
            'libellePicto' : 'Autres impôts',
            'cle' : "autres impôts et taxes",
            'note' : "Les « autres impôts » couvrent certains impôts et [[taxe]]s " + \
                     "autres que les [[Impôts locaux en France|impôts locaux]].",
            'noteHtml' : "14",
            'nul' : 'aucun ' + genCodeCommon.genLien(config,
                                                     ["Impôts locaux en France",
                                                      "autre impôt"],
                                                     isWikicode, verbose)
        }
    }
    grandeursAnalyse.append(
        [dictRecettes, produitsF, "RECETTE", couleurRecettes])

    dictSoldeF = \
    {
        'Solde de la section de fonctionnement' :
        {
            'libellePicto' : 'Résultat comptable',
            'cle' : "resultat comptable",
            'note' : "Le « solde de la section de fonctionnement » résulte de la " + \
                     "différence entre les [[Recettes publiques|recettes]] et les " + \
                     "[[Dépenses publiques|charges]] de fonctionnement.",
            'noteHtml' : "15",
            'nul' : 'solde nul'
        }
    }
    grandeursAnalyse.append([dictSoldeF, 0, "SOLDE_FONCT", couleurSolde])

    dictEmploiInvest = \
    {
        "des dépenses d'équipement" :
        {
            'libellePicto' : "Dépenses d'équipement",
            'cle' : "dont dépenses équipement",
            'note' : "Les « dépenses d’équipement » servent à financer des projets " + \
                     "d’envergure ayant pour objet d’augmenter la valeur du " + \
                     "[[Patrimoine (finance)|patrimoine]] de la commune et d’améliorer " + \
                     "la qualité des équipements municipaux, voire d’en créer de nouveaux.",
            'noteHtml' : "16",
            'nul' : "aucune dépense d'équipement"
        },
        "des " + genCodeCommon.genLien(config, ["Plan de remboursement",
                                                "remboursements"],
                                       isWikicode, verbose) + " d'emprunts" :
        {
            'libellePicto' : "Remboursements d'emprunts",
            'cle' : "remboursement emprunts et dettes assimilées",
            'note' : "Les « [[Plan de remboursement|remboursement]]s d'emprunts » " + \
                     "représentent les sommes affectées par la commune au " + \
                     "remboursement du capital de la dette.",
            'noteHtml' : "17",
            'nul' : "aucun " + genCodeCommon.genLien(config,
                                                     ["Plan de remboursement",
                                                      "remboursement"],
                                                     isWikicode, verbose) + " d'emprunt"
        }
    }
    grandeursAnalyse.append(
        [dictEmploiInvest, emploisI, "EMPLOI_INVEST", couleurEmploisInvest])

    dictRessourcesInvest = \
    {
        genCodeCommon.genLien(config, ["Emprunt (finance)", "nouvelles dettes"],
                              isWikicode, verbose) :
        {
            'libellePicto' : 'Nouvelles dettes',
            'cle' : "dont emprunts bancaires et dettes assimilées",
            'note' : "",
            'noteHtml' : '',
            'nul' : "aucune " + genCodeCommon.genLien(config,
                                                      ["Emprunt (finance)",
                                                       "nouvelles dettes"],
                                                      isWikicode, verbose)
        },
        genCodeCommon.genLien(config, ["subventions"],
                              isWikicode, verbose) + " reçues" :
        {
            'libellePicto' : 'subventions reçues',
            'cle' : "subventions reçues",
            'note' : "",
            'noteHtml' : '',
            'nul' : "aucune " + genCodeCommon.genLien(config, ["subventions",
                                                               "subvention"],
                                                      isWikicode, verbose) + " reçue"
        },
        genCodeCommon.genLien(config, ["fonds de Compensation pour la TVA"],
                              isWikicode, verbose) :
        {
            'libellePicto' : 'fctva',
            'cle' : "fctva",
            'note' : "",
            'noteHtml' : '',
            'nul' : "aucune somme au titre des " + \
                    genCodeCommon.genLien(config, ["fonds de Compensation pour la TVA"],
                                          isWikicode, verbose)
        }
    }
    grandeursAnalyse.append([
        dictRessourcesInvest, ressourcesI, "RESSOURCES_INVEST",
        couleurRessourcesInvest
    ])

    dictCAF = \
    {
        "la " + genCodeCommon.genLien(config, ["capacité d'autofinancement"],
                                      isWikicode, verbose) + \
        " (CAF)" :
        {
            'libellePicto' : "Capacité d'autofinancement",
            'cle' : "capacité autofinancement caf",
            'note' : "",
            'noteHtml' : '',
            'nul' : "aucune " + genCodeCommon.genLien(config,
                                                      ["capacité d'autofinancement"],
                                                      isWikicode, verbose)
        }
    }
    grandeursAnalyse.append([dictCAF, 0, "CAF", couleurCAF])

    if verbose:
        print("\nSortie de defTableauxPicto")
    return grandeursAnalyse
def genTexte(config, dictAllGrandeur, infosGroupement,
             modele, textSection, ville,
             listAnnees, nomProg, isWikicode, verbose):
    """
        Expanse les tags concernant du txte simple pour une ville donnée,
        les mots clés de type textuels du modèle.
        dictAllGrandeur contient toutes les données financières pour cette ville
        infosGroupement contient les infos relatives au groupement de commune
        de rattachement,
        Le texte du modèle en entrée est fourni dans la chaine textSection.
        Le type de sortie peut être du Wikicode ou du HTML.
        Le texte résultat est retourné à l'appelant.
    """

    if verbose:
        print("Entree dans genTexte")
        print('ville=', ville)
        print("modele :", modele)
        print("isWikicode =", isWikicode)

    textSection = textSection.replace("<ANNEE>", str(listAnnees[0]))
    textSection = textSection.replace("<ANNEE-1>", str(listAnnees[1]))
    textSection = textSection.replace("<ANNEE0>", str(listAnnees[-1]))

    # Commentaire de traçabilité
    outilNom = config.get('Version', 'version.appName')
    textSection = textSection.replace("<OUTIL_NOM>", outilNom)
    textSection = textSection.replace("<NOM_PROG>", nomProg)
    version = config.get('Version', 'version.number') + " : " + \
              config.get('Version', 'version.nom')
    textSection = textSection.replace("<VERSION>", version)

    if isWikicode:
        versionPicto = config.get('Version', 'version.picto')
    else:
        versionPicto = config.get('Version', 'version.pictoHTML')
    textSection = textSection.replace("<VERSION_PICTO>", versionPicto)
    versionDate = config.get('Version', 'version.date')
    textSection = textSection.replace("<VERSION_DATE>", versionDate)
    textSection = textSection.replace("<OPTIONS>",
                                      config.get('Modele', 'modele.type'))
    textSection = textSection.replace("<NOM_MODELE>", modele)

    # Tags pour la ville
    articleVille = "de "
    if ville[1][0] in "AEIOUYH":
        articleVille = "d'"
    textSection = textSection.replace("<ARTICLE_VILLE>", articleVille)
    textSection = textSection.replace("<VILLE>", ville[1])
    textSection = textSection.replace("<VILLE_LIEN>", ville[2])
    nomArticleDetail = config.get('GenCode', 'gen.prefixePagedetail') + \
                       " " + articleVille + ville[1]
    textSection = textSection.replace("<NOM_ARTICLE_DETAIL>", nomArticleDetail)
    # Construction du nom de département avec article
    article = ville[3]
    if not article.endswith("'"):
        article += " "
    nomDepartement = ville[4]
    categorieArticle = config.get('GenCode', 'gen.prefixeCategorieArticle') + \
                       " " + article + nomDepartement
    textSection = textSection.replace("<CATEGORIE_ARTICLE>", categorieArticle)

    # Info du groupement d'appartenance
    lienGroupement = "aucun groupement d'appartenance"
    if infosGroupement:
        lienGroupement = genCodeCommon.genLien(config, infosGroupement[1:2],
                                               isWikicode, verbose)
    textSection = textSection.replace("<LIEN_GROUPEMENT>", lienGroupement)

    # Budget général
    codeCle = "total des charges de fonctionnement"
    chargesF = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    codeCle = "total des emplois investissement"
    emploisI = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    depensesTotal = chargesF + emploisI
    textSection = textSection.replace("<DEPENSES_TOTAL>", f"{depensesTotal:.0f}")
    textSection = textSection.replace("<CHARGES_FONCTIONNEMENT>", f"{chargesF:.0f}")
    textSection = textSection.replace("<EMPLOIS_INVEST>", f"{emploisI:.0f}")

    codeCle = "total des produits de fonctionnement"
    produitsF = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    codeCle = "total des ressources d'investissement"
    ressourcesI = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    recettesTotal = produitsF + ressourcesI
    textSection = textSection.replace("<RECETTES_TOTAL>", f"{recettesTotal:.0f}")
    textSection = textSection.replace("<PRODUITS_FONCTIONNEMENT>", f"{produitsF:.0f}")
    textSection = textSection.replace("<RESSOURCES_INVEST>", f"{ressourcesI:.0f}")

    # Fonctionnement
    codeCle = "resultat comptable"
    resultatC = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    textSection = textSection.replace("<RESULTAT_COMPTABLE>", f"{resultatC:.0f}")
    codeCle = "resultat comptable par habitant"
    resultatCpH = dictAllGrandeur["Par habitant"][codeCle][listAnnees[0]]
    textSection = textSection.replace("<RESULTAT_COMPTABLE_PAR_HAB>", f"{resultatCpH:.0f}")
    codeCle = "total des charges de fonctionnement par habitant"
    ChargesFpH = dictAllGrandeur["Par habitant"][codeCle][listAnnees[0]]
    textSection = textSection.replace("<CHARGES_FONCTIONNEMENT_PAR_HAB>", f"{ChargesFpH:.0f}")
    codeCle = "total des produits de fonctionnement par habitant"
    ProduitsFpH = dictAllGrandeur["Par habitant"][codeCle][listAnnees[0]]
    textSection = textSection.replace("<PRODUITS_FONCTIONNEMENT_PAR_HAB>", f"{ProduitsFpH:.0f}")

    # Variation DGF
    codeCle = "dotation globale de fonctionnement"
    dgf = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[0]] * 1e3
    dgfm1 = dictAllGrandeur["Valeur totale"][codeCle][listAnnees[1]] * 1e3
    tendanceDGFstr = utilitaires.calculeTendance(config, dgf, dgfm1)
    textSection = textSection.replace("<TENDANCE_DGF>", tendanceDGFstr)

    # ratio Dette / CAF
    textSection = textSection.replace("<RATIO_N>", dictAllGrandeur["ratio n"])
    textSection = textSection.replace("<TENDANCE_RATIO_DETTE_CAF>",
                                      dictAllGrandeur["tendance ratio"])

    # Réferences
    urlMinFi = config.get('Extraction', 'dataGouvFr.Comptes')
    textSection = textSection.replace("<URL_BASE>", urlMinFi)
    urlMinFiVilles = config.get('Extraction', 'dataGouvFr.ComptesVilles')
    textSection = textSection.replace("<URL_BASE_VILLES>", urlMinFiVilles)
    textSection = textSection.replace("<DATE>", time.strftime("%d %B %G"))

    # Commentaire definition strate
    defStrate = ville[5] + ' ' + ville[6]
    defStrate = defStrate.replace('Strate :', 'La strate regroupe les')
    if isWikicode:
        strateWikif = wikifieStrate(defStrate, verbose)
    else:
        strateWikif = defStrate
    textSection = textSection.replace("<DEF_STRATE>", strateWikif)

    if verbose:
        print("textSection resultat =\n", textSection)
        print("Sortie de genTexte")

    return textSection