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.

Files changed (79) hide show
  1. {ositah-24.9.dev2/ositah.egg-info → ositah-24.9.dev4}/PKG-INFO +2 -2
  2. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/analysis.py +15 -4
  3. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/tables.py +2 -0
  4. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/tools.py +21 -2
  5. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/ositah.example.cfg +16 -4
  6. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/utils.py +17 -5
  7. {ositah-24.9.dev2 → ositah-24.9.dev4/ositah.egg-info}/PKG-INFO +2 -2
  8. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/requires.txt +1 -1
  9. {ositah-24.9.dev2 → ositah-24.9.dev4}/pyproject.toml +2 -2
  10. {ositah-24.9.dev2 → ositah-24.9.dev4}/.gitignore +0 -0
  11. {ositah-24.9.dev2 → ositah-24.9.dev4}/.gitlab-ci.yml +0 -0
  12. {ositah-24.9.dev2 → ositah-24.9.dev4}/LICENSE +0 -0
  13. {ositah-24.9.dev2 → ositah-24.9.dev4}/README.md +0 -0
  14. {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/Dockerfile +0 -0
  15. {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/docker-compose.yml +0 -0
  16. {ositah-24.9.dev2 → ositah-24.9.dev4}/docker/pyproject-poetry.toml +0 -0
  17. {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/README.md +0 -0
  18. {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/gunicorn.ositah +0 -0
  19. {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/gunicorn@.service +0 -0
  20. {ositah-24.9.dev2 → ositah-24.9.dev4}/gunicorn.config/ositah.conf.py +0 -0
  21. {ositah-24.9.dev2 → ositah-24.9.dev4}/noxfile.py +0 -0
  22. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/__init__.py +0 -0
  23. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/app.py +0 -0
  24. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/__init__.py +0 -0
  25. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/__init__.py +0 -0
  26. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/callbacks.py +0 -0
  27. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/main.py +0 -0
  28. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/parameters.py +0 -0
  29. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/configuration/tools.py +0 -0
  30. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/export.py +0 -0
  31. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/__init__.py +0 -0
  32. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/callbacks.py +0 -0
  33. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/main.py +0 -0
  34. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/apps/validation/parameters.py +0 -0
  35. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/arrow_down_up.svg +0 -0
  36. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/ositah.css +0 -0
  37. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sort_ascending.svg +0 -0
  38. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sort_descending.svg +0 -0
  39. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/assets/sorttable.js +0 -0
  40. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/main.py +0 -0
  41. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/static/style.css +0 -0
  42. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/base.html +0 -0
  43. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/bootstrap_login.html +0 -0
  44. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/templates/login_form.html +0 -0
  45. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/__init__.py +0 -0
  46. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/agents.py +0 -0
  47. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/authentication.py +0 -0
  48. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/cache.py +0 -0
  49. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/core.py +0 -0
  50. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/exceptions.py +0 -0
  51. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/hito_db.py +0 -0
  52. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/hito_db_model.py +0 -0
  53. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/menus.py +0 -0
  54. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/period.py +0 -0
  55. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/projects.py +0 -0
  56. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah/utils/teams.py +0 -0
  57. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/SOURCES.txt +0 -0
  58. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/dependency_links.txt +0 -0
  59. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/entry_points.txt +0 -0
  60. {ositah-24.9.dev2 → ositah-24.9.dev4}/ositah.egg-info/top_level.txt +0 -0
  61. {ositah-24.9.dev2 → ositah-24.9.dev4}/setup.cfg +0 -0
  62. {ositah-24.9.dev2 → ositah-24.9.dev4}/setup.py +0 -0
  63. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/README.md +0 -0
  64. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/accordion.py +0 -0
  65. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/authentication.py +0 -0
  66. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/checkbox.py +0 -0
  67. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/checklist.py +0 -0
  68. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/file-selector.py +0 -0
  69. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/file-upload.py +0 -0
  70. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/long_running_callback.py +0 -0
  71. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pandas_split.py +0 -0
  72. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pandas_split_bug_report.py +0 -0
  73. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/pattern-matching-callback.py +0 -0
  74. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/progess_bar.py +0 -0
  75. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/reset_table_checkboxes.py +0 -0
  76. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/sortable_table.py +0 -0
  77. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/sqlalchemy_test.py +0 -0
  78. {ositah-24.9.dev2 → ositah-24.9.dev4}/test-dash/templates/base.html +0 -0
  79. {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.dev2
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].sort_values(
305
- by="nom"
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 corresonding class
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
- low: 50
105
- suspect: 80
106
- good: 100
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
- if "thresholds" in config["declaration"]:
384
+ missing_params = []
385
+ for semester in ["s1", "s2"]:
384
386
  for k in ["low", "suspect", "good"]:
385
- if k not in config["declaration"]["thresholds"]:
386
- raise ConfigMissingParam(f"declaration/thresholds/{k}", file)
387
- else:
388
- config["declaration"]["thresholds"] = {"low": 50, "suspect": 75, "good": 100}
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.dev2
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
@@ -5,7 +5,7 @@ flask
5
5
  flask-multipass
6
6
  flask-sqlalchemy~=3.0
7
7
  flask-wtf
8
- hito-tools>=24.8
8
+ hito-tools>=24.8.1
9
9
  pandas>=2.2
10
10
  pymysql
11
11
  python-ldap
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ositah"
7
- version = "24.9.dev2"
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