diff --git a/app_new/constants.py b/app_new/constants.py index 39a8770..379ff70 100644 --- a/app_new/constants.py +++ b/app_new/constants.py @@ -116,6 +116,20 @@ WORK_TYPES = { "curative": "Intervention curative", } +WORKFLOW_TYPES = { + "corrective": "Corrective", + "preventive": "Préventive", + "travaux": "Travaux", + "prevention": "Prévention", +} + +WORKFLOW_STATUS_ORDERS = { + "corrective": ["brouillon", "en_attente", "planifiee", "en_cours", "en_attente_pieces", "en_attente_entreprise", "terminee", "cloturee"], + "preventive": ["brouillon", "planifiee", "en_cours", "en_attente_pieces", "en_attente_entreprise", "terminee", "cloturee"], + "travaux": ["brouillon", "attente_chef", "demande_departement", "attente_devis", "devis_a_valider", "devis_accepte", "entreprise_mandatee", "travaux_planifies", "travaux_en_cours", "travaux_termines", "reception", "cloturee"], + "prevention": ["brouillon", "en_attente", "planifiee", "en_cours", "terminee", "cloturee"], +} + # Rôles utilisateurs ROLES = { "admin": "Administrateur", diff --git a/app_new/core/models/maintenance.py b/app_new/core/models/maintenance.py index bef4ed9..82c23c1 100644 --- a/app_new/core/models/maintenance.py +++ b/app_new/core/models/maintenance.py @@ -24,6 +24,7 @@ class Intervention(db.Model): # Statut & Workflow status = db.Column(db.String(30), default="brouillon") + workflow_type = db.Column(db.String(20), nullable=False, default="corrective", index=True) # Responsable actuel (qui doit agir maintenant) assigned_to_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=True) @@ -172,6 +173,11 @@ class Intervention(db.Model): 'travaux_termines': 'success', 'reception': 'success', } return colors.get(self.status, 'secondary') + + @property + def workflow_label(self): + from app_new.constants import WORKFLOW_TYPES + return WORKFLOW_TYPES.get(self.workflow_type, self.workflow_type or 'Corrective') @property def status_label(self): diff --git a/app_new/equipments/scheduled.py b/app_new/equipments/scheduled.py index 4ae0d5e..5bde930 100644 --- a/app_new/equipments/scheduled.py +++ b/app_new/equipments/scheduled.py @@ -139,6 +139,7 @@ def create_intervention_from_task(id, task_id): equipment_id=id, room_id=request.form.get('room_id') or task.room_id, type='preventif', + workflow_type='preventive', status='en_cours', scheduled_date=task.scheduled_date, scheduled_start=request.form.get('scheduled_start') or task.scheduled_start.strftime('%H:%M') if task.scheduled_start else None, diff --git a/app_new/interventions/crud.py b/app_new/interventions/crud.py index bdae491..9543aa3 100644 --- a/app_new/interventions/crud.py +++ b/app_new/interventions/crud.py @@ -22,7 +22,7 @@ from ..core.models.planning import ScheduledTask from ..core.models.equipment import Equipment from ..core.models.college import Room from ..core.models.company import Service, Company -from app_new.constants import INTERVENTION_STATUSES, INTERVENTION_TRANSITIONS, PRIORITIES +from app_new.constants import INTERVENTION_STATUSES, INTERVENTION_TRANSITIONS, PRIORITIES, WORKFLOW_TYPES, WORKFLOW_STATUS_ORDERS interventions_bp = Blueprint('interventions', __name__) @@ -35,6 +35,7 @@ def index(): status = request.args.get('status', '') priority = request.args.get('priority', '') intervention_type = request.args.get('type', '') + workflow_type = request.args.get('workflow_type', '') lot_id = request.args.get('lot', type=int) assigned_to_id = request.args.get('assigned_to_id', type=int) frequency = request.args.get('frequency', '') @@ -57,6 +58,8 @@ def index(): query = query.filter_by(priority=priority) if intervention_type: query = query.filter(Intervention.type == intervention_type) + if workflow_type in WORKFLOW_TYPES: + query = query.filter_by(workflow_type=workflow_type) if lot_id: query = query.filter_by(lot_id=lot_id) if assigned_to_id: @@ -106,6 +109,8 @@ def index(): lots=lots, users=users, statuses=INTERVENTION_STATUSES, + workflow_status_order=WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective']), + workflow_types=WORKFLOW_TYPES, priorities=PRIORITIES, status_counts=status_counts, trashed_count=trashed_count, @@ -132,6 +137,11 @@ def create(): # Si pas de demandeur fourni, utiliser le nom de l'utilisateur connecté requester_name = current_user.username if hasattr(current_user, 'username') else 'Inconnu' + selected_type = request.form.get('intervention_type', 'curatif') + workflow_type = request.form.get('workflow_type') or { + 'preventif': 'preventive', 'amelioratif': 'travaux', + 'prevention': 'prevention', 'administratif': 'prevention', + }.get(selected_type, 'corrective') intervention = Intervention( title=request.form.get('title'), description=request.form.get('description') or '', @@ -142,7 +152,8 @@ def create(): author_id=current_user.id, status=request.form.get('status', 'brouillon'), priority=request.form.get('priority', 'normale'), - type=request.form.get('intervention_type', 'curatif'), + type=selected_type, + workflow_type=workflow_type if workflow_type in WORKFLOW_TYPES else 'corrective', notes=request.form.get('notes') or '', requester_name=requester_name, scheduled_date=datetime.strptime(request.form.get('intervention_date'), '%Y-%m-%d').date() if request.form.get('intervention_date') else None, @@ -211,6 +222,7 @@ def create(): 'assignee': '', 'date': None, 'requester_name': '' + , 'workflow_type': request.args.get('workflow', 'corrective') } interpretation = None @@ -253,6 +265,7 @@ def create(): 'information': 'curatif' } prefilled['type'] = type_map.get(interpretation.analysis_type, 'curatif') + prefilled['workflow_type'] = 'preventive' if interpretation.analysis_type == 'preventive' else prefilled.get('workflow_type', 'corrective') prefilled['equipment'] = interpretation.suggested_equipment or '' else: json_suggestions = { @@ -327,6 +340,7 @@ def create(): users=users, statuses=INTERVENTION_STATUSES, priorities=PRIORITIES, + workflow_types=WORKFLOW_TYPES, prefilled=prefilled, equipment_id=equipment_id, equipment_match=equipment_match, @@ -453,6 +467,9 @@ def edit(id): intervention.status = new_status intervention.priority = request.form.get('priority') intervention.type = request.form.get('intervention_type', intervention.type) + workflow_type = request.form.get('workflow_type') + if workflow_type in WORKFLOW_TYPES: + intervention.workflow_type = workflow_type intervention.scheduled_date = request.form.get('scheduled_date') or None intervention.notes = request.form.get('notes') intervention.requester_name = request.form.get('requester_name') or None @@ -487,6 +504,7 @@ def edit(id): 'assignee': intervention.assigned_to.username if intervention.assigned_to else '', 'date': intervention.scheduled_date, 'requester_name': intervention.requester_name or '' + , 'workflow_type': intervention.workflow_type } return render_template('interventions/new.html', @@ -497,6 +515,7 @@ def edit(id): users=users, statuses=INTERVENTION_STATUSES, priorities=PRIORITIES, + workflow_types=WORKFLOW_TYPES, prefilled=prefilled, title="Modifier l'intervention") diff --git a/app_new/interventions/templates/detail.html b/app_new/interventions/templates/detail.html index ba48fb1..494e1f2 100644 --- a/app_new/interventions/templates/detail.html +++ b/app_new/interventions/templates/detail.html @@ -61,7 +61,8 @@
- {% set workflow_order = ['brouillon', 'attente_chef', 'demande_departement', 'attente_devis', 'devis_a_valider', 'devis_accepte', 'entreprise_mandatee', 'travaux_planifies', 'travaux_en_cours', 'travaux_termines', 'reception', 'cloturee'] if intervention.execution_mode != 'interne' else ['brouillon', 'attente_chef', 'en_cours', 'en_attente_pieces', 'en_attente_entreprise', 'terminee', 'cloturee'] %} + {% set workflow_order = workflow_status_order %} +
Workflow {{ intervention.workflow_label }}
{% for step in workflow_order %} {% if step in statuses %} {% set is_current = (step == intervention.status) %} diff --git a/app_new/interventions/templates/index.html b/app_new/interventions/templates/index.html index f2e075a..f9b0bc6 100644 --- a/app_new/interventions/templates/index.html +++ b/app_new/interventions/templates/index.html @@ -55,6 +55,12 @@
+
+ +
+ {% for key, label in workflow_types.items() %} + + {% endfor %} + + Le parcours détermine les étapes affichées dans la fiche. +
{% for x in logs %}{% endfor %}
{{ x.work_date|date_fmt }}{{ x.activity }}{{ x.duration_minutes }} min
Agents et habilitations ({{ staff|length }})
DUERP — risques
{% for x in risks %}{% endfor %}
{{ x.work_unit }}{{ x.hazard }}{{ x.score }}
-
Plan d’actions
{% for x in actions %}{% endfor %}
{{ x.title }}{{ x.owner or '—' }}{{ x.due_date|date_fmt }}{{ x.status }}
+
Plan d’actions
{% for x in actions %}{% endfor %}
{{ x.title }}{{ x.owner or '—' }}{{ x.due_date|date_fmt }}
Registre sécurité / incidents / exercices
{% for x in entries %}{% endfor %}
{{ x.entry_date|date_fmt }}{{ x.entry_type }}{{ x.title }}{{ x.location }}
{% endblock %} diff --git a/migrations/versions/ff6a7b8c9d0e_add_intervention_workflow_type.py b/migrations/versions/ff6a7b8c9d0e_add_intervention_workflow_type.py new file mode 100644 index 0000000..0bb67bc --- /dev/null +++ b/migrations/versions/ff6a7b8c9d0e_add_intervention_workflow_type.py @@ -0,0 +1,16 @@ +"""Ajoute l'origine fonctionnelle des interventions.""" +from alembic import op +import sqlalchemy as sa + +revision = "ff6a7b8c9d0e" +down_revision = "fe5f6a7b8c9d" +branch_labels = None +depends_on = None + +def upgrade(): + op.add_column("interventions", sa.Column("workflow_type", sa.String(20), nullable=False, server_default="corrective")) + op.create_index("ix_interventions_workflow_type", "interventions", ["workflow_type"]) + +def downgrade(): + op.drop_index("ix_interventions_workflow_type", table_name="interventions") + op.drop_column("interventions", "workflow_type")