ositah 24.9.dev2__tar.gz → 24.9.dev4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ositah might be problematic. Click here for more details.
- {ositah-24.9.dev2/ositah.egg-info → ositah-24.9.dev4}/PKG-INFO +2 -2
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/analysis.py +15 -4
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/tables.py +2 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/tools.py +21 -2
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/ositah.example.cfg +16 -4
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/utils.py +17 -5
- {ositah-24.9.dev2 → ositah-24.9.dev4/ositah.egg-info}/PKG-INFO +2 -2
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/requires.txt +1 -1
- {ositah-24.9.dev2 → ositah-24.9.dev4}/pyproject.toml +2 -2
- {ositah-24.9.dev2 → ositah-24.9.dev4}/.gitignore +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/.gitlab-ci.yml +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/LICENSE +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/README.md +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/Dockerfile +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/docker-compose.yml +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/pyproject-poetry.toml +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/README.md +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/gunicorn.ositah +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/gunicorn@.service +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/ositah.conf.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/noxfile.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/__init__.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/app.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/__init__.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/__init__.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/callbacks.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/main.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/parameters.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/tools.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/export.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/__init__.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/callbacks.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/main.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/parameters.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/arrow_down_up.svg +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/ositah.css +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sort_ascending.svg +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sort_descending.svg +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sorttable.js +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/main.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/static/style.css +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/base.html +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/bootstrap_login.html +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/login_form.html +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/__init__.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/agents.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/authentication.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/cache.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/core.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/exceptions.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/hito_db.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/hito_db_model.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/menus.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/period.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/projects.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/teams.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/SOURCES.txt +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/dependency_links.txt +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/entry_points.txt +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/top_level.txt +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/setup.cfg +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/setup.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/README.md +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/accordion.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/authentication.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/checkbox.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/checklist.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/file-selector.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/file-upload.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/long_running_callback.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pandas_split.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pandas_split_bug_report.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pattern-matching-callback.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/progess_bar.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/reset_table_checkboxes.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/sortable_table.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/sqlalchemy_test.py +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/templates/base.html +0 -0
- {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/templates/login_form.html +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ositah
|
|
3
|
-
Version: 24.9.
|
|
3
|
+
Version: 24.9.dev4
|
|
4
4
|
Summary: Outils de Suivi d'Activités basé sur Hito
|
|
5
5
|
Author-email: Michel Jouvin <michel.jouvin@ijclab.in2p3.fr>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -19,7 +19,7 @@ Requires-Dist: flask
|
|
|
19
19
|
Requires-Dist: flask-multipass
|
|
20
20
|
Requires-Dist: flask-sqlalchemy~=3.0
|
|
21
21
|
Requires-Dist: flask-wtf
|
|
22
|
-
Requires-Dist: hito-tools>=24.8
|
|
22
|
+
Requires-Dist: hito-tools>=24.8.1
|
|
23
23
|
Requires-Dist: pandas>=2.2
|
|
24
24
|
Requires-Dist: pymysql
|
|
25
25
|
Requires-Dist: python-ldap
|
|
@@ -301,11 +301,22 @@ def project_agents_time(declarations, project):
|
|
|
301
301
|
global_params = GlobalParams()
|
|
302
302
|
columns = global_params.columns
|
|
303
303
|
|
|
304
|
-
project_agents = declarations[declarations[columns["activity"]] == project]
|
|
305
|
-
|
|
304
|
+
project_agents = declarations[declarations[columns["activity"]] == project]
|
|
305
|
+
project_agents.loc[:, columns["hours"]] = np.round(project_agents[columns["hours"]]).astype(
|
|
306
|
+
"int"
|
|
307
|
+
)
|
|
308
|
+
project_agents.loc[:, columns["weeks"]] = np.round(
|
|
309
|
+
project_agents.loc[:, columns["hours"]] / WEEK_HOURS, 1
|
|
310
|
+
)
|
|
311
|
+
if global_params.analysis_params["contributions_sorted_by_name"]:
|
|
312
|
+
sort_by = ["nom", columns["hours"]]
|
|
313
|
+
sort_ascending = True
|
|
314
|
+
else:
|
|
315
|
+
sort_by = [columns["hours"], "nom"]
|
|
316
|
+
sort_ascending = False
|
|
317
|
+
project_agents.sort_values(
|
|
318
|
+
by=sort_by, ascending=sort_ascending, ignore_index=True, inplace=True
|
|
306
319
|
)
|
|
307
|
-
project_agents[columns["hours"]] = np.round(project_agents[columns["hours"]]).astype("int")
|
|
308
|
-
project_agents[columns["weeks"]] = np.round(project_agents[columns["hours"]] / WEEK_HOURS, 1)
|
|
309
320
|
return html.Div(
|
|
310
321
|
[
|
|
311
322
|
html.Div(
|
|
@@ -23,6 +23,7 @@ from ositah.apps.validation.tools import (
|
|
|
23
23
|
agent_project_time,
|
|
24
24
|
agent_tooltip_txt,
|
|
25
25
|
category_declarations,
|
|
26
|
+
define_declaration_thresholds,
|
|
26
27
|
get_all_validation_status,
|
|
27
28
|
validation_started,
|
|
28
29
|
)
|
|
@@ -71,6 +72,7 @@ def build_validation_table(team, team_selection_date, declaration_set: int, peri
|
|
|
71
72
|
validation_disabled = not validation_started(period_date)
|
|
72
73
|
|
|
73
74
|
validation_data = get_all_validation_status(period_date)
|
|
75
|
+
define_declaration_thresholds(period_date)
|
|
74
76
|
|
|
75
77
|
try:
|
|
76
78
|
project_declarations = get_team_projects(
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Various functions used by Validation sub-application
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from datetime import datetime
|
|
5
|
+
from datetime import date, datetime
|
|
6
6
|
|
|
7
7
|
import dash_bootstrap_components as dbc
|
|
8
8
|
import pandas as pd
|
|
@@ -54,7 +54,7 @@ def activity_time_cell(row, column, row_index):
|
|
|
54
54
|
cell_id = f"validation-table-value-{row_index}-{column}"
|
|
55
55
|
|
|
56
56
|
if column == "percent_global":
|
|
57
|
-
thresholds = global_params.declaration_options["thresholds"]
|
|
57
|
+
thresholds = global_params.declaration_options["thresholds"]["current"]
|
|
58
58
|
percent = round(row["percent_global"], 1)
|
|
59
59
|
if percent <= thresholds["low"]:
|
|
60
60
|
percent_class = "table-danger"
|
|
@@ -374,6 +374,25 @@ def category_declarations(
|
|
|
374
374
|
return category_declarations
|
|
375
375
|
|
|
376
376
|
|
|
377
|
+
def define_declaration_thresholds(period_date: str):
|
|
378
|
+
"""
|
|
379
|
+
Define the declaration thresholds (low, suspect, normal) for the current period
|
|
380
|
+
|
|
381
|
+
:param period_date: a date that must be inside the declaration period
|
|
382
|
+
"""
|
|
383
|
+
global_params = GlobalParams()
|
|
384
|
+
|
|
385
|
+
period_datetime = date.fromisoformat(period_date)
|
|
386
|
+
if period_datetime.month >= 7:
|
|
387
|
+
global_params.declaration_options["thresholds"]["current"] = (
|
|
388
|
+
global_params.declaration_options["thresholds"]["s2"]
|
|
389
|
+
)
|
|
390
|
+
else:
|
|
391
|
+
global_params.declaration_options["thresholds"]["current"] = (
|
|
392
|
+
global_params.declaration_options["thresholds"]["s1"]
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
|
|
377
396
|
def get_validation_data(agent_id, period_date: str, session=None):
|
|
378
397
|
"""
|
|
379
398
|
Return the validation data for an agent or None if there is no entry in the database for this
|
|
@@ -99,11 +99,23 @@ declaration:
|
|
|
99
99
|
- Administration
|
|
100
100
|
- Support
|
|
101
101
|
# Thresholds used to mark declarations as low, suspect or good
|
|
102
|
-
# The value is the upper bound for the
|
|
102
|
+
# The value is the upper bound for the corresponding class
|
|
103
|
+
# Thresholds are declared by semester as they are typically different
|
|
103
104
|
thresholds:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
# S1: assume ho holidays as the default
|
|
106
|
+
s1:
|
|
107
|
+
low: 50
|
|
108
|
+
suspect: 80
|
|
109
|
+
good: 100
|
|
110
|
+
# S2: assume 4 weeks of holidays by default (summer + Christmas)
|
|
111
|
+
s2:
|
|
112
|
+
low: 50
|
|
113
|
+
suspect: 70
|
|
114
|
+
good: 85
|
|
115
|
+
|
|
116
|
+
# Information related to declaration analysis
|
|
117
|
+
analysis:
|
|
118
|
+
contributions_sorted_by_name: False
|
|
107
119
|
|
|
108
120
|
# Information related to validation
|
|
109
121
|
validation:
|
|
@@ -224,6 +224,7 @@ class OSITAHSessionData:
|
|
|
224
224
|
class GlobalParams:
|
|
225
225
|
def __init__(self):
|
|
226
226
|
self.agent_query = None
|
|
227
|
+
self.analysis_params = None
|
|
227
228
|
self.category_patterns = {}
|
|
228
229
|
self.columns = COLUMN_NAMES
|
|
229
230
|
self.column_titles = None
|
|
@@ -380,17 +381,28 @@ def define_config_params(file):
|
|
|
380
381
|
if "max_hours" not in config["declaration"]:
|
|
381
382
|
# Set a very high value
|
|
382
383
|
config["declaration"]["max_hours"] = 99999
|
|
383
|
-
|
|
384
|
+
missing_params = []
|
|
385
|
+
for semester in ["s1", "s2"]:
|
|
384
386
|
for k in ["low", "suspect", "good"]:
|
|
385
|
-
if
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
387
|
+
if (
|
|
388
|
+
"thresholds" not in config["declaration"]
|
|
389
|
+
or semester not in config["declaration"]["thresholds"]
|
|
390
|
+
or k not in config["declaration"]["thresholds"][semester]
|
|
391
|
+
):
|
|
392
|
+
missing_params.append(f"declaration/thresholds/{semester}/{k}")
|
|
393
|
+
if len(missing_params) > 0:
|
|
394
|
+
raise ConfigMissingParam(", ".join(missing_params), file)
|
|
389
395
|
# Default declaration period date defaults to current day if not explicitly defined
|
|
390
396
|
if "default_date" not in config["declaration"]:
|
|
391
397
|
config["declaration"]["default_date"] = datetime.now()
|
|
392
398
|
global_params.declaration_options = config["declaration"]
|
|
393
399
|
|
|
400
|
+
if "analysis" not in config:
|
|
401
|
+
config["analysis"] = {}
|
|
402
|
+
if "contributions_sorted_by_name" not in config["analysis"]:
|
|
403
|
+
config["analysis"]["contributions_sorted_by_name"] = True
|
|
404
|
+
global_params.analysis_params = config["analysis"]
|
|
405
|
+
|
|
394
406
|
if "validation" not in config:
|
|
395
407
|
config["validation"] = {}
|
|
396
408
|
if "override_period" not in config["validation"]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ositah
|
|
3
|
-
Version: 24.9.
|
|
3
|
+
Version: 24.9.dev4
|
|
4
4
|
Summary: Outils de Suivi d'Activités basé sur Hito
|
|
5
5
|
Author-email: Michel Jouvin <michel.jouvin@ijclab.in2p3.fr>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -19,7 +19,7 @@ Requires-Dist: flask
|
|
|
19
19
|
Requires-Dist: flask-multipass
|
|
20
20
|
Requires-Dist: flask-sqlalchemy~=3.0
|
|
21
21
|
Requires-Dist: flask-wtf
|
|
22
|
-
Requires-Dist: hito-tools>=24.8
|
|
22
|
+
Requires-Dist: hito-tools>=24.8.1
|
|
23
23
|
Requires-Dist: pandas>=2.2
|
|
24
24
|
Requires-Dist: pymysql
|
|
25
25
|
Requires-Dist: python-ldap
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ositah"
|
|
7
|
-
version = "24.9.
|
|
7
|
+
version = "24.9.dev4"
|
|
8
8
|
description = "Outils de Suivi d'Activités basé sur Hito"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -21,7 +21,7 @@ dependencies = [
|
|
|
21
21
|
"flask-multipass",
|
|
22
22
|
"flask-sqlalchemy~=3.0",
|
|
23
23
|
"flask-wtf",
|
|
24
|
-
"hito-tools>=24.8",
|
|
24
|
+
"hito-tools>=24.8.1",
|
|
25
25
|
"pandas>=2.2",
|
|
26
26
|
"pymysql",
|
|
27
27
|
"python-ldap",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|