Commit 5ad3eac3154a28ecf70d8fb46bb1c98aca5323e6
Exists in
master
and in
4 other branches
Charge unit is ETP
Showing
11 changed files
with
74 additions
and
52 deletions
Show diff stats
CHANGELOG.md
@@ -24,6 +24,10 @@ or major refactoring improvments. | @@ -24,6 +24,10 @@ or major refactoring improvments. | ||
24 | 24 | ||
25 | ## Unreleased | 25 | ## Unreleased |
26 | 26 | ||
27 | +## [0.3.pre-2] - 2021-04-21 - Display ETP | ||
28 | +### Changed | ||
29 | +Chart now displays charge in ETP base 1 (was base 100 ) | ||
30 | + | ||
27 | ## [0.3.pre-1] - 2021-04-16 - Irap db integration | 31 | ## [0.3.pre-1] - 2021-04-16 - Irap db integration |
28 | ### New | 32 | ### New |
29 | Irap db feed from csv file | 33 | Irap db feed from csv file |
INSTALL.md
@@ -3,9 +3,9 @@ | @@ -3,9 +3,9 @@ | ||
3 | ## Prérequis | 3 | ## Prérequis |
4 | 4 | ||
5 | - python3 | 5 | - python3 |
6 | -- sqlite ( pour le développement et les tests unitaires ) | ||
7 | -- chrome-driver et chromium ( pour les tests unitaires) | ||
8 | -- postgresql ou mysql/mariadb ( pour la production ) | 6 | +- SQLite (pour le développement et les tests unitaires) |
7 | +- chrome-driver et chromium (pour les tests unitaires) | ||
8 | +- postgresql ou mysql/mariadb (pour la production) | ||
9 | 9 | ||
10 | ## Obtenir un répertoire fonctionnel | 10 | ## Obtenir un répertoire fonctionnel |
11 | 11 | ||
@@ -23,8 +23,8 @@ | @@ -23,8 +23,8 @@ | ||
23 | 23 | ||
24 | ### Configurer l'application | 24 | ### Configurer l'application |
25 | 25 | ||
26 | -Les fichiers de configuration fournis dans le répertoire ./resources sont à copier à la racine du projet, | ||
27 | -mais peuvent être laissés tels quels pour un premier test après installation. | 26 | +Les fichiers de configuration fournis dans le répertoire ./resources sont à copier à la racine du projet, mais peuvent |
27 | +être laissés tels quels pour un premier test après installation. | ||
28 | 28 | ||
29 | Il est bon d'y jeter un oeil, les commentaires sont là pour vous aider. | 29 | Il est bon d'y jeter un oeil, les commentaires sont là pour vous aider. |
30 | (mais en anglais comme tout le code source du projet) | 30 | (mais en anglais comme tout le code source du projet) |
@@ -46,7 +46,7 @@ Il est bon d'y jeter un oeil, les commentaires sont là pour vous aider. | @@ -46,7 +46,7 @@ Il est bon d'y jeter un oeil, les commentaires sont là pour vous aider. | ||
46 | cp ./resources/flaskenv ./.flaskenv # ! noter le '.' devant le fichier destination | 46 | cp ./resources/flaskenv ./.flaskenv # ! noter le '.' devant le fichier destination |
47 | $(EDITOR) .flaskenv | 47 | $(EDITOR) .flaskenv |
48 | 48 | ||
49 | -### Créer la base de données | 49 | +### Créer la base de données |
50 | 50 | ||
51 | Dans un premier temps, pour tester l'installation, on peut s'appuyer sur une base déjà disponible. | 51 | Dans un premier temps, pour tester l'installation, on peut s'appuyer sur une base déjà disponible. |
52 | 52 | ||
@@ -57,12 +57,11 @@ la diffusion de ces données de test avec le projet plan-de-charge. | @@ -57,12 +57,11 @@ la diffusion de ces données de test avec le projet plan-de-charge. | ||
57 | cp resources/lesia-btp.sqlite ./pdc-dev.db | 57 | cp resources/lesia-btp.sqlite ./pdc-dev.db |
58 | 58 | ||
59 | Vérifier que ce chemin correspond avec celui configuré dans le fichier `db_config.py` pour la | 59 | Vérifier que ce chemin correspond avec celui configuré dans le fichier `db_config.py` pour la |
60 | -variable `sqlalchemy_devdb_uri`. | ||
61 | -C'est le cas dans le fichier initial pour une variable `FLASK_ENV` positionnée à 'development'. | 60 | +variable `sqlalchemy_devdb_uri`. C'est le cas dans le fichier initial pour une variable `FLASK_ENV` positionnée à ' |
61 | +development'. | ||
62 | 62 | ||
63 | Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'application. | 63 | Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'application. |
64 | -(sinon, passez directement à la section suivante ) | ||
65 | - | 64 | +(sinon, passez directement à la section suivante) |
66 | 65 | ||
67 | # Créer la structure de la base | 66 | # Créer la structure de la base |
68 | # | 67 | # |
@@ -89,7 +88,6 @@ Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'app | @@ -89,7 +88,6 @@ Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'app | ||
89 | flask --help | 88 | flask --help |
90 | flask pdc_db --help | 89 | flask pdc_db --help |
91 | 90 | ||
92 | - | ||
93 | ## Jouer les tests et exécuter un serveur local | 91 | ## Jouer les tests et exécuter un serveur local |
94 | 92 | ||
95 | pip install -r requirements-tests.txt | 93 | pip install -r requirements-tests.txt |
@@ -100,13 +98,13 @@ Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'app | @@ -100,13 +98,13 @@ Pour un usage plus avancé, voyez l'outil en ligne de commande fourni avec l'app | ||
100 | # | 98 | # |
101 | PYTHONPATH=. pytest --cov=app --cov-report=xml:"coverage.xml" --cov-report=term --junitxml "tests-report.xml" | 99 | PYTHONPATH=. pytest --cov=app --cov-report=xml:"coverage.xml" --cov-report=term --junitxml "tests-report.xml" |
102 | 100 | ||
103 | -Enfin, ouvrir un serveur sur localhost:5000 et y accéder avec son navigateur. | 101 | +Enfin, ouvrir un serveur sur `localhost:5000` et y accéder avec son navigateur. |
104 | 102 | ||
105 | flask run | 103 | flask run |
106 | 104 | ||
107 | -## Configurer l'appli web avec apache | 105 | +## Configurer l'appli web avec apache |
108 | 106 | ||
109 | -### Les fichiers concernés: | 107 | +### Les fichiers concernés : |
110 | 108 | ||
111 | - pdc_web.wsgi | 109 | - pdc_web.wsgi |
112 | - pdc_web.py | 110 | - pdc_web.py |
@@ -137,14 +135,13 @@ Enfin, ouvrir un serveur sur localhost:5000 et y accéder avec son navigateur. | @@ -137,14 +135,13 @@ Enfin, ouvrir un serveur sur localhost:5000 et y accéder avec son navigateur. | ||
137 | a2ensite pdc-web | 135 | a2ensite pdc-web |
138 | apachectl restart | 136 | apachectl restart |
139 | 137 | ||
140 | - | ||
141 | -## Mise à jour | 138 | +## Mise à jour |
142 | 139 | ||
143 | ### git pull | 140 | ### git pull |
144 | 141 | ||
145 | ### git autodeploy | 142 | ### git autodeploy |
146 | 143 | ||
147 | -Les fichiers concernés: | 144 | +Les fichiers concernés : |
148 | 145 | ||
149 | - scripts/post-deploy.sh | 146 | - scripts/post-deploy.sh |
150 | - resources/post-receive.git-hook | 147 | - resources/post-receive.git-hook |
@@ -163,8 +160,8 @@ La procédure: | @@ -163,8 +160,8 @@ La procédure: | ||
163 | 160 | ||
164 | ## Gestion des utilisateurs | 161 | ## Gestion des utilisateurs |
165 | 162 | ||
166 | -La table `users` stocke les utilisateur qui se connectent à l'applicationa avec leur rôle et les droits associés. | ||
167 | -Un ensemble de commandes permet de les gérer: | 163 | +La table `users` stocke les utilisateurs qui se connectent à l'applicationa avec leur rôle et les droits associés. Un |
164 | +ensemble de commandes permet de les gérer : | ||
168 | 165 | ||
169 | flask pdc_db user_show_all # liste existante | 166 | flask pdc_db user_show_all # liste existante |
170 | flask pdc_db user_add # ajouter un nouveau login | 167 | flask pdc_db user_add # ajouter un nouveau login |
@@ -172,31 +169,28 @@ Un ensemble de commandes permet de les gérer: | @@ -172,31 +169,28 @@ Un ensemble de commandes permet de les gérer: | ||
172 | flask pdc_db user_delete # effacer un login existant | 169 | flask pdc_db user_delete # effacer un login existant |
173 | flask pdc_db show_roles # lister les rôles disponibles | 170 | flask pdc_db show_roles # lister les rôles disponibles |
174 | 171 | ||
175 | -## Intégration Pycharm | 172 | +## Intégration Pycharm |
176 | 173 | ||
177 | -Ce projet utilisant le pattern "factory", il faut procéder | ||
178 | -à quelques configuration afin de le faire tourner avec | 174 | +Ce projet utilisant le pattern "factory", il faut procéder à quelques configurations afin de le faire tourner avec |
179 | pycharm. | 175 | pycharm. |
180 | 176 | ||
181 | -Pour une procédure détaillée, voir la page: | 177 | +Pour une procédure détaillée, voir la page : |
182 | 178 | ||
183 | https://flask.palletsprojects.com/en/1.1.x/cli/#pycharm-integration | 179 | https://flask.palletsprojects.com/en/1.1.x/cli/#pycharm-integration |
184 | 180 | ||
185 | -Dans le menu 'Edit Configurations', changer les champs: | 181 | +Dans le menu 'Edit Configurations', changer les champs : |
186 | 182 | ||
187 | - 'module name' positionné à 'flask' | 183 | - 'module name' positionné à 'flask' |
188 | -- et dans le champs 'Parameters' choisir 'run' | 184 | +- et dans le champ 'Parameters' choisir 'run' |
189 | 185 | ||
190 | - | ||
191 | -Cette configuration permet de lire les variables positionées dans le fichier .flaskenv | 186 | +Cette configuration permet de lire les variables positionées dans le fichier `.flaskenv` |
192 | 187 | ||
193 | FLASK_ENV=development | 188 | FLASK_ENV=development |
194 | FLASK_APP=pdc_web | 189 | FLASK_APP=pdc_web |
195 | 190 | ||
196 | - | ||
197 | -Ainsi fait, exécutez votre projet depuis pycharm et essayez sur un navigateur à l'adresse localhost:5000. | 191 | +Ainsi fait, exécutez votre projet depuis pycharm et essayez sur un navigateur à l'adresse `localhost:5000`. |
198 | 192 | ||
199 | ## Troubleshooting | 193 | ## Troubleshooting |
200 | 194 | ||
201 | -* Q: parfois le module Flask-Migrate n'est pas correctement chargé aprés son installation. | ||
202 | -* R: simplement recharger l'environnement virtuel avec `source venv/bin/activate` | 195 | +* Q : parfois le module Flask-Migrate n'est pas correctement chargé aprés son installation. |
196 | +* R : simplement recharger l'environnement virtuel avec `source venv/bin/activate` |
VERSION.txt
app/commands/commands.py
@@ -131,6 +131,8 @@ def feed_from_irap(csv_file_name): | @@ -131,6 +131,8 @@ def feed_from_irap(csv_file_name): | ||
131 | for period_name in range(2011, 2030): | 131 | for period_name in range(2011, 2030): |
132 | t = Period.query.filter(Period.name == period_name).one() | 132 | t = Period.query.filter(Period.name == period_name).one() |
133 | charge = r[f"{period_name}"] | 133 | charge = r[f"{period_name}"] |
134 | + # Charge are stored as percent in db, but as fraction of ETP in irap csv | ||
135 | + # we make the conversion here. | ||
134 | try: | 136 | try: |
135 | charge = int(100 * float(charge)) | 137 | charge = int(100 * float(charge)) |
136 | except ValueError: | 138 | except ValueError: |
app/db_mgr.py
1 | -from app.models import db | 1 | +from app.models import db, Period |
2 | + | ||
3 | +# TODO: make this configurable, and choose another place to use it, | ||
4 | +# in 'routes.py' maybe | ||
5 | +# Charge as stored on a 100% basis, percent of total worked time; | ||
6 | +# Here it is possible to convert to an ETP basis, dividing by 100 | ||
7 | +# or we set it to '1' if we want to keep the percent basis | ||
8 | +charge_unit = 100 | ||
2 | 9 | ||
3 | 10 | ||
4 | def projects(): | 11 | def projects(): |
@@ -8,7 +15,7 @@ def projects(): | @@ -8,7 +15,7 @@ def projects(): | ||
8 | """ | 15 | """ |
9 | current_period_id = get_current_period() | 16 | current_period_id = get_current_period() |
10 | sql_txt = """ | 17 | sql_txt = """ |
11 | - select p.id, p.name, sum(tc.charge_rate) as total_charge | 18 | + select p.id, p.name, IFNULL(sum(tc.charge_rate), 0) as total_charge |
12 | from project as p left join | 19 | from project as p left join |
13 | ( select c.project_id, c.charge_rate from charge c where c.period_id = {}) | 20 | ( select c.project_id, c.charge_rate from charge c where c.period_id = {}) |
14 | tc | 21 | tc |
@@ -27,7 +34,7 @@ def agents(): | @@ -27,7 +34,7 @@ def agents(): | ||
27 | """ | 34 | """ |
28 | current_period_id = get_current_period() | 35 | current_period_id = get_current_period() |
29 | sql_txt = """ | 36 | sql_txt = """ |
30 | - select a.id, a.firstname, a.secondname, sum(tc.charge_rate) as total_charge | 37 | + select a.id, a.firstname, a.secondname, IFNULL (sum(tc.charge_rate), 0) as total_charge |
31 | from agent as a left join | 38 | from agent as a left join |
32 | ( select c.agent_id, c.charge_rate from charge c where c.period_id = {}) | 39 | ( select c.agent_id, c.charge_rate from charge c where c.period_id = {}) |
33 | tc | 40 | tc |
@@ -86,6 +93,8 @@ def charges_by_project_stacked(project_id, category="service"): | @@ -86,6 +93,8 @@ def charges_by_project_stacked(project_id, category="service"): | ||
86 | . | 93 | . |
87 | . | 94 | . |
88 | per_n, value_n0, value_n1, ....., value_nn, | 95 | per_n, value_n0, value_n1, ....., value_nn, |
96 | + | ||
97 | + TODO: common with charges_by_agent_stacked(agent_id): code to extrat | ||
89 | """ | 98 | """ |
90 | if category == 'capacity': | 99 | if category == 'capacity': |
91 | category_table = 'capacity' | 100 | category_table = 'capacity' |
@@ -117,7 +126,7 @@ def charges_by_project_stacked(project_id, category="service"): | @@ -117,7 +126,7 @@ def charges_by_project_stacked(project_id, category="service"): | ||
117 | # build the charges line for the current period | 126 | # build the charges line for the current period |
118 | category_charges = [period_name] | 127 | category_charges = [period_name] |
119 | for (category_rate,) in db.session.execute(charge_by_categorie_req): | 128 | for (category_rate,) in db.session.execute(charge_by_categorie_req): |
120 | - category_rate = str(category_rate) if category_rate else '0' | 129 | + category_rate = str(round(category_rate / charge_unit, 2)) if category_rate else '0' |
121 | category_charges.append(category_rate) | 130 | category_charges.append(category_rate) |
122 | all_charges.append(category_charges) | 131 | all_charges.append(category_charges) |
123 | 132 | ||
@@ -127,6 +136,7 @@ def charges_by_project_stacked(project_id, category="service"): | @@ -127,6 +136,7 @@ def charges_by_project_stacked(project_id, category="service"): | ||
127 | def charges_by_agent_stacked(agent_id): | 136 | def charges_by_agent_stacked(agent_id): |
128 | """ | 137 | """ |
129 | Build the list of charges for all projects of one agent, period by period | 138 | Build the list of charges for all projects of one agent, period by period |
139 | + TODO: common with charges_by_project_stacked(project_id, ..) code to extrat | ||
130 | :param agent_id: | 140 | :param agent_id: |
131 | :return: | 141 | :return: |
132 | """ | 142 | """ |
@@ -143,10 +153,9 @@ def charges_by_agent_stacked(agent_id): | @@ -143,10 +153,9 @@ def charges_by_agent_stacked(agent_id): | ||
143 | group by p.id | 153 | group by p.id |
144 | order by p.id | 154 | order by p.id |
145 | """.format(agent_id, period_id) | 155 | """.format(agent_id, period_id) |
146 | - print(charge_by_project_req) | ||
147 | category_charges = [period_name] | 156 | category_charges = [period_name] |
148 | for (category_rate,) in db.session.execute(charge_by_project_req): | 157 | for (category_rate,) in db.session.execute(charge_by_project_req): |
149 | - category_rate = str(category_rate) if category_rate else '0' | 158 | + category_rate = str(round(category_rate / charge_unit, 2)) if category_rate else '0' |
150 | category_charges.append(category_rate) | 159 | category_charges.append(category_rate) |
151 | all_charges.append(category_charges) | 160 | all_charges.append(category_charges) |
152 | return all_charges | 161 | return all_charges |
@@ -207,4 +216,5 @@ def get_current_period(): | @@ -207,4 +216,5 @@ def get_current_period(): | ||
207 | :return: the id of the period of current day | 216 | :return: the id of the period of current day |
208 | """ | 217 | """ |
209 | # TODO: request on dates as soon as periods are dated | 218 | # TODO: request on dates as soon as periods are dated |
210 | - return 14 | 219 | + p = Period.query.filter((Period.name == '2021') | (Period.name == '2021_S1')).one() |
220 | + return p.id |
app/main/static/js/charges.js
1 | +function roundToTwo(num) { | ||
2 | + return +(Math.round(num + "e+2") + "e-2"); | ||
3 | +} | ||
4 | + | ||
1 | function build_chart(div_selector, data_url, entity_name, category_type) { | 5 | function build_chart(div_selector, data_url, entity_name, category_type) { |
2 | 6 | ||
3 | const main_elt = document.getElementById("main") | 7 | const main_elt = document.getElementById("main") |
@@ -99,7 +103,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | @@ -99,7 +103,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | ||
99 | .duration(200) | 103 | .duration(200) |
100 | .style("opacity", 1); | 104 | .style("opacity", 1); |
101 | tooltip | 105 | tooltip |
102 | - .html("<b>" + category_title + ":</b> " + category_name + "<br>" + "<b>Charge:</b> " + category_charge + "%") | 106 | + .html("<b>" + category_title + ":</b> " + category_name + "<br>" + "<b>Charge:</b> " + category_charge + " ETP") |
103 | .style("left", (e.pageX - tooltip_offset.dx) + "px") | 107 | .style("left", (e.pageX - tooltip_offset.dx) + "px") |
104 | .style("top", (e.pageY - tooltip_offset.dy) + "px") | 108 | .style("top", (e.pageY - tooltip_offset.dy) + "px") |
105 | } | 109 | } |
@@ -120,7 +124,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | @@ -120,7 +124,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | ||
120 | .duration(200) | 124 | .duration(200) |
121 | .style("opacity", 1) | 125 | .style("opacity", 1) |
122 | tooltip | 126 | tooltip |
123 | - .html("<b>" + d.period + ": </b>" + d.total + "%") | 127 | + .html("<b>" + d.period + ": </b>" + d.total + " ETP") |
124 | .style("left", (e.pageX - tooltip_offset_dot.dx) + "px") | 128 | .style("left", (e.pageX - tooltip_offset_dot.dx) + "px") |
125 | .style("top", (e.pageY - tooltip_offset_dot.dy) + "px") | 129 | .style("top", (e.pageY - tooltip_offset_dot.dy) + "px") |
126 | } | 130 | } |
@@ -247,7 +251,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | @@ -247,7 +251,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | ||
247 | var period_values = Object.values(d).slice(1) | 251 | var period_values = Object.values(d).slice(1) |
248 | var row = {} | 252 | var row = {} |
249 | row['period'] = d.period | 253 | row['period'] = d.period |
250 | - row['total'] = d3.sum(period_values) | 254 | + row['total'] = roundToTwo(d3.sum(period_values)) |
251 | periods_total_charge.push(row) | 255 | periods_total_charge.push(row) |
252 | }); | 256 | }); |
253 | 257 | ||
@@ -308,8 +312,9 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | @@ -308,8 +312,9 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | ||
308 | if (categories_total_charge.hasOwnProperty(k)) { | 312 | if (categories_total_charge.hasOwnProperty(k)) { |
309 | categories_total_charge[k] += +d[k] | 313 | categories_total_charge[k] += +d[k] |
310 | } else { | 314 | } else { |
311 | - categories_total_charge[k] = d[k] | 315 | + categories_total_charge[k] = +d[k] |
312 | } | 316 | } |
317 | + categories_total_charge[k] = roundToTwo(categories_total_charge[k]) | ||
313 | } | 318 | } |
314 | ) | 319 | ) |
315 | }) | 320 | }) |
@@ -384,7 +389,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | @@ -384,7 +389,7 @@ function build_chart(div_selector, data_url, entity_name, category_type) { | ||
384 | .attr("transform", "rotate(-90)") | 389 | .attr("transform", "rotate(-90)") |
385 | .attr("y", -margin.left + 40) | 390 | .attr("y", -margin.left + 40) |
386 | .attr("x", -margin.top - 70) | 391 | .attr("x", -margin.top - 70) |
387 | - .text("Charge (% ETP)"); | 392 | + .text("Charge en ETP"); |
388 | 393 | ||
389 | // | 394 | // |
390 | // Write chart Title | 395 | // Write chart Title |
app/main/templates/agent.html
@@ -17,8 +17,12 @@ | @@ -17,8 +17,12 @@ | ||
17 | <tbody> | 17 | <tbody> |
18 | {% for line in charges[1:] %} | 18 | {% for line in charges[1:] %} |
19 | <tr> | 19 | <tr> |
20 | - {% for cell in line %} | ||
21 | - <td>{{cell}}</td> | 20 | + {% for i in range(line|length) %} |
21 | + {%if 'Charge' in charges[0][i] %} | ||
22 | + <td>{{line[i]}} %</td> | ||
23 | + {%else%} | ||
24 | + <td>{{line[i]}}</td> | ||
25 | + {%endif%} | ||
22 | {% endfor %} | 26 | {% endfor %} |
23 | </tr> | 27 | </tr> |
24 | {% endfor %} | 28 | {% endfor %} |
app/main/templates/agents.html
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | {{ agent.firstname }} | 15 | {{ agent.firstname }} |
16 | {{ agent.secondname }} | 16 | {{ agent.secondname }} |
17 | </a></td> | 17 | </a></td> |
18 | - <td>{{agent.total_charge}}</td> | 18 | + <td>{{agent.total_charge}} %</td> |
19 | <td>{{agent.num_projects}}</td> | 19 | <td>{{agent.num_projects}}</td> |
20 | </tr> | 20 | </tr> |
21 | {% endfor %} | 21 | {% endfor %} |
app/main/templates/projects.html
@@ -13,9 +13,7 @@ | @@ -13,9 +13,7 @@ | ||
13 | <td><a href="{{url_for('main.project', project_id=project.id)}}"> | 13 | <td><a href="{{url_for('main.project', project_id=project.id)}}"> |
14 | {{ project.name }}</a> | 14 | {{ project.name }}</a> |
15 | </td> | 15 | </td> |
16 | - <td> | ||
17 | - {{ project.total_charge }}</a> | ||
18 | - </td> | 16 | + <td>{{ project.total_charge }} % </td> |
19 | </tr> | 17 | </tr> |
20 | {% endfor %} | 18 | {% endfor %} |
21 | </tbody> | 19 | </tbody> |
app/templates/base_page.html
@@ -17,11 +17,11 @@ | @@ -17,11 +17,11 @@ | ||
17 | <span class="navbar-brand">{{current_user.name}}</span> | 17 | <span class="navbar-brand">{{current_user.name}}</span> |
18 | </li> | 18 | </li> |
19 | <li class="nav-item text-nowrap"> | 19 | <li class="nav-item text-nowrap"> |
20 | - <a class="nav-link" href="{{ url_for('auth.logout') }}">Déconnection</a> | 20 | + <a class="nav-link" href="{{ url_for('auth.logout') }}">Déconnexion</a> |
21 | </li> | 21 | </li> |
22 | {% else %} | 22 | {% else %} |
23 | <li class="nav-item text-nowrap"> | 23 | <li class="nav-item text-nowrap"> |
24 | - <a class="nav-link" href="{{ url_for('auth.login') }}">Connection</a> | 24 | + <a class="nav-link" href="{{ url_for('auth.login') }}">Connexion</a> |
25 | </li> | 25 | </li> |
26 | {% endif %} | 26 | {% endif %} |
27 | </ul> | 27 | </ul> |
resources/pdc_config.py
@@ -96,6 +96,11 @@ class DevConfig(Config): | @@ -96,6 +96,11 @@ class DevConfig(Config): | ||
96 | # ignores @role_required decorator | 96 | # ignores @role_required decorator |
97 | ROLE_DISABLED = True | 97 | ROLE_DISABLED = True |
98 | 98 | ||
99 | + from datetime import datetime | ||
100 | + import re | ||
101 | + date = datetime.now().strftime("%y%m%d%H%M") | ||
102 | + VERSION = re.sub(r"^(\d\.\d)\..*$", r"\1" + f".pre-{date}", Config.VERSION) | ||
103 | + | ||
99 | 104 | ||
100 | # Testing configuration | 105 | # Testing configuration |
101 | # | 106 | # |