ositah 25.6.dev1__py3-none-any.whl → 25.9.dev2__py3-none-any.whl

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 (42) hide show
  1. ositah/app.py +17 -17
  2. ositah/apps/analysis.py +785 -785
  3. ositah/apps/configuration/callbacks.py +916 -916
  4. ositah/apps/configuration/main.py +546 -546
  5. ositah/apps/configuration/parameters.py +74 -74
  6. ositah/apps/configuration/tools.py +112 -112
  7. ositah/apps/export.py +1209 -1191
  8. ositah/apps/validation/callbacks.py +240 -240
  9. ositah/apps/validation/main.py +89 -89
  10. ositah/apps/validation/parameters.py +25 -25
  11. ositah/apps/validation/tables.py +646 -646
  12. ositah/apps/validation/tools.py +552 -552
  13. ositah/assets/arrow_down_up.svg +3 -3
  14. ositah/assets/ositah.css +53 -53
  15. ositah/assets/sort_ascending.svg +4 -4
  16. ositah/assets/sort_descending.svg +5 -5
  17. ositah/assets/sorttable.js +499 -499
  18. ositah/main.py +449 -449
  19. ositah/ositah.example.cfg +229 -229
  20. ositah/static/style.css +53 -53
  21. ositah/templates/base.html +22 -22
  22. ositah/templates/bootstrap_login.html +38 -38
  23. ositah/templates/login_form.html +26 -26
  24. ositah/utils/agents.py +124 -124
  25. ositah/utils/authentication.py +287 -287
  26. ositah/utils/cache.py +19 -19
  27. ositah/utils/core.py +13 -13
  28. ositah/utils/exceptions.py +64 -64
  29. ositah/utils/hito_db.py +51 -51
  30. ositah/utils/hito_db_model.py +253 -253
  31. ositah/utils/menus.py +339 -339
  32. ositah/utils/period.py +139 -139
  33. ositah/utils/projects.py +1179 -1178
  34. ositah/utils/teams.py +42 -42
  35. ositah/utils/utils.py +474 -474
  36. {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/METADATA +149 -150
  37. ositah-25.9.dev2.dist-info/RECORD +46 -0
  38. {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/licenses/LICENSE +29 -29
  39. ositah-25.6.dev1.dist-info/RECORD +0 -46
  40. {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/WHEEL +0 -0
  41. {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/entry_points.txt +0 -0
  42. {ositah-25.6.dev1.dist-info → ositah-25.9.dev2.dist-info}/top_level.txt +0 -0
@@ -1,240 +1,240 @@
1
- """
2
- Dash callbacks for Validation sub-application
3
- """
4
-
5
- from datetime import datetime
6
- from uuid import uuid4
7
-
8
- import dash_bootstrap_components as dbc
9
- from dash import dcc, html
10
- from dash.dependencies import MATCH, Input, Output, State
11
-
12
- from ositah.app import app
13
- from ositah.apps.validation.parameters import *
14
- from ositah.apps.validation.tables import (
15
- build_missing_agents_table,
16
- build_statistics_table,
17
- build_validation_table,
18
- )
19
- from ositah.apps.validation.tools import get_validation_data, project_declaration_snapshot
20
- from ositah.utils.hito_db import get_db
21
- from ositah.utils.menus import (
22
- TEAM_SELECTED_VALUE_ID,
23
- TEAM_SELECTION_DATE_ID,
24
- VALIDATION_PERIOD_SELECTED_ID,
25
- create_progress_bar,
26
- )
27
- from ositah.utils.period import get_validation_period_id
28
-
29
-
30
- @app.callback(
31
- [
32
- Output(TAB_ID_DECLARATION_STATS, "children"),
33
- Output(TAB_ID_VALIDATION, "children"),
34
- Output(TAB_ID_MISSING_AGENTS, "children"),
35
- Output(VALIDATION_SAVED_INDICATOR_ID, "data"),
36
- Output(VALIDATION_SAVED_ACTIVE_TAB_ID, "data"),
37
- ],
38
- [
39
- Input(VALIDATION_LOAD_INDICATOR_ID, "data"),
40
- Input(VALIDATION_TAB_MENU_ID, "active_tab"),
41
- Input(TEAM_SELECTED_VALUE_ID, "data"),
42
- Input(VALIDATION_DECLARATIONS_SELECTED_ID, "data"),
43
- ],
44
- [
45
- State(TEAM_SELECTION_DATE_ID, "data"),
46
- State(VALIDATION_SAVED_INDICATOR_ID, "data"),
47
- State(VALIDATION_PERIOD_SELECTED_ID, "data"),
48
- State(VALIDATION_SAVED_ACTIVE_TAB_ID, "data"),
49
- ],
50
- prevent_initial_call=True,
51
- )
52
- def display_validation_tables(
53
- load_in_progress,
54
- active_tab: str,
55
- team: str,
56
- declaration_set: int,
57
- team_selection_date,
58
- previous_load_in_progress,
59
- period_date: str,
60
- previous_active_tab: str,
61
- ):
62
- """
63
- Display active tab contents after a team or an active tab change. Exact action depends on
64
- the value of the load in progress indicator. If it is equal to the previous value, it means
65
- this is the start of the update process: progress bar is displayed and a dcc.Interval is
66
- created to schedule again this callback after incrementing the load in progress indicator.
67
- This causes the callback to be reentered and this time it triggers the real processing for
68
- the tab resulting in the final update of the active tab contents. An empty content is
69
- returned for inactive tabs.
70
-
71
- :param load_in_progress: load in progress indicator
72
- :param tab: select tab name
73
- :param team: selected team
74
- :param declaration_set: selected declaration set (all, validated or non-validated ones)
75
- :param team_selection_date: last time the team selection was changed
76
- :param previous_load_in_progress: previous value of the load_in_progress indicator
77
- :param period_date: a date that must be inside the declaration period
78
- :param previous_active_tab: previously active tab
79
- :return: tab content (empty if the tab is not active)
80
- """
81
-
82
- tab_contents = []
83
-
84
- # Be sure to fill the return values in the same order as Output are declared
85
- tab_list = [TAB_ID_DECLARATION_STATS, TAB_ID_VALIDATION, TAB_ID_MISSING_AGENTS]
86
- for tab in tab_list:
87
- if team and len(team) > 0 and tab == active_tab:
88
- if load_in_progress > previous_load_in_progress and active_tab == previous_active_tab:
89
- if active_tab == TAB_ID_DECLARATION_STATS:
90
- tab_contents.append(
91
- build_statistics_table(team, team_selection_date, period_date)
92
- )
93
- elif active_tab == TAB_ID_VALIDATION:
94
- tab_contents.append(
95
- build_validation_table(
96
- team, team_selection_date, declaration_set, period_date
97
- )
98
- )
99
- elif active_tab == TAB_ID_MISSING_AGENTS:
100
- tab_contents.append(
101
- build_missing_agents_table(team, team_selection_date, period_date)
102
- )
103
- else:
104
- tab_contents.append(
105
- dbc.Alert("Erreur interne: tab non supporté"), color="warning"
106
- )
107
- previous_load_in_progress += 1
108
- else:
109
- component = html.Div(
110
- [
111
- create_progress_bar(team),
112
- dcc.Interval(
113
- id=VALIDATION_DISPLAY_INTERVAL_ID,
114
- n_intervals=0,
115
- max_intervals=1,
116
- interval=500,
117
- ),
118
- ]
119
- )
120
- tab_contents.append(component)
121
- else:
122
- tab_contents.append("")
123
-
124
- tab_contents.extend([previous_load_in_progress, active_tab])
125
-
126
- return tab_contents
127
-
128
-
129
- @app.callback(
130
- Output(VALIDATION_LOAD_INDICATOR_ID, "data"),
131
- Input(VALIDATION_DISPLAY_INTERVAL_ID, "n_intervals"),
132
- State(VALIDATION_SAVED_INDICATOR_ID, "data"),
133
- prevent_initial_call=True,
134
- )
135
- def display_validation_tables_trigger(n, previous_load_indicator):
136
- """
137
- Increment (change) of the input of display_validation_tables callback to get it fired a
138
- second time after displaying the progress bar. The output component must be updated each
139
- time the callback is entered to trigger the execution of the other callback, thus the
140
- choice of incrementing it at each call.
141
-
142
- :param n: n_interval property of the dcc.Interval (0 or 1)
143
- :return: 1 increment to previous value
144
- """
145
-
146
- return previous_load_indicator + 1
147
-
148
-
149
- @app.callback(
150
- Output({"type": "validation-switch", "id": MATCH}, "value"),
151
- Input({"type": "validation-switch", "id": MATCH}, "value"),
152
- State({"type": "validation-agent-id", "id": MATCH}, "data"),
153
- State(TEAM_SELECTED_VALUE_ID, "data"),
154
- State(TEAM_SELECTION_DATE_ID, "data"),
155
- State(VALIDATION_PERIOD_SELECTED_ID, "data"),
156
- prevent_initial_call=True,
157
- )
158
- def validation_button_callback(value, agent_id, team, team_selection_date, period_date: str):
159
- """
160
- Function called as a callback for the validation button. It adds a validation entry for
161
- the selected agent with a timestamp allowing to get the validation history. Doesn't add an
162
- entry if the validation status is unchanged (should not happen).
163
-
164
- :param value: a list with of values with last one equals 1 if the switch is on, an empty
165
- list or a list with 1 value (0) if the switch is off
166
- :param agent_id: the agent ID of the selected agent
167
- :param team: selected team
168
- :param team_selection_date: last time the team selection was changed
169
- :param period_date: a date that must be inside the declaration period
170
- :return: None
171
- """
172
-
173
- from ositah.utils.hito_db_model import OSITAHValidation
174
-
175
- db = get_db()
176
- session = db.session
177
-
178
- validation_data = get_validation_data(agent_id, period_date, session)
179
-
180
- # If the validation switch is on, add a new validation entry for the agent (except if there
181
- # is an existing validated entry but it should not happen) and save the associated project
182
- # declarations. If the switch is off and a validated entry exists, update the "validated"
183
- # attribute to false and do not add a new project declarations.
184
- switch_on = len(value) > 0 and value[len(value) - 1] > 0
185
- if switch_on:
186
- if validation_data is None or validation_data.validated != switch_on:
187
- validation_id = str(uuid4())
188
- validation_data = OSITAHValidation(
189
- id=validation_id,
190
- validated=switch_on,
191
- timestamp=datetime.now(),
192
- agent_id=agent_id,
193
- period_id=get_validation_period_id(period_date),
194
- )
195
- try:
196
- session.add(validation_data)
197
- # A flush() is required before calling project_declaration_snapshot() else the
198
- # first insert is lost
199
- # MJ 2023-07-12: hack to workaround a problem with flush() leading to an undefined
200
- # foreign key
201
- # session.flush()
202
- session.commit()
203
- project_declaration_snapshot(
204
- agent_id,
205
- validation_id,
206
- team,
207
- team_selection_date,
208
- period_date,
209
- session,
210
- )
211
- session.commit()
212
- except: # noqa: E722
213
- session.rollback()
214
- raise
215
-
216
- elif validation_data.validated:
217
- validation_data.validated = switch_on
218
- # Keep track of the original timestamp
219
- validation_data.initial_timestamp = validation_data.timestamp
220
- validation_data.timestamp = datetime.now()
221
- session.commit()
222
-
223
- return value
224
-
225
-
226
- @app.callback(
227
- Output(VALIDATION_DECLARATIONS_SELECTED_ID, "data"),
228
- Input(VALIDATION_DECLARATIONS_SWITCH_ID, "value"),
229
- prevent_initial_call=True,
230
- )
231
- def select_declarations_set(new_set):
232
- """
233
- This callback is used to forward to the validation table callback the selected declarations
234
- set through a dcc.Store that exists permanently in the page.
235
-
236
- :param new_set: selected declarations set
237
- :return: same value
238
- """
239
-
240
- return new_set
1
+ """
2
+ Dash callbacks for Validation sub-application
3
+ """
4
+
5
+ from datetime import datetime
6
+ from uuid import uuid4
7
+
8
+ import dash_bootstrap_components as dbc
9
+ from dash import dcc, html
10
+ from dash.dependencies import MATCH, Input, Output, State
11
+
12
+ from ositah.app import app
13
+ from ositah.apps.validation.parameters import *
14
+ from ositah.apps.validation.tables import (
15
+ build_missing_agents_table,
16
+ build_statistics_table,
17
+ build_validation_table,
18
+ )
19
+ from ositah.apps.validation.tools import get_validation_data, project_declaration_snapshot
20
+ from ositah.utils.hito_db import get_db
21
+ from ositah.utils.menus import (
22
+ TEAM_SELECTED_VALUE_ID,
23
+ TEAM_SELECTION_DATE_ID,
24
+ VALIDATION_PERIOD_SELECTED_ID,
25
+ create_progress_bar,
26
+ )
27
+ from ositah.utils.period import get_validation_period_id
28
+
29
+
30
+ @app.callback(
31
+ [
32
+ Output(TAB_ID_DECLARATION_STATS, "children"),
33
+ Output(TAB_ID_VALIDATION, "children"),
34
+ Output(TAB_ID_MISSING_AGENTS, "children"),
35
+ Output(VALIDATION_SAVED_INDICATOR_ID, "data"),
36
+ Output(VALIDATION_SAVED_ACTIVE_TAB_ID, "data"),
37
+ ],
38
+ [
39
+ Input(VALIDATION_LOAD_INDICATOR_ID, "data"),
40
+ Input(VALIDATION_TAB_MENU_ID, "active_tab"),
41
+ Input(TEAM_SELECTED_VALUE_ID, "data"),
42
+ Input(VALIDATION_DECLARATIONS_SELECTED_ID, "data"),
43
+ ],
44
+ [
45
+ State(TEAM_SELECTION_DATE_ID, "data"),
46
+ State(VALIDATION_SAVED_INDICATOR_ID, "data"),
47
+ State(VALIDATION_PERIOD_SELECTED_ID, "data"),
48
+ State(VALIDATION_SAVED_ACTIVE_TAB_ID, "data"),
49
+ ],
50
+ prevent_initial_call=True,
51
+ )
52
+ def display_validation_tables(
53
+ load_in_progress,
54
+ active_tab: str,
55
+ team: str,
56
+ declaration_set: int,
57
+ team_selection_date,
58
+ previous_load_in_progress,
59
+ period_date: str,
60
+ previous_active_tab: str,
61
+ ):
62
+ """
63
+ Display active tab contents after a team or an active tab change. Exact action depends on
64
+ the value of the load in progress indicator. If it is equal to the previous value, it means
65
+ this is the start of the update process: progress bar is displayed and a dcc.Interval is
66
+ created to schedule again this callback after incrementing the load in progress indicator.
67
+ This causes the callback to be reentered and this time it triggers the real processing for
68
+ the tab resulting in the final update of the active tab contents. An empty content is
69
+ returned for inactive tabs.
70
+
71
+ :param load_in_progress: load in progress indicator
72
+ :param tab: select tab name
73
+ :param team: selected team
74
+ :param declaration_set: selected declaration set (all, validated or non-validated ones)
75
+ :param team_selection_date: last time the team selection was changed
76
+ :param previous_load_in_progress: previous value of the load_in_progress indicator
77
+ :param period_date: a date that must be inside the declaration period
78
+ :param previous_active_tab: previously active tab
79
+ :return: tab content (empty if the tab is not active)
80
+ """
81
+
82
+ tab_contents = []
83
+
84
+ # Be sure to fill the return values in the same order as Output are declared
85
+ tab_list = [TAB_ID_DECLARATION_STATS, TAB_ID_VALIDATION, TAB_ID_MISSING_AGENTS]
86
+ for tab in tab_list:
87
+ if team and len(team) > 0 and tab == active_tab:
88
+ if load_in_progress > previous_load_in_progress and active_tab == previous_active_tab:
89
+ if active_tab == TAB_ID_DECLARATION_STATS:
90
+ tab_contents.append(
91
+ build_statistics_table(team, team_selection_date, period_date)
92
+ )
93
+ elif active_tab == TAB_ID_VALIDATION:
94
+ tab_contents.append(
95
+ build_validation_table(
96
+ team, team_selection_date, declaration_set, period_date
97
+ )
98
+ )
99
+ elif active_tab == TAB_ID_MISSING_AGENTS:
100
+ tab_contents.append(
101
+ build_missing_agents_table(team, team_selection_date, period_date)
102
+ )
103
+ else:
104
+ tab_contents.append(
105
+ dbc.Alert("Erreur interne: tab non supporté"), color="warning"
106
+ )
107
+ previous_load_in_progress += 1
108
+ else:
109
+ component = html.Div(
110
+ [
111
+ create_progress_bar(team),
112
+ dcc.Interval(
113
+ id=VALIDATION_DISPLAY_INTERVAL_ID,
114
+ n_intervals=0,
115
+ max_intervals=1,
116
+ interval=500,
117
+ ),
118
+ ]
119
+ )
120
+ tab_contents.append(component)
121
+ else:
122
+ tab_contents.append("")
123
+
124
+ tab_contents.extend([previous_load_in_progress, active_tab])
125
+
126
+ return tab_contents
127
+
128
+
129
+ @app.callback(
130
+ Output(VALIDATION_LOAD_INDICATOR_ID, "data"),
131
+ Input(VALIDATION_DISPLAY_INTERVAL_ID, "n_intervals"),
132
+ State(VALIDATION_SAVED_INDICATOR_ID, "data"),
133
+ prevent_initial_call=True,
134
+ )
135
+ def display_validation_tables_trigger(n, previous_load_indicator):
136
+ """
137
+ Increment (change) of the input of display_validation_tables callback to get it fired a
138
+ second time after displaying the progress bar. The output component must be updated each
139
+ time the callback is entered to trigger the execution of the other callback, thus the
140
+ choice of incrementing it at each call.
141
+
142
+ :param n: n_interval property of the dcc.Interval (0 or 1)
143
+ :return: 1 increment to previous value
144
+ """
145
+
146
+ return previous_load_indicator + 1
147
+
148
+
149
+ @app.callback(
150
+ Output({"type": "validation-switch", "id": MATCH}, "value"),
151
+ Input({"type": "validation-switch", "id": MATCH}, "value"),
152
+ State({"type": "validation-agent-id", "id": MATCH}, "data"),
153
+ State(TEAM_SELECTED_VALUE_ID, "data"),
154
+ State(TEAM_SELECTION_DATE_ID, "data"),
155
+ State(VALIDATION_PERIOD_SELECTED_ID, "data"),
156
+ prevent_initial_call=True,
157
+ )
158
+ def validation_button_callback(value, agent_id, team, team_selection_date, period_date: str):
159
+ """
160
+ Function called as a callback for the validation button. It adds a validation entry for
161
+ the selected agent with a timestamp allowing to get the validation history. Doesn't add an
162
+ entry if the validation status is unchanged (should not happen).
163
+
164
+ :param value: a list with of values with last one equals 1 if the switch is on, an empty
165
+ list or a list with 1 value (0) if the switch is off
166
+ :param agent_id: the agent ID of the selected agent
167
+ :param team: selected team
168
+ :param team_selection_date: last time the team selection was changed
169
+ :param period_date: a date that must be inside the declaration period
170
+ :return: None
171
+ """
172
+
173
+ from ositah.utils.hito_db_model import OSITAHValidation
174
+
175
+ db = get_db()
176
+ session = db.session
177
+
178
+ validation_data = get_validation_data(agent_id, period_date, session)
179
+
180
+ # If the validation switch is on, add a new validation entry for the agent (except if there
181
+ # is an existing validated entry but it should not happen) and save the associated project
182
+ # declarations. If the switch is off and a validated entry exists, update the "validated"
183
+ # attribute to false and do not add a new project declarations.
184
+ switch_on = len(value) > 0 and value[len(value) - 1] > 0
185
+ if switch_on:
186
+ if validation_data is None or validation_data.validated != switch_on:
187
+ validation_id = str(uuid4())
188
+ validation_data = OSITAHValidation(
189
+ id=validation_id,
190
+ validated=switch_on,
191
+ timestamp=datetime.now(),
192
+ agent_id=agent_id,
193
+ period_id=get_validation_period_id(period_date),
194
+ )
195
+ try:
196
+ session.add(validation_data)
197
+ # A flush() is required before calling project_declaration_snapshot() else the
198
+ # first insert is lost
199
+ # MJ 2023-07-12: hack to workaround a problem with flush() leading to an undefined
200
+ # foreign key
201
+ # session.flush()
202
+ session.commit()
203
+ project_declaration_snapshot(
204
+ agent_id,
205
+ validation_id,
206
+ team,
207
+ team_selection_date,
208
+ period_date,
209
+ session,
210
+ )
211
+ session.commit()
212
+ except: # noqa: E722
213
+ session.rollback()
214
+ raise
215
+
216
+ elif validation_data.validated:
217
+ validation_data.validated = switch_on
218
+ # Keep track of the original timestamp
219
+ validation_data.initial_timestamp = validation_data.timestamp
220
+ validation_data.timestamp = datetime.now()
221
+ session.commit()
222
+
223
+ return value
224
+
225
+
226
+ @app.callback(
227
+ Output(VALIDATION_DECLARATIONS_SELECTED_ID, "data"),
228
+ Input(VALIDATION_DECLARATIONS_SWITCH_ID, "value"),
229
+ prevent_initial_call=True,
230
+ )
231
+ def select_declarations_set(new_set):
232
+ """
233
+ This callback is used to forward to the validation table callback the selected declarations
234
+ set through a dcc.Store that exists permanently in the page.
235
+
236
+ :param new_set: selected declarations set
237
+ :return: same value
238
+ """
239
+
240
+ return new_set
@@ -1,89 +1,89 @@
1
- """
2
- OSITAH validation sub-application
3
-
4
- This file contains only the layout definitions
5
- """
6
-
7
- from ositah.apps.validation.callbacks import *
8
- from ositah.utils.menus import DATA_SELECTED_SOURCE_ID, TABLE_TYPE_DUMMY_STORE, team_list_dropdown
9
- from ositah.utils.projects import DATA_SOURCE_HITO
10
-
11
-
12
- def validation_submenus():
13
- """
14
- Build the tabs menus of the validation sub-application
15
-
16
- :return: DBC Tabs
17
- """
18
-
19
- return dbc.Tabs(
20
- [
21
- dbc.Tab(
22
- id=TAB_ID_DECLARATION_STATS,
23
- tab_id=TAB_ID_DECLARATION_STATS,
24
- label="Statistiques",
25
- ),
26
- dbc.Tab(
27
- id=TAB_ID_VALIDATION,
28
- tab_id=TAB_ID_VALIDATION,
29
- label="Déclarations Effectuées",
30
- ),
31
- dbc.Tab(
32
- id=TAB_ID_MISSING_AGENTS,
33
- tab_id=TAB_ID_MISSING_AGENTS,
34
- label="Déclarations Manquantes",
35
- ),
36
- ],
37
- id=VALIDATION_TAB_MENU_ID,
38
- )
39
-
40
-
41
- def validation_layout():
42
- """
43
- Build the layout for this application, after reading the data if necessary.
44
-
45
- :return: application layout
46
- """
47
-
48
- from ositah.utils.hito_db_model import (
49
- OSITAHProjectDeclaration,
50
- OSITAHValidation,
51
- OSITAHValidationPeriod,
52
- )
53
-
54
- db = get_db()
55
-
56
- OSITAHValidationPeriod.__table__.create(db.session.bind, checkfirst=True)
57
- OSITAHValidation.__table__.create(db.session.bind, checkfirst=True)
58
- OSITAHProjectDeclaration.__table__.create(db.session.bind, checkfirst=True)
59
-
60
- return html.Div(
61
- [
62
- html.H1("Affichage et validation des déclarations"),
63
- team_list_dropdown(),
64
- dcc.Store(id=DATA_SELECTED_SOURCE_ID, data=DATA_SOURCE_HITO),
65
- html.Div(
66
- validation_submenus(),
67
- id="validation-submenus",
68
- style={"marginTop": "3em"},
69
- ),
70
- dcc.Store(id=VALIDATION_LOAD_INDICATOR_ID, data=0),
71
- dcc.Store(id=VALIDATION_SAVED_INDICATOR_ID, data=0),
72
- dcc.Store(
73
- id=VALIDATION_DECLARATIONS_SELECTED_ID,
74
- data=VALIDATION_DECLARATIONS_SELECT_ALL,
75
- ),
76
- dcc.Store(id=VALIDATION_SAVED_ACTIVE_TAB_ID, data=""),
77
- # The following dcc.Store coupled with tables must be created in the layout for
78
- # the callback to work
79
- dcc.Store(id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_VALIDATION}, data=0),
80
- dcc.Store(
81
- id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_MISSING_AGENTS},
82
- data=0,
83
- ),
84
- dcc.Store(
85
- id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_DECLARATION_STATS},
86
- data=0,
87
- ),
88
- ]
89
- )
1
+ """
2
+ OSITAH validation sub-application
3
+
4
+ This file contains only the layout definitions
5
+ """
6
+
7
+ from ositah.apps.validation.callbacks import *
8
+ from ositah.utils.menus import DATA_SELECTED_SOURCE_ID, TABLE_TYPE_DUMMY_STORE, team_list_dropdown
9
+ from ositah.utils.projects import DATA_SOURCE_HITO
10
+
11
+
12
+ def validation_submenus():
13
+ """
14
+ Build the tabs menus of the validation sub-application
15
+
16
+ :return: DBC Tabs
17
+ """
18
+
19
+ return dbc.Tabs(
20
+ [
21
+ dbc.Tab(
22
+ id=TAB_ID_DECLARATION_STATS,
23
+ tab_id=TAB_ID_DECLARATION_STATS,
24
+ label="Statistiques",
25
+ ),
26
+ dbc.Tab(
27
+ id=TAB_ID_VALIDATION,
28
+ tab_id=TAB_ID_VALIDATION,
29
+ label="Déclarations Effectuées",
30
+ ),
31
+ dbc.Tab(
32
+ id=TAB_ID_MISSING_AGENTS,
33
+ tab_id=TAB_ID_MISSING_AGENTS,
34
+ label="Déclarations Manquantes",
35
+ ),
36
+ ],
37
+ id=VALIDATION_TAB_MENU_ID,
38
+ )
39
+
40
+
41
+ def validation_layout():
42
+ """
43
+ Build the layout for this application, after reading the data if necessary.
44
+
45
+ :return: application layout
46
+ """
47
+
48
+ from ositah.utils.hito_db_model import (
49
+ OSITAHProjectDeclaration,
50
+ OSITAHValidation,
51
+ OSITAHValidationPeriod,
52
+ )
53
+
54
+ db = get_db()
55
+
56
+ OSITAHValidationPeriod.__table__.create(db.session.bind, checkfirst=True)
57
+ OSITAHValidation.__table__.create(db.session.bind, checkfirst=True)
58
+ OSITAHProjectDeclaration.__table__.create(db.session.bind, checkfirst=True)
59
+
60
+ return html.Div(
61
+ [
62
+ html.H1("Affichage et validation des déclarations"),
63
+ team_list_dropdown(),
64
+ dcc.Store(id=DATA_SELECTED_SOURCE_ID, data=DATA_SOURCE_HITO),
65
+ html.Div(
66
+ validation_submenus(),
67
+ id="validation-submenus",
68
+ style={"marginTop": "3em"},
69
+ ),
70
+ dcc.Store(id=VALIDATION_LOAD_INDICATOR_ID, data=0),
71
+ dcc.Store(id=VALIDATION_SAVED_INDICATOR_ID, data=0),
72
+ dcc.Store(
73
+ id=VALIDATION_DECLARATIONS_SELECTED_ID,
74
+ data=VALIDATION_DECLARATIONS_SELECT_ALL,
75
+ ),
76
+ dcc.Store(id=VALIDATION_SAVED_ACTIVE_TAB_ID, data=""),
77
+ # The following dcc.Store coupled with tables must be created in the layout for
78
+ # the callback to work
79
+ dcc.Store(id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_VALIDATION}, data=0),
80
+ dcc.Store(
81
+ id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_MISSING_AGENTS},
82
+ data=0,
83
+ ),
84
+ dcc.Store(
85
+ id={"type": TABLE_TYPE_DUMMY_STORE, "id": TABLE_ID_DECLARATION_STATS},
86
+ data=0,
87
+ ),
88
+ ]
89
+ )